Удаление сирот пользователей в WordPress Multisite

Вопрос или проблема

Я настроил 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;

Важные замечания

  1. Осторожность при удалении: Прежде чем запустить этот код, убедитесь, что вы не удаляете нужных пользователей. Эту операцию нельзя будет откатить. Рекомендуется сделать резервную копию базы данных перед выполнением.

  2. Тестирование: Протестируйте код на тестовой среде или в режиме ‘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 может значительно упростить управление пользователями в вашей системе. Используя вышеприведённые подходы, вы сможете эффективно поддерживать чистоту вашей базы данных и избегать переполнения ненужной информацией. Всегда помните о резервном копировании перед выполнением массовых операций чувствительного характера, таких как удаление данных.

Оцените материал
Добавить комментарий

Капча загружается...