Quando viene cancellata la colonna "post_content_filtered" nel database da WordPress?


29

Alcuni plugin di WordPress (anche se molto pochi) usano la post_content_filteredcolonna nel database per salvare alcuni dati relativi a un post.

Ad esempio, Markdown on Save memorizza la versione markdown di un post separatamente nella post_content_formattedcolonna e il codice HTML analizzato nella post_contentcolonna, in modo che quando il plug-in è disattivato i post non emettano Markdown (perché l'HTML è archiviato post_content).

Ora, mi sono reso conto che post_content_filteredè praticamente usato per l'archiviazione temporanea, cioè il contenuto nella colonna viene perso (o cancellato) quando:

  • apporti modifiche a un post (titolo, tag, categorie, ecc.) usando l'opzione "Modifica rapida"

  • un post programmato viene (automaticamente) pubblicato

  • fai modifiche collettive ai post

  • si passa tra le revisioni di un post

  • un post viene salvato da un editor esterno (ovvero non l'editor di post di WordPress)

Domande:

  1. In quali altre situazioni vengono post_content_filteredcancellati i dati nella colonna?

  2. C'è un modo per impedire che ciò accada affatto? (Voglio dire, c'è un modo per assicurarsi che i dati siano archiviati in modo permanente, nel modo in cui post_contentviene trattata la colonna?)

Risposte:


29

Ogni aggiornamento post in WordPress è gestito dalla wp_update_postfunzione.

Questa funzione ha alcune impostazioni predefinite e per post_content_filteredil valore predefinito è '' (stringa vuota).

Una volta che i valori predefiniti vengono uniti a args passati alla funzione tramite, wp_parse_argsciò significa che ogni volta che un post viene aggiornato e post_content_filterednon viene passato esplicitamente, viene impostato su una stringa vuota.

Ora possiamo chiederci: quando viene post_content_filteredpassato esplicitamente wp_update_post? La risposta è: mai da WordPress.

Quindi per la tua prima domanda:

In quali altre situazioni vengono cancellati i dati nella colonna post_content_filtered?

La risposta breve è: ogni volta che un post viene aggiornato, per qualsiasi motivo .

Si noti che la modifica di un solo campo è un aggiornamento, in particolare ogni modifica dello stato è un aggiornamento, ad esempio bozza da pubblicare, in attesa di pubblicazione, pubblicazione futura, pubblicazione nel cestino (eliminazione post) e così via ...

Se qualcosa cambia in un post, post_content_filteredviene cancellato; l'unica eccezione è quando post_content_filteredviene esplicitamente passato a wp_update_post, e come già detto, questo non viene mai fatto da WordPress.

C'è un modo per impedire che ciò accada affatto? (Voglio dire, c'è un modo per assicurarsi che i dati siano archiviati in modo permanente?

Se crei quel campo con il tuo codice e vuoi preservarlo, devi guardare ogni aggiornamento eseguito da WordPress e impedire la modifica.

Questo può sembrare un duro lavoro, ma se leggi la prima frase in questa risposta, " Ogni aggiornamento dei post in WordPress è gestito dalla wp_update_postfunzione ", capisci che l'unica cosa necessaria è guardare quella funzione, che fortunatamente ha diversi hook .

Il gancio che suggerisco è il wp_insert_post_dataper 2 motivi:

  • Viene eseguito prima dell'aggiornamento, quindi non è necessario ripristinarlo ma è possibile prevenirlo
  • Passa 2 parametri: i dati che la funzione sta per aggiornare e una matrice dei parametri passati, che (in caso di aggiornamento) contengono l'ID del post

Quindi usando un semplice get_postsei in grado di confrontare come è il post ora e come sarà il post: se non ti piace qualcosa, puoi cambiarlo.

Codifichiamo:

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;

}

C'è un possibile problema, in cui la funzione precedente impedisce ogni post_content_filtered pulizia. E se tu , per qualsiasi motivo, vuoi cancellarlo?

Ho detto che ogni modifica al post WP è gestita da wp_update_post, ma tu non sei WordPress.

Puoi scrivere una funzione come:

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

Essendo una $wpdbquery, non attiva il nostro filtro, quindi il ripristino viene eseguito senza problemi e ovunque nel codice è necessario ripristinare post_content_filtered, è possibile chiamare questa funzione.

Puoi anche creare un metabox con un pulsante "Elimina contenuto filtrato" e quando si fa clic su questo pulsante è sufficiente chiamare la reset_post_content_filteredfunzione, ad esempio tramite Ajax.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.