Eliminar todos los suscriptores de wp_users y wp_usermeta unos miles a la vez
Tengo un sitio con 70K suscriptores spam, y no necesito ninguno de ellos. Necesito eliminar todos los suscriptores de wp_users y los metadatos asociados en wp_usermeta usando una consulta en adminer o phpmyadmin.
Pero para evitar saturar el servidor, ¿cómo puedo borrar unos miles a la vez?
Esta parece ser la consulta básica que necesito:
DELETE
FROM wp_users
INNER JOIN wp_usermeta ON wp_users.ID = wp_usermeta.user_id
WHERE meta_key = 'wp_capabilities'
AND meta_value LIKE '%subscriber%'
// ¿excepto cómo selecciono unos miles a la vez?
¿Pero cómo selecciono unos miles a la vez?
Mi forma favorita de hacer algo como esto no es mediante la manipulación de la base de datos (lo cual siempre me preocupa que pueda tener efectos secundarios), sino a través de una herramienta de línea de comandos.
Por ejemplo, teniendo una instalación funcional de WP CLI, puedes simplemente ejecutar esto:
wp user delete $(wp user list --role=subscriber --field=ID --number=10) --reassign=1
El parámetro reassign
es el ID del usuario al que se reasignará el contenido. Podemos usar "--number" (el límite), aunque no está bien documentado, porque WP_User_Query lo soporta.
Ahí lo tienes - una utilidad de línea de comandos limpia y de una sola línea para realizar operaciones como esta.
Recomendaría que en este caso primero pruebes la subconsulta "wp user list..." para ver qué usuarios se eliminarán. Después de ejecutar el comando de una línea, verás información como esta:
...
Éxito: Usuario 123 eliminado de https://example.com/.
Éxito: Usuario 124 eliminado de https://example.com/.
...

Puedes usar la función de WordPress para esto. wp_delete_user(); esta función trabaja con el ID de usuario. Puedes obtener todos los IDs de usuarios suscriptores de esta manera: get_users() obteniendo tus usuarios filtrados.
$get_subscribers = get_users('role=subscriber');
foreach($get_subscribers as $user){
wp_delete_user($user->ID);
}

Tuve un problema similar y después de leer esta pregunta hice este plugin (adaptado para tu pregunta).
Una vez instalado, crea un menú de administración bajo Usuarios llamado Eliminación Masiva de Usuarios. Cuando accedes a esta página, elimina los usuarios en lotes, de 20 en 20 según tu consulta SQL (mi consulta original era ligeramente diferente).
Puedes hacer los lotes más pequeños o más grandes, pero esto te permite eliminar muchos usuarios sin que el servidor se bloquee, aunque puede tomar algunos minutos si hay muchos registros de spam.
Utiliza jQuery para recargar la página después de procesar cada lote (esto podría hacerse con AJAX, supongo, pero necesitaba algo rápido).
Quizás alguien más encuentre esto útil. Lo más probable es que necesites adaptar la consulta SQL a tu situación.
<?php
/*
Plugin Name: Eliminación Masiva de Usuarios Spam
Description: Elimina los registros de spam
Version: 0.1
Author: Steven
Text Domain: bulk-delete-spam-users
*/
add_action('admin_menu', 'my_users_menu');
function my_users_menu() {
add_users_page('Eliminación Masiva de Usuarios', 'Eliminación Masiva de Usuarios', 'read', 'bulk-user-delete', 'active_users_nodel');
}
function active_users_nodel() {
global $wpdb;
$result = array();
$result = $wpdb->get_results('
SELECT wp_users.id, wp_users.user_login FROM wp_users
INNER JOIN wp_usermeta ON wp_users.ID = wp_usermeta.user_id
WHERE meta_key = "wp_capabilities"
AND meta_value LIKE "%subscriber%"
');
$users = $result;
$i = 0;
echo '<div class="bud-box">';
$users_remain = $users ? 'true' : 'false';
$current_user = wp_get_current_user();
echo '<strong>El contenido huérfano será reasignado a:</strong><br />';
echo 'Nombre de usuario: ' . $current_user->user_login . '<br />';
echo 'ID de usuario: ' . $current_user->ID . '<br />';
<h3>eliminando actualmente...</h3>
foreach($users as $user) {
$i++;
if($i < 20) {
wp_delete_user( $user->ID, $current_user->ID );
var_dump($user->user_login);
}
}
echo '</div>';
?>
<script>
(function($){
$(document).ready(function(){
var uremain = <?php echo $users_remain; ?>;
if( uremain == true){
location.reload();
}
});
})(jQuery);
</script>
<?php } ?>

No puedo activar este plugin. Tienes un error en tu código, falta el echo alrededor del <h3>currently deleting...</h3>

posible con límite en caso de lotes grandes o recursos limitados:
DELETE
FROM wp_users
WHERE EXISTS
( SELECT t2.user_id
FROM wp_usermeta AS t2
WHERE t2.user_id = wp_users.ID
AND t2.meta_key ='wp_capabilities' AND meta_value LIKE '%customer%'
)
ORDER BY ID DESC
LIMIT 10000
