WordPress何时清除数据库中的“ post_content_filtered”列?


29

一些WordPress插件(尽管很少)使用post_content_filtered数据库中的列来保存与帖子相关的一些数据。

例如,保存时的Markdown在post_content_formatted列中分别存储帖子的Markdown版本,在列中存储已解析的HTML post_content,因此,在停用插件时,帖子不会喷出Markdown(因为HTML存储在中post_content)。

现在,我开始意识到这post_content_filtered几乎是用于临时存储的,即在以下情况下,列中的内容会丢失(或清除):

  • 您可以使用“快速编辑”选项对帖子(标题,标签,类别等)进行更改

  • 预定的帖子(自动)发布

  • 您对帖子进行批量编辑

  • 您可以在帖子的修订之间切换

  • 从外部编辑器(即不是WordPress帖子编辑器)保存帖子

问题:

  1. 在其他情况下,该post_content_filtered列中的数据是否被清除?

  2. 有没有办法完全防止这种情况发生?(我的意思是,有没有办法确保数据被永久存储,即post_content列的处理方式?)

Answers:


29

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。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.