Comment supprimer en bloc tous les utilisateurs sans publication?

8

J'ai 10 mille utilisateurs, environ 98% de ces utilisateurs n'ont jamais publié de message (je veux dire un message et non des commentaires).

J'ai besoin d'un moyen de supprimer en masse les utilisateurs avec 0 messages.

La méthode doit compter tous les messages, y compris les types de messages personnalisés et doit utiliser la fonction WordPress appropriée pour supprimer un utilisateur comme s'ils avaient été supprimés manuellement dans le tableau de bord et pas simplement déposer un tableau / une ligne sur mysql, car cela pourrait entraîner des résultats inattendus.

Il existe un ancien plugin qui fait cela, mais ne prend pas en compte tous les types de messages, il ne peut donc pas vraiment être utilisé.

Toute aide appréciée.

Michael Rogers
la source
3
Vous pouvez simplement réutiliser le code dans ma réponse ici: wordpress.stackexchange.com/a/231485/24875
Christine Cooper

Réponses:

8

Si vous avez un grand nombre d'utilisateurs à supprimer, vous pouvez utiliser la commande wp user delete wp-cli pour éviter les délais d'expiration des scripts.

Voici un exemple de requête SQL pour supprimer tous les utilisateurs sans messages de tout type et de tout statut .

Vous pouvez donc essayer ce one-liner non testé :

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

ou sous forme développée:

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

Notez que nous avons ajouté une AND ID NOT IN (1,2,3)restriction supplémentaire pour vous assurer que ces utilisateurs ne sont pas supprimés (par exemple, les utilisateurs administrateurs). Vous devrez l'adapter à vos besoins ainsi qu'au préfixe de la table wp_.

Lorsque j'ai brièvement testé cela pour quelques utilisateurs, j'ai remarqué que je devais ajouter la tail -n +2partie pour éviter les 3 premières lignes de l'en-tête et la bordure du tableau de la wp db querysortie.

Ici, nous réaffectons tous les messages à l'utilisateur 1, pour éviter la notification:

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

J'espère que vous pourrez l'ajuster davantage à vos besoins, comme assouplir les conditions de suppression de l'utilisateur en les ajoutant WHERE post_status = 'publish'.

Remarque: N'oubliez pas de sauvegarder avant de tester!

Birgire
la source
Je ne comprends pas. Les messages rassurants ne devraient pas se produire. Je ne veux pas supprimer les utilisateurs qui ont publié uniquement ceux avec 0 messages.
Michael Rogers
1
Cela ne devrait pas affecter cet exemple spécifique car nous ciblons tout type et statut de publication. C'était juste pour éviter la notification de la commande utilisateur wp delete. Vous pouvez également la sauter et appuyer You utiliser --yespour tout. Si vous modifiez le SQL pour supprimer uniquement les utilisateurs qui ont publié des articles, vous en aurez peut-être besoin pour éviter de supprimer, par exemple, les brouillons. Notez que vous avez mentionné dans la question les utilisateurs qui n'ont jamais publié de message .. Cela signifie strictement qu'ils pourraient avoir des brouillons. Je supposais que vous n'aviez pas cela à l'esprit ;-) Veuillez être très précis dans la question de ce que vous voulez supprimer pour éviter toute conjecture. @MichaelRogers
birgire
4

Voici un moyen de le faire en PHP. Cela peut être lent et / ou timeout, mais comme c'est une chose unique, cela ne devrait pas trop d'importance. Placez temporairement dans votre fichier functions.php ou téléchargez-le en tant que nouveau plugin.

//* 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
la source
1

À en juger par le code source de l'ancien plugin que vous avez mentionné, les types de publication qu'il ne considère pas sont les pièces jointes et les révisions . Je pense que vous pouvez facilement résoudre ce problème en le supprimant du code source du fichier plugin no-posts-user-delete.php

    AND NOT WP.post_type in ('attachment', 'revision')
Nikolay
la source
Désolé! Je voulais dire des types de messages personnalisés. L'auteur a écrit sur les forums de support qu'il ne compte pas les types de messages personnalisés uniquement "post", donc cela supprimerait les utilisateurs qui ont fait des messages personnalisés et ce n'est pas bon.
Michael Rogers
@MichaelRogers Je ne pense pas qu'il pense cela. Comme je l'ai dit, les seuls types qui ne sont pas comptés sont les deux que j'ai écrits. Le plugin devrait donc affecter les types de publication personnalisés. Ils sont stockés dans la même table de base de données. Je vous suggère de faire une sauvegarde puis d'essayer le plugin et de voir si cela fonctionne comme vous le souhaitez. Si ce n'est pas le cas, restaurez la sauvegarde.
Nikolay