WordPress中的每个更新均由该wp_update_post
功能处理。
该函数有一些默认值,post_content_filtered
默认值为''(空字符串)。
一旦将默认值与通过wp_parse_args
它传递给函数的args合并,则意味着每次更新帖子post_content_filtered
且未显式传递它时,它将被设置为空字符串。
现在我们可以问:何时post_content_filtered
显式传递给wp_update_post
?答案是:决不靠WordPress。
因此,对于第一个问题:
在其他什么情况下,会清除post_content_filtered列中的数据?
简短的答案是:每次更新帖子,无论出于何种原因。
请注意,仅更改一个字段就是更新,尤其是,每个状态更改都是一个更新,例如,要发布的草稿,待发布的待办事项,将来要发布的内容,发布到回收站(删除后的内容),等等...
如果帖子中发生了某些更改,则将post_content_filtered
其清除;唯一的例外是when post_content_filtered
被显式传递给wp_update_post
,并且正如已经说过的那样,WordPress从未做到这一点。
有没有办法完全防止这种情况发生?(我的意思是,有没有办法确保数据被永久存储?
如果您使用代码创建该字段,并且想要保留它,则必须查看WordPress执行的每个更新,并阻止更改。
这听起来像是艰苦的工作,但是如果您阅读此答案的第一句话“ WordPress中的每个帖子更新均由该wp_update_post
函数处理 ”,您将了解,唯一需要的是查看该函数,幸运的是,它具有不同的钩子。
我建议使用的钩子有wp_insert_post_data
两个原因:
- 它在更新之前运行,因此您不必恢复但可以防止
- 它传递2个参数:函数将要更新的数据,以及(在更新的情况下)包含帖子ID的传递参数的数组
因此,get_post
您可以使用简单的方法来比较帖子的当前状态以及帖子的状态:如果您不喜欢某些内容,则可以对其进行更改。
让我们编写代码:
add_filter( 'wp_insert_post_data', 'preserve_content_filtered', 999, 2 );
function preserve_content_filtered ( $data, $postarr ) {
/* If this is not an update, we have nothing to do */
if ( ! isset($postarr['ID']) || ! $postarr['ID'] ) return $data;
/*
* Do you want you filter per post_type?
* You should, to prevent issues on post type like menu items.
*/
if ( ! in_array( $data['post_type'], array( 'post', 'page' ) ) ) return $data;
/* How post is now, before the update */
$before = get_post( $postarr['ID'] );
/* If content_filtered is already empty we have nothing to preserve */
if ( empty( $before->post_content_filtered ) ) return $data;
if ( empty( $data['post_content_filtered'] ) ) {
/*
* Hey! WordPress wants to clear our valuable post_content_filtered...
* Let's prevent it!
*/
$data['post_content_filtered'] = $before->post_content_filtered;
}
return $data;
}
可能存在问题,以前的功能无法进行每次 post_content_filtered
清洁。如果您出于任何原因想要清除它?
我已经说过,每个WP帖子的更改都由处理wp_update_post
,但是您不是WordPress。
您可以编写如下函数:
function reset_post_content_filtered( $postid ) {
global $wpdb;
$wpdb->query( $wpdb->prepare(
"UPDATE $wpdb->posts SET `post_content_filtered` = '' WHERE `ID` = %d", $postid
) );
}
作为$wpdb
查询,它不会触发我们的过滤器,因此重设没有问题,并且在您需要重设的代码中的任何地方post_content_filtered
,都可以调用此函数。
您还可以创建一个带有“清除内容过滤”按钮的metabox,单击此按钮后,只需调用您的reset_post_content_filtered
函数即可,例如通过Ajax。