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_data
2つの理由によるものです。
- 更新の前に実行されるため、回復する必要はありませんが、防ぐことができます
- 関数が更新するデータと、(更新の場合)投稿の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_filtered
Ajaxなどを介して関数を呼び出すだけです。