web-dev-qa-db-fra.com

Supprimer les révisions après publication

Est-il possible de supprimer des révisions de publication/page de la base de données lorsqu'un article/page est publié?

11/05/12 Réponse: Voir le plugin ci-dessous par bueltge

Je souhaite le faire sur un site contenant 5 000 messages et 125 000 commentaires. il est sur un VPS et peut gérer la taille de la table wp_posts - avant que je ne supprime toutes les révisions, la table comptait 1,5 gigs - mais je veux toujours garder la taille de la base de données globale au minimum en empêchant les révisions.

Mais le client me dit qu'il a perdu un gros message en raison d'un gel du navigateur. Par conséquent: est-il possible de supprimer les révisions de publication/page de la base de données pour chaque publication/page lors de sa publication?

Quel crochet serait utilisé? Est-ce que save_post est le bon? http://codex.wordpress.org/Plugin_API/Action_Reference/save_post

Le paramètre de sauvegarde automatique est défini dans wp-config.php, mais selon la documentation, il enregistre automatiquement la publication/page au fur et à mesure de son travail et écrase chaque sauvegarde automatique.

Ce que je veux faire, c’est accumuler les révisions pour les brouillons - quel qu’en soit le nombre - en fonction du nombre de fois où "Enregistrer" et "Mise à jour" sont utilisés par l’auteur - mais une fois le brouillon publié, supprimez toutes les révisions. Il n'y aura que des révisions pour une publication, mais plutôt que d'essayer d'analyser post_ID, la requête SQL peut être exécutée dans toutes les publications.

C’est ce que j’essaie dans functions.php, mais j’obtiens une erreur Call to a member function query() on a non-object.

function delete_revisions_on_publish( $post_id ) {

    if ( !wp_is_post_revision( $post_id ) ) {

remove_action('save_post', 'delete_revisions_on_publish');

    $wpdb->query( 
    $wpdb->prepare( 
    "DELETE a,b,c
    FROM wp_posts a
    LEFT JOIN wp_term_relationships b ON (a.ID = b.object_id)
    LEFT JOIN wp_postmeta c ON (a.ID = c.post_id)
    WHERE a.post_type = 'revision' "
        )
);
        }
}
add_action( 'save_post', 'delete_revisions_on_publish' );
1
markratledge

Je pense qu'un petit plugin avec le hook 'publish_posts' est suffisant. Mais je ne connais pas de fonction essentielle pour supprimer les révisions et j’utilise une requête avec les fonctions WP. La source n'est pas testée, écrite uniquement pour ce post.

<?php
/**
 * Plugin Name: WPSE71248 Delete Revisions on Publish Posts
 * Plugin URI:  http://wordpress.stackexchange.com/questions/71248/
 * Description: 
 * Version:     1.0.0
 * Author:      Frank Bültge
 * Author URI:  http://bueltge.de
 * License:     GPLv3
 */

! defined( 'ABSPATH' ) and exit;

add_action( 'publish_post', 'fb_remove_revisions' );

function fb_remove_revisions( $post_id = FALSE ) {

    $post_id = (int) $post_id;

    $revisions = '';
    // Get the revisions
    $revisions = new WP_Query( array(
        'post_status'    => 'inherit',
        'post_type'      => 'revision',
        'showposts'      => -1,
        'posts_per_page' => -1,
        'post_parent'    => $post_id
    ) );

    if ( empty( $revisions ) )
        return $post_id;

    // Remove the revisions the non-core-way
    global $wpdb;
    foreach ( $revisions->posts as $revision ) {
        $query = $wpdb->prepare(
            "
            DELETE FROM $wpdb->posts 
            WHERE ID = %d
            AND post_parent = %d
            ",
            $revision->ID, 
            $post_id
        );
        $wpdb->query( $query );
    }

    return $post_id;
}

Vous pouvez également utiliser le téléchargement depuis Gist 4017151

5
bueltge

Je préférerais une approche différente pour y parvenir. Plutôt que d'utiliser le $wpdb global pour accéder directement à la base de données et supprimer des révisions, j'ai utilisé les fonctions WP. Le code suivant supprimera les révisions de Publish ou Update de tous les types de publication prenant en charge revisions et ayant le statut publish:

add_action( 'admin_init', 'add_delete_revision_actions' );
function add_delete_revision_actions () {

    // get all post types, except 'revision'
    $post_types = get_post_types( array( 'exclude_from_search' => false ) );

    // add action for each post type that supports 'revisions'
    foreach ($post_types as $post_type) {
        if ( post_type_supports( $post_type, 'revisions' )) {
            add_action("publish_$post_type", 'delete_revisions_on_publish', 10, 1);
        }
    }
}

function delete_revisions_on_publish ($post_id) {

    // get revisions for this post
    $revisions = wp_get_post_revisions($post_id);

    // .. and delete it
    foreach ($revisions as $revision) {
        $delete = wp_delete_post_revision($revision->ID);
        // check for errors
        // if ( is_wp_error($delete) ) { ... }
    }
}
1
Ahmad M

Cela devrait être possible et on dirait que vous êtes sur la bonne voie.

Pour résoudre votre erreur "Appelez une fonction membre", je pense que vous avez besoin de global $wpdb; en haut de cette fonction.

Je pense que le crochet appelé auparavant publish_post serait un meilleur crochet pour vous car il est spécifique aux publications. save_post sera exécuté pour toutes les sauvegardes.

En outre, vous dites que "la requête SQL peut parcourir toutes les publications", mais cela effacera les révisions de tous les brouillons si vous avez plusieurs publications dans les travaux ou si vous enregistrez une modification dans une publication publiée alors que vous avez un brouillon dans les travaux. Quoi qu'il en soit, c'est votre choix, mais vous n'avez pas du tout besoin de $wpdb->prepare si vous le faites. Il n'y a pas d'autre entrée que la chaîne SQL codée en dur, il n'est donc pas nécessaire de "préparer" quoi que ce soit.

$wpdb->query( 
    $wpdb->prepare( 
    "DELETE a,b,c
    FROM wp_posts a
    LEFT JOIN wp_term_relationships b ON (a.ID = b.object_id)
    LEFT JOIN wp_postmeta c ON (a.ID = c.post_id)
    WHERE a.post_type = 'revision' 
    AND a.ID = %d",
    $post_id
  )
);
0
s_ha_dum