WordPressプラグインの中には(ごくわずかですが)データベース内のpost_content_filtered
列を使用して投稿に関するデータを保存するものがあります。
たとえば、 Markdown on Save はpost_content_formatted
列に投稿のマークダウンバージョンとpost_content
列に解析済みHTMLを別々に保存するので、プラグインが無効になったときに投稿がMarkdownと表示されないようになります。 post_content
)に格納されています。
さて、私はpost_content_filtered
が一時的な記憶のためにほとんど使われていることに気づきました、すなわち、以下の場合、列の内容は失われます(またはクリアされます)。
[クイック編集]オプションを使用して投稿(タイトル、タグ、カテゴリなど)に変更を加えます。
予定投稿が(自動的に)公開されます
投稿を一括編集します
投稿のリビジョンを切り替える
投稿が外部エディタ(WordPress投稿エディタではない)から保存されている
質問:
post_content_filtered
列のデータは他にどのような状況でクリアされますか?
これがまったく起こらないようにする方法はありますか? (つまり、データが永続的に格納されるようにする方法、post_content
列の処理方法はありますか?)
WordPressのすべての投稿更新はwp_update_post
関数によって処理されます。
この関数にはいくつかのデフォルトがあり、post_content_filtered
のデフォルト値は ''(空の文字列)です。
デフォルトがwp_parse_args
を介してfunctionに渡される引数とマージされると、投稿が更新され、post_content_filtered
が明示的に渡されないたびに、空の文字列に設定されます。
post_content_filtered
が明示的にwp_update_post
に渡されるのはいつか?答えは:決してWordPressによる)。
それであなたの最初の質問のために:
Post_content_filtered列のデータは他にどのような状況でクリアされますか?
簡単な答えは:何らかの理由で投稿が更新されるたびに{_。
1つのフィールドのみを変更するis更新、特にすべてのステータスの変更は更新です。たとえば、公開するドラフト、公開する予定、公開する予定、ゴミ箱に公開する(削除後など)などです。 ..
投稿に何か変更があった場合、post_content_filtered
はクリアされます。唯一の例外は、post_content_filtered
が明示的にwp_update_post
に渡される場合です。すでに述べたように、これはWordPressによって行われることはありません。
これがまったく起こらないようにする方法はありますか? (つまり、データが永続的に保存されていることを確認する方法はありますか。
あなたがあなたのコードでそのフィールドを作成し、そしてあなたがそれを保存したいのなら、あなたはWordPressによって実行されたevery updateを見て、そしてその変更を防ぐ必要があります。
これは大変な作業のように思えるかもしれませんが、この答えの最初の文「WordPressのすべての投稿更新はwp_update_post
functionによって処理される」を読むと、必要なことはその関数を見ることだけです幸いなことに、さまざまなフックがあります。
私が提案するフックは、2つの理由からwp_insert_post_data
です。
ですから、単純な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;
}
前の関数がeverypost_content_filtered
のクリーニングを妨げる可能性のある問題があります。そして、なんらかの理由でyouをクリアしたい場合は、
すべての[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
をリセットする必要がある場合は、この関数を呼び出すことができます。
また、 'Clear content filtered'ボタンを使ってメタボックスを作成することもできます。このボタンがクリックされたときにはreset_post_content_filtered
関数を呼び出すだけです。 Ajaxを介して。