Когда WordPress очищает столбец "отфильтрованный контент" в базе данных?
Некоторые плагины WordPress (хотя их очень мало) используют столбец post_content_filtered
в базе данных для сохранения некоторых данных, связанных с публикацией.
Например, Уценка при сохранении сохраняет уцененную версию записи отдельно в столбце post_content_formatted
и проанализированный HTML в столбце post_content
, чтобы при отключении плагина записи не выдавали уценку (потому что HTML хранится в post_content
).
Теперь я понял, что post_content_filtered
в значительной степени используется для временного хранение, т.е. содержимое столбца теряется (или очищается), когда:
Вы вносите изменения в публикацию (заголовок, теги, категории и т.д.), Используя опцию "Быстрое редактирование".
Запланированная публикация (автоматически) публикуется
Вы делаете массовые правки в сообщениях
Вы переключаетесь между редакциями публикации
Сообщение сохраняется из внешнего редактора (т. е. не из сообщения WordPress редактор)
Вопросы:
В каких других ситуациях данные в столбце
post_content_filtered
очищаются?Есть ли способ предотвратить это вообще? (Я имею в виду, есть ли способ убедиться, что данные хранятся постоянно, как обрабатывается столбец
post_content
?)
1 answers
Каждое обновление публикации в 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 причинам:
- Он запускается до обновления, поэтому вам не нужно восстанавливать , но вы можете предотвратить
- Он передает 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.