Como excluir em massa todos os usuários sem postagens?

8

Eu tenho 10 mil usuários, cerca de 98% desses usuários nunca publicaram um post (quero dizer, post não comentários).

Eu preciso de uma maneira de excluir em massa os usuários com 0 postagens.

O método deve contar todas as postagens incluídas nos tipos de postagem personalizados e deve usar a função adequada do WordPress para excluir um usuário como se fosse excluído manualmente no painel e não apenas soltar uma tabela / linha no mysql, pois isso pode causar resultados inesperados.

um plug-in antigo que faz isso, mas não considera todos os tipos de postagem, portanto não pode ser realmente usado.

Qualquer ajuda apreciada.

Michael Rogers
fonte
3
Você pode simplesmente reutilizar o código na minha resposta aqui: wordpress.stackexchange.com/a/231485/24875
Christine Cooper

Respostas:

8

Se você tiver um grande número de usuários para excluir, poderá usar o comando wp user delete wp-cli para evitar o tempo limite do script.

Aqui está um exemplo de uma consulta SQL para excluir todos os usuários sem postagens de qualquer tipo e status .

Portanto, você pode tentar esta linha única não testada :

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 em forma expandida:

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

Observe que adicionamos uma AND ID NOT IN (1,2,3)restrição extra para garantir que esses usuários não sejam excluídos (por exemplo, usuários administrativos). Você precisará ajustá-lo às suas necessidades e também ao prefixo da tabela wp_.

Quando testei brevemente isso para alguns usuários, notei que era necessário adicionar a tail -n +2peça para evitar as três principais linhas do cabeçalho e a borda da tabela da wp db querysaída.

Aqui, redesignamos todas as postagens para o usuário 1, para evitar o aviso:

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

Espero que você possa ajustá-lo ainda mais às suas necessidades, como relaxar as condições de exclusão do usuário adicionando WHERE post_status = 'publish'.

Nota: Lembre-se de fazer backup antes de testar!

Birgire
fonte
Eu não entendo. Reassing posts não deve acontecer. Não quero excluir usuários que postaram apenas aqueles com 0 posts, nenhum reassing deve acontecer.
Michael Rogers
1
Não deve afetar este exemplo específico, pois segmentamos qualquer tipo e status de postagem. Isso foi apenas para evitar o aviso do comando wp delete user. Você também pode ignorá-lo e pressionar You usar --yespara todos. Se você modificar o sql para excluir apenas os usuários que publicaram postagens, poderá ser necessário evitar a exclusão, por exemplo, de rascunhos. Observe que você mencionou na pergunta usuários que nunca publicaram uma postagem . Isso significa estritamente que eles podem ter rascunhos. Supus que você não tinha isso em mente ;-) Por favor, seja muito específico na pergunta que deseja excluir para evitar as suposições. @MichaelRogers
birgire
4

Aqui está uma maneira de fazer isso em PHP. Pode ser lento e / ou tempo limite, mas como é uma coisa única, não deve importar muito. Coloque temporariamente dentro do seu functions.php ou faça o upload como um novo 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
fonte
1

A julgar pelo código fonte do plug-in antigo que você mencionou, os tipos de postagem que ele não considera são anexos e revisão . Eu acho que você pode facilmente corrigir isso removendo isso do código-fonte do arquivo de plugin no-posts-user-delete.php

    AND NOT WP.post_type in ('attachment', 'revision')
Nikolay
fonte
Desculpa! Eu quis dizer tipos de postagem personalizados. O autor escreveu nos fóruns de suporte que não conta os tipos de postagem personalizados apenas "postagem" para excluir os usuários que fizeram postagens personalizadas e isso não é bom.
Michael Rogers
@ MichaelRogers Eu não acho que ele quis dizer isso. Como eu disse, os únicos tipos que não são contados são os dois que escrevi. Portanto, o plug-in deve afetar os tipos de postagem personalizados. Eles são armazenados na mesma tabela de banco de dados. Sugiro que você faça um backup e tente o plug-in e veja se ele funciona como você deseja. Caso contrário, restaure o backup.
Nikolay