Quand la colonne 'post_content_filtered' de la base de données est-elle effacée par WordPress?

29

Certains plugins WordPress (bien que très peu) utilisent la post_content_filteredcolonne dans la base de données pour enregistrer certaines données liées à un message.

Par exemple, Markdown on Save stocke la version markdown d'un article séparément dans la post_content_formattedcolonne et le code HTML analysé dans la post_contentcolonne, de sorte que lorsque le plugin est désactivé, les articles ne vomissent pas Markdown (car le code HTML est stocké dans post_content).

Maintenant, je me suis rendu compte que post_content_filteredc'est à peu près utilisé pour le stockage temporaire, c'est-à-dire que le contenu de la colonne est perdu (ou effacé) lorsque:

  • vous apportez des modifications à un article (titre, tags, catégories, etc.) à l'aide de l'option «Édition rapide»

  • une publication programmée est (automatiquement) publiée

  • vous effectuez des modifications groupées des messages

  • vous basculez entre les révisions d'un article

  • une publication est enregistrée à partir d'un éditeur externe (c'est-à-dire pas de l'éditeur de publication WordPress)

Des questions:

  1. Dans quelles autres situations les données de la post_content_filteredcolonne sont-elles effacées?

  2. Existe-t-il un moyen d'empêcher que cela se produise? (Je veux dire, existe-t-il un moyen de s'assurer que les données sont stockées en permanence, la façon dont la post_contentcolonne est traitée?)

c'est moi
la source

Réponses:

29

Chaque mise à jour post dans WordPress est gérée par la wp_update_postfonction.

Cette fonction a des valeurs par défaut, et pour post_content_filteredla valeur par défaut est '' (chaîne vide).

Une fois que les valeurs par défaut sont fusionnées avec les arguments passés à la fonction via wp_parse_argscela signifie que chaque fois qu'une publication est mise à jour et post_content_filteredn'est pas explicitement transmise, elle est définie sur une chaîne vide.

Maintenant, nous pouvons demander: quand est-il post_content_filteredexplicitement transmis à wp_update_post? La réponse est: jamais par WordPress.

Donc pour votre première question:

Dans quelles autres situations les données de la colonne post_content_filtered sont-elles effacées?

La réponse courte est: chaque fois qu'un article est mis à jour, pour quelque raison que ce soit .

Notez que la modification d'un seul champ est une mise à jour, en particulier, chaque changement de statut est une mise à jour, par exemple, brouillon à publier, en attente de publication, futur à publier, publier dans la corbeille (une suppression de publication), etc.

Si quelque chose change dans un message, il post_content_filteredest effacé; la seule exception est quand post_content_filteredest explicitement passé à wp_update_post, et comme déjà dit, cela n'est jamais fait par WordPress.

Existe-t-il un moyen d'empêcher cela de se produire? (Je veux dire, existe-t-il un moyen de s'assurer que les données sont stockées en permanence?

Si vous créez ce champ avec votre code et que vous souhaitez le conserver, vous devez regarder chaque mise à jour effectuée par WordPress et empêcher le changement.

Cela peut sembler un travail difficile, mais si vous lisez la première phrase de cette réponse, " Chaque mise à jour de poste dans WordPress est gérée par la wp_update_postfonction ", vous comprenez que la seule chose nécessaire est de regarder cette fonction, qui a heureusement différents crochets .

L'hameçon que je propose est le wp_insert_post_datapour 2 raisons:

  • Il s'exécute avant la mise à jour, vous n'avez donc pas à récupérer mais vous pouvez empêcher
  • Il passe 2 paramètres: les données que la fonction va mettre à jour, et un tableau des paramètres passés, qui (en cas de mise à jour) contiennent l'ID de la publication

Donc, en utilisant un simple, get_postvous pouvez comparer la façon dont le message est maintenant et comment le message sera: si vous n'aimez pas quelque chose, vous pouvez le changer.

Codons:

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;

}

Il y a un problème possible, où la fonction précédente empêche chaque post_content_filtered nettoyage. Et si vous , pour une raison quelconque, vous voulez l'effacer?

J'ai dit que chaque changement de publication WP est géré par wp_update_post, mais vous n'êtes pas WordPress.

Vous pouvez écrire une fonction comme:

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

Étant une $wpdbrequête, elle ne déclenche pas notre filtre, donc la réinitialisation se fait sans problème, et partout dans votre code que vous devez réinitialiser post_content_filtered, vous pouvez appeler cette fonction.

Vous pouvez également créer une métabox avec un bouton «Effacer le contenu filtré» et lorsque vous cliquez sur ce bouton, il vous suffit d'appeler votre reset_post_content_filteredfonction, par exemple via Ajax.

gmazzap
la source