WordPressでデータベースの「post_content_filtered」列がクリアされるのはいつですか?


29

一部のWordPressプラグイン(ごく少数ですが)は、post_content_filteredデータベースの列を使用して、投稿に関連するデータを保存します。

たとえば、保存時のマークダウンでは、投稿のマークダウンバージョンがpost_content_formatted列に個別に保存され、解析されたHTMLがpost_content列に保存されるため、プラグインが非アクティブ化されたときに投稿がMarkdownを吐き出すことはありません(HTMLはに保存されるためpost_content)。

今、私はそれpost_content_filteredが一時的なストレージにほとんど使用されていることに気付きました。

  • 「クイック編集」オプションを使用して、投稿(タイトル、タグ、カテゴリなど)を変更します。

  • スケジュールされた投稿が(自動的に)公開されます

  • 投稿を一括編集します

  • 投稿のリビジョンを切り替える

  • 投稿は外部エディターから保存されます(つまり、WordPress投稿エディターではありません)

質問:

  1. 他のどのような状況でpost_content_filtered列のデータがクリアされますか?

  2. これがまったく起こらないようにする方法はありますか?(つまり、データが永続的に保存されていること、post_content列が処理されていることを確認する方法はありますか?)

回答:


29

WordPressのすべての投稿の更新は、wp_update_post関数によって処理されます。

この関数にはいくつかのデフォルトがありpost_content_filtered、デフォルト値は ''(空の文字列)です。

デフォルトが、wp_parse_argsそれを介して関数に渡される引数とマージされると、投稿が更新され、post_content_filtered明示的に渡されるたびに空の文字列に設定されることを意味します。

今、私たちは尋ねることができます:にpost_content_filtered明示的に渡されるのはwp_update_postいつですか?答えは、WordPressによるものではありません

最初の質問:

他のどのような状況でpost_content_filtered列のデータがクリアされますか?

簡単な答えは:何らかの理由で投稿が更新されるたびです。

1つのフィールドのみを変更すること更新であり、特に、すべてのステータスの変更は更新であることに注意してください。

投稿で何かが変更された場合、post_content_filteredクリアされます。唯一の例外は、post_content_filtered明示的にに渡されるwp_update_post場合であり、既に述べたように、これはWordPressによって実行されることはありません。

これがまったく起こらないようにする方法はありますか?(つまり、データが永続的に保存されるようにする方法はありますか?

コードでそのフィールドを作成し、それを保持する場合は、WordPressによって実行されるすべての更新を確認し、変更を防止する必要があります。

これは大変な作業のように聞こえますが、この回答の最初の文「WordPressのすべての投稿の更新はwp_update_post関数によって処理されます」を読むと、必要なことはその関数を見るだけであることがわかります。 。

私が提案するフックは、wp_insert_post_data2つの理由によるものです。

  • 更新のに実行されるため、回復する必要はありませんが、防ぐことができます
  • 関数が更新するデータと、(更新の場合)投稿のIDを含む渡されたパラメーターの配列の2つのパラメーターを渡します。

シンプル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、あなたは、この関数を呼び出すことができます。

また、「フィルターされたコンテンツをクリア」ボタンを使用してメタボックスを作成し、このボタンをクリックすると、reset_post_content_filteredAjaxなどを介して関数を呼び出すだけです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.