wake-up-neo.net

Löschen Sie alle Beiträge von WordPress mit Ausnahme der neuesten X-Beiträge

Bei einem Projekt muss ich nur 10 aktuelle Beiträge auf der Website speichern und alle anderen Beiträge automatisch löschen. Also habe ich mir diese Funktion ausgedacht, die nach dem Veröffentlichen/Aktualisieren ausgelöst wird, und habe den Parameter offset verwendet, um die letzten 10 Elemente auszuschließen.

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' );

Aber es scheint, offset hat hier nicht mit 'posts_per_page' => -1 funktioniert und es werden weiterhin alle Beiträge gelöscht. Ich habe darüber nachgedacht, die Datumsabfrage zu verwenden, aber sie wird auch nicht funktionieren, da sehr häufig neue Beiträge erstellt werden.

Gibt es eine Möglichkeit, alle Posts mit Ausnahme der letzten 10 oder 5 auszuwählen? WordPress kann sie also verarbeiten und die letzten X Posts behalten.

6
Robert hue

Der Parameter offset wird ignoriert, wenn posts_per_page in -1 auf WP_Query gesetzt ist. Wenn Sie sich den Quellcode in der Klasse WP_Query ansehen, setzt posts_per_page=-1nopaging auf true.

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

Dadurch wird die LIMIT nicht an die SQL-Abfrage (empty($q['nopaging'] === false, die die bedingte Anweisung nicht erfüllt) angehängt, was bedeutet, dass die gesamte Paginierung/der gesamte Offset ignoriert wird und alle Posts unabhängig davon zurückgegeben werden

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'];
}

Ich denke, die beste Lösung ist es, normale PHP (array_slice()) zu verwenden, nachdem alle Posts abgerufen wurden. Sie möchten hier nur Post-IDs erhalten, da die Ausführung von wp_delete_post ziemlich teuer ist und nur die Post-ID wirklich benötigt, sodass wir keine weiteren Post-Informationen benötigen.

Kurz gesagt, Ihre Abfrage sieht folgendermaßen aus: (HINWEIS:Dies ist alles ungetestet und benötigt 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

Kurz bevor ich es vergesse, können Sie posts_per_page auch als einen unwahrscheinlichen ganzzahligen Wert anstelle von -1 definieren. Dies funktioniert auch mit Ihrem Code mit dem Parametersatz offset

6
Pieter Goosen

Die Tatsache, dass sich 'nopaging' => true und 'posts_per_page' => -1 gleich verhalten. Diese Parameter heben die LIMIT-Klausel der MySQL-Anforderung auf, die von Ihrem WP gesendet wurde.

offset (int) - Anzahl der zu verschiebenden oder zu übergebenden Pfosten. Warnung: Das Festlegen des Versatzparameters überschreibt/ignoriert den ausgelagerten Parameter und unterbricht die Paginierung (Klicken Sie hier, um dieses Problem zu umgehen). Der Parameter 'offset' wird ignoriert, wenn 'posts_per_page' => - 1 (alle Beiträge anzeigen) verwendet wird.

In Anbetracht der MySQL-Dokumente und ihrer Empfehlung können Sie für den Parameter posts_per_page eine große Zahl verwenden, wobei der Offset unverändert bleibt.

Um alle Zeilen von einem bestimmten Offset bis zum Ende der Ergebnismenge abzurufen, können Sie für den zweiten Parameter eine große Zahl verwenden. Diese Anweisung ruft alle Zeilen von der 96. bis zur letzten Zeile ab:

SELECT * FROM tbl LIMIT 95,18446744073709551615;

0
Ignat B.