Каждое обновление в 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.