web-dev-qa-db-fra.com

Supprimer tous les messages de WordPress, sauf les derniers messages X

Sur un projet, je ne dois garder que 10 derniers messages sur le site Web et supprimer automatiquement tous les autres messages. J'ai donc créé cette fonction qui déclenche la publication/la mise à jour et j'ai utilisé le paramètre offset pour exclure les 10 derniers éléments.

function wpse_auto_delete_posts( $post_ID ) {
  global $post;

  $delete_posts = get_posts( array( 'post_type' => 'post', 'offset' => 10, 'posts_per_page' => -1 ) );
  foreach ( $delete_posts as $delete_post ) : setup_postdata( $delete_post );
    wp_delete_post( $delete_post->ID, true );
  endforeach;
  wp_reset_postdata();

}
add_action( 'publish_post', 'wpse_auto_delete_posts' );

Mais il semble que offset n'a pas fonctionné ici avec 'posts_per_page' => -1 et la suppression continue de toutes les publications. J'ai pensé à utiliser la requête Date mais cela ne fonctionnera pas non plus, car de nouveaux messages sont créés très fréquemment.

Existe-t-il un moyen de sélectionner toutes les publications, à l'exception des dernières 10 ou 5. Ainsi, WordPress peut les traiter et conserver les dernières publications X.

6
Robert hue

Le paramètre offsetest ignoré avec posts_per_page défini sur -1 dans WP_Query. Si vous examinez le code source dans la classe WP_Query, posts_per_page=-1 définit nopagingsur true.

if ( !isset($q['nopaging']) ) {
    if ( $q['posts_per_page'] == -1 ) {
        $q['nopaging'] = true;
    } else {
        $q['nopaging'] = false;
    }
}

Ceci n’ajoute pas le nom LIMITà la requête SQL (empty($q['nopaging'] === false qui échoue avec l’instruction conditionnelle), ce qui signifie que toute la pagination/l’offset est ignorée et que toutes les publications sont renvoyées, quel que soit le résultat.

if ( empty($q['nopaging']) && !$this->is_singular ) {
    $page = absint($q['paged']);
    if ( !$page )
        $page = 1;

    if ( empty($q['offset']) ) {
        $pgstrt = absint( ( $page - 1 ) * $q['posts_per_page'] ) . ', ';
    } else { // we're ignoring $page and using 'offset'
        $q['offset'] = absint($q['offset']);
        $pgstrt = $q['offset'] . ', ';
    }
    $limits = 'LIMIT ' . $pgstrt . $q['posts_per_page'];
}

Je pense que la meilleure solution consiste à utiliser PHP (array_slice()) _ normal après avoir reçu tous les articles. Vous voulez obtenir uniquement les identifiants de post ici car wp_delete_post est assez coûteux à exécuter et n'a besoin que de l'identifiant de post, nous n'avons donc besoin d'aucune autre information de post.

En bref, votre requête ressemblera à ceci: (NOTE:Ceci n’a pas été testé et nécessite PHP 5.4+)

add_action( 'publish_post', function ( $post_ID ) 
{
    $args = [
        'nopaging' => true,
        'fields'   => 'ids'
    ];
    $posts_array = get_posts( $args );
    // Make sure that we have post ID's returned
    if ( $posts_array ) {
        // Get all post ids after the 10th post using array_slice
        $delete_posts = array_slice( $posts_array, 10 );
        // Make sure that we actually have post ID's in the $delete_posts array
        if ( $delete_posts ) {
            foreach ( $delete_posts as $delete_post )
                wp_delete_post( $delete_post, true );
        }
    }
});

EDIT

Juste avant que j'oublie, vous pouvez également définir posts_per_page comme valeur entière improbable au lieu de -1. Cela fonctionnera également avec votre code avec le jeu de paramètres offsetname__

6
Pieter Goosen

Le fait que 'nopaging' => true et 'posts_per_page' => -1 se comporte de la même manière. Ces paramètres annulent la clause LIMIT de la requête MySQL faite par votre WP.

offset (int) - nombre de messages à déplacer ou à passer. Avertissement: La définition du paramètre offset annule/ignore le paramètre paginé et interrompt la pagination (cliquez ici pour obtenir une solution de contournement). Le paramètre 'offset' est ignoré lorsque 'posts_per_page' => - 1 (afficher tous les messages) est utilisé.

Considérant les docs MySQL et leurs recommandations, vous pouvez utiliser un grand nombre pour le paramètre posts_per_page, en laissant offset tel quel.

Pour récupérer toutes les lignes d'un certain décalage jusqu'à la fin du jeu de résultats, vous pouvez utiliser un nombre élevé pour le deuxième paramètre. Cette instruction récupère toutes les lignes de la 96ème à la dernière:

SELECT * FROM tbl LIMIT 95,18446744073709551615;

0
Ignat B.