Коли стовпчик "post_content_filtered" у базі даних очищається WordPress?


29

Деякі плагіни WordPress (хоча дуже мало) використовують post_content_filteredстовпчик у базі даних, щоб зберегти деякі дані, пов’язані з публікацією.

Наприклад, Markdown on Save зберігає версію post_content_formattedрозмітки публікації окремо у стовпці та проаналізований HTML у post_contentстовпці, так що при відключенні плагіну публікації не розкриватимуть Markdown (оскільки HTML зберігається у post_content).

Тепер я зрозумів, що post_content_filteredв основному використовується для тимчасового зберігання, тобто вміст у стовпці втрачається (або очищається), коли:

  • ви вносите зміни до публікації (заголовка, тегів, категорій тощо), використовуючи опцію "Швидке редагування"

  • запланована публікація (автоматично) публікується

  • ви робите масові зміни до публікацій

  • ви переходите між редакціями публікації

  • публікація зберігається із зовнішнього редактора (тобто не редактора повідомлень WordPress)

Запитання:

  1. У яких інших ситуаціях post_content_filteredочищаються дані у стовпці?

  2. Чи є спосіб взагалі не допустити цього? (Я маю на увазі, чи є спосіб переконатися, що дані зберігаються постійно, як post_contentобробляється стовпець?)

Відповіді:


29

Кожне оновлення повідомлення в 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.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.