Кожне оновлення повідомлення в WordPress обробляється wp_update_post
функцією.
Ця функція має деякі значення за замовчуванням, а для post_content_filtered
типового значення - '' (порожній рядок).
Після об'єднання за замовчуванням аргументів, переданих для його функціонування, wp_parse_args
це означає, що кожен раз, коли повідомлення оновлюється і post_content_filtered
явно не передається, він встановлюється в порожній рядок.
Тепер ми можемо запитати: коли це post_content_filtered
явно передається wp_update_post
? Відповідь: ніколи WordPress.
Тож для вашого першого питання:
У яких інших ситуаціях очищаються дані у стовпчику post_content_filtered?
Коротка відповідь: щоразу, коли повідомлення оновлюється, з будь-якої причини .
Зауважте, що зміна лише одного поля є оновленням, зокрема, кожна зміна статусу - це оновлення, наприклад, проект для публікації, очікування до публікації, публікація в майбутньому, публікація в кошику (публікація видалення) тощо.
Якщо щось змінюється в дописі, post_content_filtered
воно видаляється; Єдиний виняток - це, коли post_content_filtered
це явно передається wp_update_post
, і як вже було сказано, WordPress цього ніколи не робить.
Чи є спосіб взагалі не допустити цього? (Я маю на увазі, чи є спосіб переконатися, що дані зберігаються постійно?
Якщо ви створюєте це поле зі своїм кодом, і хочете його зберегти, вам слід переглянути кожне оновлення, яке виконує WordPress, і запобігти їх змінам.
Це може здатися важкою працею, але якщо ви прочитаєте перше речення в цій відповіді, " Кожне оновлення повідомлення в WordPress обробляється wp_update_post
функцією ", ви розумієте, що єдине, що потрібно - це подивитися на цю функцію, на щастя якої є різні гачки. .
Гак, який я пропоную, є з wp_insert_post_data
двох причин:
- Він працює до оновлення, тому вам не доведеться відновитись, але ви можете запобігти
- Він передає 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.