web-dev-qa-db-fra.com

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

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

Par exemple, Markdown on Save stocke la version de réduction d’une publication séparément dans la colonne post_content_formatted et le code HTML analysé dans la colonne post_content de sorte que, lorsque le plug-in est désactivé, les publications ne soient pas expulsées par Markdown (car HTML est stocké dans post_content).

Maintenant, je me suis rendu compte que post_content_filtered est plutôt 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, balises, catégories, etc.) à l'aide de l'option "Édition rapide"

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

  • vous faites des modifications en vrac aux articles

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

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

Questions:

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

  2. Y a-t-il un moyen d'empêcher que cela ne se produise? (Je veux dire, y a-t-il un moyen de s’assurer que les données sont stockées de manière permanente, comme la colonne post_content est traitée?)

27
its_me

Chaque mise à jour dans WordPress est gérée par la fonction wp_update_post.

Cette fonction a des valeurs par défaut. Pour post_content_filtered, la valeur par défaut est '' (chaîne vide).

Une fois que les valeurs par défaut sont fusionnées avec les arguments passés à function via wp_parse_args, cela signifie que chaque fois qu'une publication est mise à jour et que post_content_filtered n'est pas explicitement passé, il est défini sur une chaîne vide.

Nous pouvons maintenant demander: quand le post_content_filtered est-il explicitement passé à 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 message est mis à jour, pour une raison quelconque .

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, à publier ultérieurement, à publier dans la corbeille (une suppression de publication), etc.

Si quelque chose change dans une publication, alors post_content_filtered est effacé; La seule exception est lorsque post_content_filtered est explicitement passé à wp_update_post, et comme déjà dit, cela n'est jamais fait par WordPress.

Y a-t-il un moyen d'empêcher que cela ne se produise? (Je veux dire, existe-t-il un moyen de s’assurer que les données sont stockées de manière permanente?

Si vous créez ce champ avec votre code et que vous souhaitez le conserver, vous devez consulter every update effectué par WordPress et empêcher le changement.

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

Le crochet que je suggère est le wp_insert_post_data pour 2 raisons:

  • Il exécute before la mise à jour, vous n'avez donc pas besoin de recover mais vous pouvez prevent
  • 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_post, vous êtes en mesure de comparer la publication actuelle et la publication suivante: si vous n'aimez pas quelque chose, vous pouvez le modifier.

Let's code:

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 tous les post_content_filtered nettoyage. Et si vous , pour quelque raison que ce soit, vous voulez l’effacer?

J'ai dit que chaque WP publication est modifiée 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
    ) );
}

S'agissant d'une requête $wpdb, notre filtre n'est pas déclenché. La réinitialisation s'effectue donc sans problème. Vous pouvez appeler cette fonction partout dans votre code pour réinitialiser post_content_filtered.

Vous pouvez également créer une métabox avec le bouton "Effacer le contenu filtré". Lorsque ce bouton est cliqué, appelez simplement votre fonction reset_post_content_filtered, par exemple. via Ajax.

28
gmazzap