Удалить аккаунт фронтенд WordPress

Добавим кнопку удалить аккаунт в личном кабинете пользователя

snimok jekrana 2025 07 05 v 19.56.57 1
add_shortcode('delete_account_button', function() {
    if (!is_user_logged_in()) {
        return '';
    }
    $user_id = get_current_user_id();
    $deletion_attempts_key = 'deletion_attempts_' . $user_id;
    $deletion_attempts = get_transient($deletion_attempts_key);
    $error_msg = '';
    if ($deletion_attempts && $deletion_attempts >= 3) {
        $error_msg = 'Превышен лимит попыток удаления аккаунта. Пожалуйста, подождите 15 минут.';
    }

    if (isset($_POST['delete_my_account']) && !$error_msg) {
        if (!isset($_POST['delete_my_account_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['delete_my_account_nonce'])), 'delete_my_account_action')) {
            set_transient($deletion_attempts_key, ($deletion_attempts ? $deletion_attempts + 1 : 1), 15 * MINUTE_IN_SECONDS);
            wp_die('Ошибка безопасности. Пожалуйста, попробуйте еще раз.', 'Ошибка безопасности', [
                'response' => 403,
                'back_link' => true,
            ]);
        }
        if (!isset($_POST['current_password'])) {
            $error_msg = 'Необходимо ввести текущий пароль для подтверждения удаления аккаунта.';
        } else {
            $user = get_user_by('id', $user_id);
            if (!$user || !wp_check_password(sanitize_text_field($_POST['current_password']), $user->data->user_pass, $user_id)) {
                set_transient($deletion_attempts_key, ($deletion_attempts ? $deletion_attempts + 1 : 1), 15 * MINUTE_IN_SECONDS);
                $error_msg = 'Неверный пароль';
            } elseif ((int)$user_id !== get_current_user_id()) {
                // Пользователь может удалять только себя
                $error_msg = 'У вас нет прав для удаления этого аккаунта';
            } else {
                error_log('User ID ' . $user_id . ' requested account deletion from IP: ' . $_SERVER['REMOTE_ADDR']);
                do_action('before_delete_user_account', $user_id);
                require_once(ABSPATH.'wp-admin/includes/user.php');
                $deleted = wp_delete_user($user_id);
                if ($deleted) {
                    wp_clear_auth_cookie();
                    wp_set_current_user(0);
                    wp_safe_redirect(home_url());
                    exit;
                } else {
                    $error_msg = 'Произошла ошибка при удалении аккаунта. Пожалуйста, обратитесь к администратору.';
                }
            }
        }
    }

    ob_start();
    ?>
    <div class="delete-account-container">
        <form method="post" onsubmit="return confirm('Вы действительно хотите удалить свой аккаунт?');">
            <?php wp_nonce_field('delete_my_account_action', 'delete_my_account_nonce'); ?>
            <input type="hidden" name="action" value="delete_account">
            <div class="form-field">
                <label for="current_password">Текущий пароль:</label>
                <input type="password" name="current_password" id="current_password" required>
            </div>
            <?php wp_referer_field(); ?>
            <button type="submit" name="delete_my_account" class="delete-account-btn">
                Удалить аккаунт
            </button>
        </form>
        <?php if (!empty($error_msg)): ?>
            <div class="errors-message"><?php echo esc_html($error_msg); ?></div>
        <?php endif; ?>
    </div>
    <?php
    return ob_get_clean();
});

add_action('template_redirect', function() {
    if (!is_user_logged_in()) {
        return;
    }
    global $post;
    if (!$post || !has_shortcode($post->post_content, 'delete_account_button')) {
        return;
    }
    $ip = $_SERVER['REMOTE_ADDR'];
    $visit_key = 'delete_page_visits_' . md5($ip);
    $visits = get_transient($visit_key);
    
    if (!$visits) {
        set_transient($visit_key, 1, HOUR_IN_SECONDS);
    } else if ($visits > 10) {
        wp_die('Доступ временно ограничен из соображений безопасности. Пожалуйста, повторите попытку позже.', 'Доступ ограничен', [
            'response' => 429,
            'back_link' => true,
        ]);
    } else {
        set_transient($visit_key, $visits + 1, HOUR_IN_SECONDS);
    }
});

Если у вас пользователи могут загружать аватары, то удалим и картинку аватара из медиатеки WordPress. Поменяйте метаполе аватара (user_avatar) на своё!

add_action('before_delete_user_account', function($user_id) {
    $avatar_id = get_user_meta($user_id, 'user_avatar', true);
    if ($avatar_id && is_numeric($avatar_id)) {
        wp_delete_attachment(absint($avatar_id), true);
        delete_user_meta($user_id, 'user_avatar');
    }
    $sessions = WP_Session_Tokens::get_instance($user_id);
    $sessions->destroy_all();
    error_log('User account deleted: User ID ' . $user_id . ', Date: ' . current_time('mysql') . ', IP: ' . $_SERVER['REMOTE_ADDR']);
});

Добавьте шорткод в личный кабинет пользователя [delete_account_button]
Немного стилизуем:

selector .delete-account-btn{background:transparent;color:#e4939f;text-decoration:underline;padding:4px 4px;font-size:13px;}
selector .form-field label{margin-bottom:10px; color:#F6F3EF;font-weight:bold;font-size:14px;}
#current_password{border-radius:10px;border:2px solid #d1d1d1;width:210px;background:#4d4d4d;}
.errors-message {color:#f5b4b5;margin-top:10px;font-size:14px;}
Picture of Автор: Александра

Автор: Александра

@avsalexandra
Занимаюсь натуральным питанием собак и кошек BARF. Wordpress для души ☺️

Crocoblock
Elementor
Gutenberg
Jetengine
Jetformbuilder
profile builder
Woocommerce
Wordpress
WYSIWYG
Лейка
#публикация постов
#видео
#доменная почта
#рассылка
#бейдж
#благотворительность
#заказ ожидает
#подарок
#подчёркивание
#vk
#автосохранение
#пожертвования
#мультивыбор
#роли
#drag and drop
#изображения товаров
#подписки
#цена
#отменить заказ
#самозанятый
#чеки
#мой налог
#alt text
#галерея товара
#возврат
#видео товара
Комментарии:

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