數據庫中的’post_content_filtered’ 列何時被 WordPress 清除?
問題描述
一些 WordPress 插件 (儘管很少) 使用數據庫中的 post_content_filtered 列來保存一些與文章相關的數據。
例如,Markdown on Save 分別將 post_content_formatted 列中的解析後的 HTML 和 post_content 列中的 HTML 分開存儲在一起,這樣當插件被禁用時,這些帖子不會顯示出 Markdown(因為 HTML 存儲在 post_content 中) 。
現在,我意識到 post_content_filtered 幾乎用於臨時存儲,即:列中的內容丟失 (或清除):
-
您使用’Quick Edit’ 選項更改帖子 (標題,標籤,類別等)
-
(自動) 發佈預定的帖子
-
您可以批量修改帖子
-
你在一個帖子的修訂之間切換
-
一個帖子從外部編輯器 (即不是 WordPress 的帖子編輯器) 保存起來
問題:
-
在其他情況下,
post_content_filtered列中的數據是否已清除? -
有辦法防止這種情況發生嗎? (我的意思是,有沒有辦法確保數據被永久存儲,
post_content列的處理方式?)
最佳解決方案
WordPress 中的每個帖子更新都由 wp_update_post 函數處理。
此功能有一些默認值,而對於 post_content_filtered,默認值為”(空字符串) 。
一旦默認值與通過 wp_parse_args 傳遞給函數的 args 合併,這意味着每次更新一個帖子並且沒有明確傳遞 post_content_filtered 時,它被設置為一個空字符串。
現在我們可以問:post_content_filtered 是什麼時候顯式傳遞給 wp_update_post?答案是:永遠不要用 WordPress 。
所以對於你的第一個問題:
In what other situations is the data in the post_content_filtered column cleared?
簡短的回答是:每次更新一個帖子,都是因為任何原因。
請注意,僅更改一個字段是更新,特別是每個狀態更改都是更新。草稿發佈,等待發布,未來發布,發佈到垃圾 (一個帖子刪除) 等等…
如果帖子發生變化,則 post_content_filtered 被清除; 只有當 post_content_filtered 被明確傳遞給 wp_update_post 時才是異常,而且如上所述,這是從來沒有由 WordPress 完成的。
Is there a way to prevent this from happening at all? (I mean, is there a way to make sure that the data is stored permanently?
如果您使用代碼創建該字段,並且要保留它,則必須查看 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 。
參考文獻
注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。