Вопрос или проблема
Я настроил WP Multisite и написал функцию для ежедневного удаления всех блогов, кроме одного. Теперь, когда вы используете функцию wpmu_delete_blog(), блоги удаляются, однако их пользователи остаются и не ассоциированы с каким-либо сайтом. Я хочу получить всех этих пользователей и удалить их сразу после удаления блогов. Все пользователи, которых я создаю, получают роль ‘demouser’. Как мне это сделать?
Вам нужно выбрать всех доступных пользователей (см. $users
ниже), чтобы пройтись по каждому и определить, является ли он demouser; для удаления всех пользователей без ассоциированного сайта (см. empty($user_blogs)
ниже) вы можете вызвать wpmu_delete_user()
(для этого потребуется загрузить ms.php
, если вы загружаете его в теме или плагине).
Просто добавьте следующий фрагмент сразу после той части вашего кода, где вы удаляете блоги:
global $wpdb;
$users = $wpdb->get_results("SELECT ID, user_login FROM $wpdb->users");
foreach ( $users as $user ) :
$user_login = $user->user_login; // получить логин
$user_id = $user->ID; // получить ID
// проверить имя
if ( $user_login == 'demouser' ) :
$user_blogs = get_blogs_of_user( $user_id ); // получить связанные сайты
// проверить на пустоту
if ( empty($user_blogs) ) :
require_once ABSPATH . 'wp-admin/includes/ms.php';
wpmu_delete_user( $user_id ); // удалить пользователя
endif;
endif;
endforeach;
Будьте осторожны с этим, так как это удалит не назначенных пользователей, и вы не сможете восстановить удаленных пользователей!
Я знаю, что это старый пост, но я использовал этот код, чтобы создать пару команд WP-CLI на демонстрационном multisite и подумал, что это может быть полезным.
Мы настроили его в crontab для удаления сайтов, возраст которых превышает один день, плюс код здесь для очистки любых бездомных пользователей.
Команды: wp mytools clean_users
и wp mytools delete
.
<?php
class MyTools_WPCLI_Command extends WP_CLI_Command {
public function clean_users( $args, $assoc_args ) {
global $wpdb;
$delete = array();
$dryrun = false;
$users = $wpdb->get_results( "SELECT ID, user_login FROM $wpdb->users" );
if ( isset( $assoc_args['dry-run'] ) ) {
$dryrun = true;
}
WP_CLI::success( sprintf( 'Найдено %s пользователей', count( $users ) ) );
foreach ( $users as $user ) {
$user_login = $user->user_login;
$user_id = $user->ID;
if ( ! is_super_admin( $user_id ) ) {
$user_blogs = get_blogs_of_user( $user_id );
if ( empty( $user_blogs ) ) {
$delete[] = $user_id;
}
}
}
$total = count( $delete );
if ( ! $total ) {
WP_CLI::success( 'Нечего удалять!' );
exit();
}
if ( $dryrun ) {
WP_CLI::success( "[DRYRUN] Удалил бы $total пользователей." );
exit();
}
$progress = \WP_CLI\Utils\make_progress_bar( "Удаление $total пользователей", $total );
foreach ( $delete as $user_id ) {
require_once ABSPATH . 'wp-admin/includes/ms.php';
wpmu_delete_user( $user_id );
$progress->tick();
}
$progress->finish();
}
public function delete( $args, $assoc_args ) {
global $wpdb;
$blogs = $wpdb->get_results( "SELECT * FROM {$wpdb->blogs} where blog_id > '1' AND registered < NOW() - INTERVAL 1 DAY" );
$total = count( $blogs );
$dryrun = false;
if( isset( $assoc_args['dry-run'] ) ) {
$dryrun = true;
}
if( $total < 1 ) {
WP_CLI::success( 'Нет сайтов для удаления.' );
return false;
}
$progress = \WP_CLI\Utils\make_progress_bar( "Удаление $count сайтов", $total );
foreach ( $blogs as $blog ) {
$parts = explode( '.', $blog->domain );
if( ! $dryrun ) {
WP_CLI::runcommand( 'site delete ' . $blog->blog_id . ' --yes --quiet' );
WP_CLI::runcommand( 'user delete ' . $parts[0] . ' --yes --network --quiet' );
}
$progress->tick();
}
$progress->finish();
if( $dryrun ) {
WP_CLI::success( "[DRYRUN] Удалил бы $total сайтов." );
} else {
WP_CLI::success( "Удалено $total сайтов." );
}
}
}
WP_CLI::add_command( 'mytools', 'MyTools_WPCLI_Command' );
.
Ответ или решение
Удаление «сирот» пользователей в WordPress Multisite
В системе WordPress Multisite может возникнуть ситуация, когда после удаления сайтов (блогов) остаются пользователи, не привязанные к каким-либо активным сайтам. Эти «сироты» могут создавать лишнюю нагрузку на базу данных и усложнять управление пользователями, особенно если у вас есть система, в которой пользователи создаются автоматически, как в вашем случае с ролью ‘demouser’.
Проблема
Вы описали, что вы используете функцию wpmu_delete_blog()
для удаления всех блогов, кроме одного. Однако, несмотря на то, что блоги удалены, их пользователи остаются в базе данных без привязки к сайту. Вам необходимо найти и удалить всех пользователей с определённой ролью (‘demouser’), у которых нет связанных сайтов, чтобы очистить систему.
Решение
Для решения этой задачи можно использовать следующий подход: сначала получите список всех пользователей, затем проверьте для каждого пользователя, связаны ли с ним какие-либо блоги. Если блогов нет, и пользователь имеет роль ‘demouser’, удалите его с помощью функции wpmu_delete_user()
. Не забудьте загрузить файл ms.php
, так как он необходим для работы с мультисайтовыми функциями.
Пример кода
Вот пример кода, который можно добавить сразу после удаления блогов в вашей функции:
global $wpdb;
$users = $wpdb->get_results("SELECT ID, user_login FROM $wpdb->users");
foreach ( $users as $user ) :
$user_login = $user->user_login; // Получаем логин
$user_id = $user->ID; // Получаем ID
// Проверяем, если это 'demouser'
if ( $user_login == 'demouser' ) :
$user_blogs = get_blogs_of_user( $user_id ); // Получаем связанные сайты
// Проверяем, если блогов нет
if ( empty($user_blogs) ) :
require_once ABSPATH . 'wp-admin/includes/ms.php';
wpmu_delete_user( $user_id ); // Удаляем пользователя
endif;
endif;
endforeach;
Важные замечания
-
Осторожность при удалении: Прежде чем запустить этот код, убедитесь, что вы не удаляете нужных пользователей. Эту операцию нельзя будет откатить. Рекомендуется сделать резервную копию базы данных перед выполнением.
-
Тестирование: Протестируйте код на тестовой среде или в режиме ‘dry-run’, если возможно, чтобы убедиться, что он работает так, как вы ожидаете.
WP-CLI интеграция
Вы упомянули, что планируете использовать WP-CLI для автоматизации процесса удаления. Ниже приведен пример команды WP-CLI, которая включает в себя логику для удаления «сирот» пользователей:
class MyTools_WPCLI_Command extends WP_CLI_Command {
public function clean_users( $args, $assoc_args ) {
global $wpdb;
$delete = array();
$dryrun = false;
$users = $wpdb->get_results( "SELECT ID, user_login FROM $wpdb->users" );
if ( isset( $assoc_args['dry-run'] ) ) {
$dryrun = true;
}
WP_CLI::success( sprintf( 'Найдено %s пользователей', count( $users ) ) );
foreach ( $users as $user ) {
$user_login = $user->user_login;
$user_id = $user->ID;
if ( ! is_super_admin( $user_id ) ) {
$user_blogs = get_blogs_of_user( $user_id );
if ( empty( $user_blogs ) ) {
$delete[] = $user_id;
}
}
}
$total = count( $delete );
if ( ! $total ) {
WP_CLI::success( 'Ничего не нужно удалять!' );
exit();
}
if ( $dryrun ) {
WP_CLI::success( "[DRYRUN] Удаление $total пользователей." );
exit();
}
$progress = \WP_CLI\Utils\make_progress_bar( "Удаление $total пользователей", $total );
foreach ( $delete as $user_id ) {
require_once ABSPATH . 'wp-admin/includes/ms.php';
wpmu_delete_user( $user_id );
$progress->tick();
}
$progress->finish();
}
}
WP_CLI::add_command( 'mytools', 'MyTools_WPCLI_Command' );
Заключение
Удаление «сирот» пользователей в WordPress Multisite может значительно упростить управление пользователями в вашей системе. Используя вышеприведённые подходы, вы сможете эффективно поддерживать чистоту вашей базы данных и избегать переполнения ненужной информацией. Всегда помните о резервном копировании перед выполнением массовых операций чувствительного характера, таких как удаление данных.