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

8 set 2013, 13:08:28
Visualizzazioni: 13.9K
Voti: 34

Alcuni plugin WordPress (anche se pochi) utilizzano la colonna post_content_filtered nel database per salvare alcuni dati relativi a un articolo.

Ad esempio, Markdown on Save memorizza la versione markdown di un articolo separatamente nella colonna post_content_formatted e l'HTML parsato nella colonna post_content, in modo che quando il plugin viene disattivato gli articoli non visualizzino il markdown (perché l'HTML è memorizzato in post_content).

Ora, ho capito che post_content_filtered viene utilizzata praticamente per lo storage temporaneo, cioè il contenuto nella colonna viene perso (o cancellato) quando:

  • apporti modifiche a un articolo (titolo, tag, categorie, ecc.) utilizzando l'opzione 'Modifica rapida'

  • un articolo programmato viene (automaticamente) pubblicato

  • effettui modifiche in blocco agli articoli

  • passi da una revisione all'altra di un articolo

  • un articolo viene salvato da un editor esterno (cioè non dall'editor di articoli di WordPress)

Domande:

  1. In quali altre situazioni vengono cancellati i dati dalla colonna post_content_filtered?

  2. Esiste un modo per evitare che questo accada del tutto? (Voglio dire, c'è un modo per assicurarsi che i dati vengano memorizzati in modo permanente, come viene trattata la colonna post_content?)

0
Tutte le risposte alla domanda 1
0
37

Ogni aggiornamento di un post in WordPress viene gestito dalla funzione wp_update_post.

Questa funzione ha alcuni valori predefiniti, e per post_content_filtered il valore predefinito è '' (stringa vuota).

Una volta che i valori predefiniti vengono uniti agli argomenti passati alla funzione tramite wp_parse_args, significa che ogni volta che un post viene aggiornato e post_content_filtered non viene passato esplicitamente, viene impostato su una stringa vuota.

Ora possiamo chiederci: quando viene passato esplicitamente post_content_filtered a wp_update_post? La risposta è: mai da parte di WordPress.

Quindi per la tua prima domanda:

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

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

Nota che modificare solo un campo è un aggiornamento, in particolare, ogni cambio di stato è un aggiornamento, ad esempio da bozza a pubblicato, da in attesa a pubblicato, da programmato a pubblicato, da pubblicato a cestino (un'eliminazione del post), e così via...

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

C'è un modo per evitare che questo accada del tutto? (Voglio dire, c'è un modo per assicurarsi che i dati vengano memorizzati permanentemente?)

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

Questo potrebbe sembrare un lavoro difficile, ma se leggi la prima frase di questa risposta, "Ogni aggiornamento di un post in WordPress viene gestito dalla funzione wp_update_post", capisci che l'unica cosa necessaria è controllare quella funzione, che fortunatamente ha diversi hook.

L'hook che suggerisco è wp_insert_post_data per 2 motivi:

  • Viene eseguito prima dell'aggiornamento, quindi non devi recuperare ma puoi prevenire
  • Passa 2 parametri: i dati che la funzione sta per aggiornare e un array dei parametri passati, che (in caso di aggiornamento) contengono l'ID del post

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

Vediamo il codice:

add_filter( 'wp_insert_post_data', 'preserve_content_filtered', 999, 2 );

function preserve_content_filtered ( $data, $postarr ) {

    /* Se non è un aggiornamento, non abbiamo nulla da fare */
    if ( ! isset($postarr['ID']) || ! $postarr['ID'] ) return $data;

    /*
     * Vuoi filtrare per post_type?
     * Dovresti, per evitare problemi su tipi di post come le voci di menu.
     */
    if ( ! in_array( $data['post_type'], array( 'post', 'page' ) ) ) return $data;

    /* Come è il post ora, prima dell'aggiornamento */
    $before = get_post( $postarr['ID'] ); 

    /* Se content_filtered è già vuoto, non abbiamo nulla da preservare */
    if ( empty( $before->post_content_filtered ) ) return $data;

    if ( empty( $data['post_content_filtered'] ) ) {
        /*
         * Ehi! WordPress vuole cancellare il nostro prezioso post_content_filtered...
         * Preveniamolo!
         */
        $data['post_content_filtered'] = $before->post_content_filtered;
    }

    return $data;

}

C'è un possibile problema, dove la funzione precedente previene ogni pulizia di post_content_filtered. E se tu, per qualsiasi motivo, volessi cancellarlo?

Ho detto che ogni modifica di un post in WP viene 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 query $wpdb, non attiva il nostro filtro, quindi il reset viene eseguito senza problemi, e ovunque nel tuo codice hai bisogno di resettare post_content_filtered, puoi chiamare questa funzione.

Puoi anche creare un metabox con un pulsante 'Pulisci content filtered' e quando questo pulsante viene cliccato chiamare semplicemente la tua funzione reset_post_content_filtered, ad esempio via Ajax.

11 set 2013 06:04:50