Wie lösche ich alle Benutzer ohne Beiträge in großen Mengen?

8

Ich habe 10 Tausend Benutzer, ungefähr 98% dieser Benutzer haben nie einen Beitrag veröffentlicht (ich meine Beitrag keine Kommentare).

Ich brauche eine Möglichkeit, Benutzer mit 0 Beiträgen massenweise zu löschen.

Die Methode muss alle Beiträge zählen, die benutzerdefinierte Beitragstypen enthalten, und muss die richtige WordPress-Funktion verwenden, um einen Benutzer so zu löschen, als ob sie manuell im Dashboard gelöscht worden wären, und nicht nur eine Tabelle / Zeile auf MySQL zu löschen, da dies zu unerwarteten Ergebnissen führen könnte.

Es gibt ein altes Plugin , das dies tut, aber nicht alle Beitragstypen berücksichtigt und daher nicht wirklich verwendet werden kann.

Jede Hilfe geschätzt.

Michael Rogers
quelle
3
Sie können den Code in meiner Antwort hier einfach wiederverwenden: wordpress.stackexchange.com/a/231485/24875
Christine Cooper

Antworten:

8

Wenn Sie eine große Anzahl von Benutzern löschen müssen, können Sie den Befehl wp user delete wp-cli verwenden , um Skript-Timeouts zu vermeiden.

Hier ist ein Beispiel für eine SQL-Abfrage zum Löschen aller Benutzer ohne Beiträge jeglichen Typs und Status .

Sie können daher diesen ungetesteten Einzeiler ausprobieren :

wp user delete $(wp db query "SELECT ID FROM wp_users WHERE ID NOT IN (SELECT DISTINCT post_author FROM wp_posts ) AND ID NOT IN (1,2,3)" | tail -n +2 ) --reassign=1

oder in erweiterter Form:

wp user delete $(wp db query
    "SELECT ID  
         FROM wp_users   
         WHERE ID NOT IN (  
            SELECT DISTINCT post_author FROM wp_posts 
         ) AND ID NOT IN (1,2,3)" | tail -n +2 
  ) --reassign=1

Beachten Sie, dass wir eine zusätzliche AND ID NOT IN (1,2,3)Einschränkung hinzugefügt haben , um sicherzustellen, dass diese Benutzer nicht gelöscht werden (z. B. Administratorbenutzer). Sie müssen es an Ihre Bedürfnisse und auch an das Tabellenpräfix anpassen wp_.

Als ich dies für einige Benutzer kurz testete, bemerkte ich, dass ich das tail -n +2Teil hinzufügen musste , um die oberen 3 Zeilen in der Kopfzeile und den Tabellenrand der wp db queryAusgabe zu vermeiden .

Hier weisen wir Benutzer 1 alle Beiträge neu zu, um den Hinweis zu vermeiden:

--reassign parameter not passed. All associated posts will be deleted. Proceed? [y/n] 

Ich hoffe, Sie können es weiter an Ihre Bedürfnisse anpassen, z. B. indem Sie die Löschbedingungen des Benutzers durch Hinzufügen lockern WHERE post_status = 'publish'.

Hinweis: Denken Sie daran, vor dem Testen ein Backup zu erstellen!

Birgire
quelle
Ich verstehe es nicht Das erneute Durchsuchen von Posts sollte nicht erfolgen. Ich möchte keine Benutzer löschen, die nur solche mit 0 Posts gepostet haben. Es sollte kein erneutes Durchsuchen erfolgen.
Michael Rogers
1
Dieses spezielle Beispiel sollte davon nicht betroffen sein, da wir auf einen Beitragstyp und -status abzielen. Dies diente nur dazu, die Benachrichtigung über den Befehl wp delete user zu vermeiden. Sie können ihn auch überspringen und für alle drücken Yoder verwenden --yes. Wenn Sie die SQL so ändern, dass nur Benutzer gelöscht werden, die Beiträge veröffentlicht haben, benötigen Sie diese möglicherweise, um das Löschen von z. B. Entwürfen zu vermeiden. Beachten Sie, dass Sie in der Frage Benutzer erwähnt haben, die noch nie einen Beitrag veröffentlicht haben . Dies bedeutet streng genommen, dass sie möglicherweise Entwürfe haben. Ich nahm an, dass du das nicht im Sinn hattest ;-) Bitte sei sehr genau in der Frage, was du löschen möchtest, um das Rätselraten zu vermeiden. @ MichaelRogers
Birgire
4

Hier ist eine Möglichkeit, dies in PHP zu tun. Es mag langsam und / oder zeitlich begrenzt sein, aber da es eine einmalige Sache ist, sollte es nicht zu viel ausmachen. Platzieren Sie es vorübergehend in Ihrer functions.php oder laden Sie es als neues Plugin hoch.

//* You don't want to run this on admin_init. Run it once and deactivate
add_action( 'admin_init', 'wpse_262100_admin_init' );
function wpse_262100_admin_init() {
  $reserved_post_types = [
    'attachment',
    'revision',
    'nav_menu_item',
    'custom_css',
    'customize_changeset',
  ];

  //* Get the non-reserved post types
  $post_types = array_diff( array_keys( get_post_types() ), $reserved_post_types );
  foreach( get_users() as $user ) {
    if( 0 == count_user_posts( $user->ID, $post_types ) ) {
      wp_delete_user( $user->ID );
    }
  }
}
Nathan Johnson
quelle
1

Gemessen am Quellcode des alten Plugins, das Sie erwähnt haben, sind die Post-Typen, die nicht berücksichtigt werden, Anhang und Überarbeitung . Ich denke, Sie können dies leicht beheben, indem Sie dies aus dem Quellcode der Plugin-Datei no-posts-user-delete.php entfernen

    AND NOT WP.post_type in ('attachment', 'revision')
Nikolay
quelle
Es tut uns leid! Ich meinte benutzerdefinierte Beitragstypen. Der Autor hat in den Support-Foren geschrieben, dass benutzerdefinierte Beitragstypen nicht nur "Beiträge" gezählt werden, sodass Benutzer gelöscht werden, die benutzerdefinierte Beiträge erstellt haben, und das ist nicht gut.
Michael Rogers
@ MichaelRogers Ich glaube nicht, dass er das so meint. Wie gesagt, die einzigen Typen, die nicht gezählt werden, sind die beiden, die ich geschrieben habe. Das Plugin sollte sich also auf benutzerdefinierte Beitragstypen auswirken. Sie werden in derselben Datenbanktabelle gespeichert. Ich schlage vor, dass Sie ein Backup erstellen und dann das Plugin ausprobieren und prüfen, ob es so funktioniert, wie Sie es möchten. Wenn dies nicht der Fall ist, stellen Sie die Sicherung wieder her.
Nikolay