Отправка письма активации при программном создании пользователя

11 окт. 2013 г., 15:45:25
Просмотры: 31.2K
Голосов: 11

Интересно, может ли кто-нибудь помочь.

В принципе, я создал пользовательскую форму регистрации, которая после валидации добавляет пользователя в таблицу пользователей.

function _new_user($data) {

    // Разделение данных
    $default_newuser = array(
        'user_pass' =>  wp_hash_password( $data['user_pass']),
        'user_login' => $data['user_login'],
        'user_email' => $data['user_email'],
        'first_name' => $data['first_name'],
        'last_name' => $data['last_name'],
        'role' => 'pending'
    );

    wp_insert_user($default_newuser);
} 

Теперь, мне нужно, чтобы вместо отправки письма с подтверждением, которое я могу сделать с помощью следующего кода:

wp_new_user_notification($user_id, $data['user_pass']);

Я хочу отправить письмо активации пользователя. Я пробовал несколько вариантов, но не смог найти ничего конкретного. Надеюсь, кто-то сталкивался с этой проблемой раньше.

0
Все ответы на вопрос 3
14
12

Для реализации процесса активации пользователя необходимо выполнить следующие шаги:

  1. После создания нового пользователя добавить пользовательское поле, указывающее, что аккаунт требует активации
  2. Отправить письмо с кодом активации, содержащее ссылку на страницу активации
  3. Реализовать страницу активации
  4. При попытке входа проверить наличие пользовательского поля. Если поле существует - не разрешать вход и показывать сообщение об ошибке активации.

Добавление пользовательского поля и отправка email:

function _new_user($data) {

    // Разделение данных
    $default_newuser = array(
        'user_pass' =>  wp_hash_password( $data['user_pass']),
        'user_login' => $data['user_login'],
        'user_email' => $data['user_email'],
        'first_name' => $data['first_name'],
        'last_name' => $data['last_name'],
        'role' => 'pending' // Роль "ожидающий подтверждения"
    );

    $user_id = wp_insert_user($default_newuser);
    if ( $user_id && !is_wp_error( $user_id ) ) {
        $code = sha1( $user_id . time() );
        $activation_link = add_query_arg( array( 'key' => $code, 'user' => $user_id ), get_permalink( /* ID ВАШЕЙ СТРАНИЦЫ АКТИВАЦИИ */ ));
        add_user_meta( $user_id, 'has_to_be_activated', $code, true );
        wp_mail( $data['user_email'], 'ТЕМА ПИСЬМА АКТИВАЦИИ', 'ПОЗДРАВЛЯЕМ! ДЛЯ АКТИВАЦИИ ПЕРЕЙДИТЕ ПО ССЫЛКЕ: ' . $activation_link );
    }
}

Проверка активации при входе:

// Переопределение основной функции
if ( !function_exists('wp_authenticate') ) :
function wp_authenticate($username, $password) {
    $username = sanitize_user($username);
    $password = trim($password);

    $user = apply_filters('authenticate', null, $username, $password);

    if ( $user == null ) {
        // Какое сообщение об ошибке должно быть?
        $user = new WP_Error('authentication_failed', __('<strong>ОШИБКА</strong>: Неверное имя пользователя или пароль.'));
    } elseif ( get_user_meta( $user->ID, 'has_to_be_activated', true ) != false ) {
        $user = new WP_Error('activation_failed', __('<strong>ОШИБКА</strong>: Пользователь не активирован.'));
    }

    $ignore_codes = array('empty_username', 'empty_password');

    if (is_wp_error($user) && !in_array($user->get_error_code(), $ignore_codes) ) {
        do_action('wp_login_failed', $username);
    }

    return $user;
}
endif;

Страница активации:

add_action( 'template_redirect', 'wpse8170_activate_user' );
function wpse8170_activate_user() {
    if ( is_page() && get_the_ID() == /* ID ВАШЕЙ СТРАНИЦЫ АКТИВАЦИИ */ ) {
        $user_id = filter_input( INPUT_GET, 'user', FILTER_VALIDATE_INT, array( 'options' => array( 'min_range' => 1 ) ) );
        if ( $user_id ) {
            // Получаем хэш активации из метаполя пользователя
            $code = get_user_meta( $user_id, 'has_to_be_activated', true );
            if ( $code == filter_input( INPUT_GET, 'key' ) ) {
                delete_user_meta( $user_id, 'has_to_be_activated' );
            }
        }
    }
}

Это отправная точка, которую вы можете модифицировать под свои нужды.

11 окт. 2013 г. 16:42:49
Комментарии

Хороший пост. Но думаю, вы упустили один момент. Когда вы блокируете вход неавторизованных пользователей, как вы получаете user_id через get_current_user_id() на странице активации?

s1lv3r s1lv3r
11 окт. 2013 г. 17:05:29

черт... :) хорошее замечание, исправлю через минуту :)

Eugene Manuilov Eugene Manuilov
11 окт. 2013 г. 17:06:33

Спасибо за эту замечательную информацию. Я пытался найти какое-то готовое решение для повторной отправки письма с активацией, так как в админ-панели есть функция "переслать активацию". Я думал, что при добавлении пользователя со статусом "ожидает активации" код активации автоматически генерируется и сохраняется в базе данных, но после проверки обнаружил, что "очевидно" это не так :) В любом случае. Все логично, и еще раз спасибо.

Joe Buckle Joe Buckle
11 окт. 2013 г. 17:07:21

@JoeBuckle Это странно. На чистой установке у вас вообще не должно быть ссылки resend activation. Возможно, у вас уже установлен плагин для этого? Также BuddyPress из коробки предоставляет функционал активации пользователей.

s1lv3r s1lv3r
11 окт. 2013 г. 17:09:27

@s1lv3r Может ли это быть связано с Theme-My-Login?

Joe Buckle Joe Buckle
11 окт. 2013 г. 17:10:52

@s1lv3r я обновил ответ, теперь всё будет работать :)

Eugene Manuilov Eugene Manuilov
11 окт. 2013 г. 17:10:57

@JoeBuckle На странице возможностей плагина указано: Требовать подтверждения email или одобрения пользователей при регистрации http://wordpress.org/plugins/theme-my-login/.

s1lv3r s1lv3r
11 окт. 2013 г. 17:13:08

@EugeneManuilov Хорошая работа. Возможно, стоит также использовать add_role() для добавления роли "ожидающий" без каких-либо прав. :-)

s1lv3r s1lv3r
11 окт. 2013 г. 17:16:09

@s1lv3r Да, ты прав. Theme-My-Login действительно обладает широкими возможностями и давно используется на этом сайте. Но сейчас я реализую процесс платной подписки с бесплатным периодом и т.д... Это довольно сложно, поэтому приходится писать нативное решение. В итоге этот плагин будет отключен.

Joe Buckle Joe Buckle
11 окт. 2013 г. 17:17:03

@s1lv3r как я уже сказал, это лишь отправная точка, все остальное выходит за рамки моего ответа :)

Eugene Manuilov Eugene Manuilov
11 окт. 2013 г. 17:17:06

@EugeneManuilov Вы правы. Не хотел быть придирчивым. :-)

s1lv3r s1lv3r
11 окт. 2013 г. 17:17:56

я получаю ошибку: WP_Error Object ( [errors] => Array ( [empty_user_login] => Array ( [0] => Нельзя создать пользователя с пустым именем для входа. ) ) [error_data] => Array ( ) )

user2477139 user2477139
7 дек. 2016 г. 20:14:14

однако, когда я вывожу логин пользователя и его email, я вижу данные

user2477139 user2477139
7 дек. 2016 г. 20:14:47

У меня вопрос: я хочу создать внешнюю кнопку "Повторно отправить активацию" на фронтенде, как в wp-admin -> пользователи -> ожидающие (Resend Activation). Но мне нужно это на фронтенд-странице. Я не буду создавать кастомную страницу активации, просто нужно повторно отправить email с использованием стандартной функции WordPress

webstackoverload webstackoverload
28 февр. 2025 г. 12:07:37
Показать остальные 9 комментариев
0

Два варианта на выбор:

  1. Использовать плагин, например User activation email или New User Approve

  2. Реализовать это самостоятельно с помощью кода.

Некоторые функции, которые помогут вам начать:

  • wp_mail() для отправки письма,
  • add_user_meta() для сохранения ключа активации пользователя,
  • сгенерировать ссылку, содержащую ключ, и добавить её в письмо, создать страницу в WordPress, которая обработает параметр с ключом (например, используя add_shortcode()),
  • использовать get_user_meta() для проверки ключа активации с сохранённым в базе данных, добавить ещё один ключ метаданных пользователя, чтобы отметить его как активированного в случае успеха,
  • добавить функцию к фильтру authenticate, чтобы предотвратить вход любого пользователя, который не активирован.
11 окт. 2013 г. 16:47:28
0

Вы можете получить user_id следующим образом во время аутентификации:

$username='email пользователя, введенный на панели входа.';
$results = $wpdb->get_row( "SELECT ID FROM wp_users WHERE user_email='".$username."'");
   $activation_id = $results->ID;
   $activation_key =  get_user_meta( $activation_id, 'has_to_be_activated', true );
 if($activation_key != false )
 {
  echo '<h4 class="error">Ваша учетная запись еще не активирована.<br /> Для активации проверьте свою электронную почту и перейдите по ссылке активации.</h4>';
 }
else{
//здесь выполните аутентификацию пользователя...
}
16 мая 2017 г. 11:03:59