Kapan kolom 'post_content_filtered' dalam database dihapus oleh WordPress?

29

Beberapa plugin WordPress (walaupun sangat sedikit) menggunakan post_content_filteredkolom dalam basis data untuk menyimpan beberapa data yang terkait dengan sebuah posting.

Misalnya, Penurunan Harga pada Simpan menyimpan versi penurunan harga dari sebuah posting secara terpisah di post_content_formattedkolom dan HTML yang diuraikan dalam post_contentkolom, sehingga ketika plugin dinonaktifkan, tulisan tidak akan memuntahkan Markdown (karena HTML disimpan di post_content).

Sekarang, saya menyadari bahwa post_content_filteredcukup banyak digunakan untuk penyimpanan sementara yaitu konten di kolom hilang (atau dihapus) ketika:

  • Anda membuat perubahan pada sebuah posting (judul, tag, kategori, dll.) menggunakan opsi 'Edit Cepat'

  • posting terjadwal (otomatis) diterbitkan

  • Anda mengedit secara massal posting

  • Anda beralih di antara revisi pos

  • sebuah posting disimpan dari editor eksternal (mis. bukan editor posting WordPress)

Pertanyaan:

  1. Dalam situasi lain apa data dalam post_content_filteredkolom dihapus?

  2. Apakah ada cara untuk mencegah hal ini terjadi sama sekali? (Maksud saya, apakah ada cara untuk memastikan bahwa data disimpan secara permanen, cara post_contentkolom diperlakukan?)

ini aku
sumber

Jawaban:

29

Setiap pembaruan posting di WordPress ditangani oleh wp_update_postfungsinya.

Fungsi ini memiliki beberapa default, dan untuk post_content_filterednilai default adalah '' (string kosong).

Setelah default digabungkan dengan args yang diteruskan untuk berfungsi melalui wp_parse_argsitu berarti bahwa setiap kali posting diperbarui dan post_content_filteredtidak secara eksplisit diteruskan, itu diatur ke string kosong.

Sekarang kita dapat bertanya: kapan post_content_filteredsecara eksplisit diteruskan wp_update_post? Jawabannya adalah: tidak pernah oleh WordPress.

Jadi untuk pertanyaan pertama Anda:

Dalam situasi apa lagi data dalam kolom post_content_filtered dihapus?

Jawaban singkatnya adalah: setiap kali posting diperbarui, untuk alasan apa pun .

Perhatikan bahwa mengubah hanya satu bidang adalah pembaruan, khususnya, setiap perubahan status adalah pembaruan, misalnya konsep untuk menerbitkan, menunggu untuk mempublikasikan, masa depan untuk menerbitkan, mempublikasikan ke sampah (penghapusan tulisan), dan seterusnya ...

Jika ada sesuatu yang berubah dalam sebuah pos, maka post_content_filtereddihapus; Satu-satunya pengecualian adalah ketika post_content_filteredsecara eksplisit diteruskan ke wp_update_post, dan seperti yang sudah dikatakan, ini tidak pernah dilakukan oleh WordPress.

Apakah ada cara untuk mencegah hal ini terjadi sama sekali? (Maksud saya, apakah ada cara untuk memastikan bahwa data disimpan secara permanen?

Jika Anda membuat bidang itu dengan kode Anda, dan Anda ingin melestarikannya, Anda harus melihat setiap pembaruan yang dilakukan oleh WordPress, dan mencegah perubahan.

Ini bisa terdengar seperti kerja keras, tetapi jika Anda membaca kalimat pertama dalam jawaban ini, " Setiap pembaruan posting di WordPress ditangani oleh wp_update_postfungsi ", Anda mengerti bahwa satu-satunya hal yang diperlukan adalah melihat fungsi itu, yang untungnya memiliki kait berbeda .

Pengait yang saya sarankan adalah wp_insert_post_datauntuk 2 alasan:

  • Ini berjalan sebelum pembaruan, jadi Anda tidak perlu memulihkan tetapi Anda bisa mencegahnya
  • Melewati 2 parameter: data yang fungsinya akan diperbarui, dan larik parameter yang dilewati, yang (jika terjadi pembaruan) berisi ID pos

Jadi, dengan menggunakan sederhana get_postAnda dapat membandingkan bagaimana posting sekarang, dan bagaimana posting akan: jika Anda tidak menyukai sesuatu, Anda dapat mengubahnya.

Mari kode:

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;

}

Ada masalah yang mungkin terjadi, di mana fungsi sebelumnya mencegah setiap post_content_filtered pembersihan. Dan jika Anda , karena alasan apa pun, ingin menghapusnya?

Saya telah mengatakan bahwa setiap perubahan posting WP ditangani oleh wp_update_post, tetapi Anda bukan WordPress.

Anda dapat menulis fungsi seperti:

function reset_post_content_filtered( $postid ) {
    global $wpdb;
    $wpdb->query( $wpdb->prepare(
        "UPDATE $wpdb->posts SET `post_content_filtered` = '' WHERE `ID` = %d", $postid
    ) );
}

Menjadi $wpdbkueri, itu tidak memicu filter kami, jadi pengaturan ulang dilakukan tanpa masalah, dan di mana pun dalam kode Anda yang perlu Anda atur ulang post_content_filtered, Anda dapat memanggil fungsi ini.

Anda juga dapat membuat metabox dengan tombol 'Bersihkan konten yang difilter' dan ketika tombol ini diklik, panggil saja reset_post_content_filteredfungsi Anda , mis. Via Ajax.

gmazzap
sumber