Отправка письма активации при программном создании пользователя
Интересно, может ли кто-нибудь помочь.
В принципе, я создал пользовательскую форму регистрации, которая после валидации добавляет пользователя в таблицу пользователей.
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']);
Я хочу отправить письмо активации пользователя. Я пробовал несколько вариантов, но не смог найти ничего конкретного. Надеюсь, кто-то сталкивался с этой проблемой раньше.
Для реализации процесса активации пользователя необходимо выполнить следующие шаги:
- После создания нового пользователя добавить пользовательское поле, указывающее, что аккаунт требует активации
- Отправить письмо с кодом активации, содержащее ссылку на страницу активации
- Реализовать страницу активации
- При попытке входа проверить наличие пользовательского поля. Если поле существует - не разрешать вход и показывать сообщение об ошибке активации.
Добавление пользовательского поля и отправка 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' );
}
}
}
}
Это отправная точка, которую вы можете модифицировать под свои нужды.

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

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

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

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

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

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

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

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

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

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

Два варианта на выбор:
Использовать плагин, например User activation email или New User Approve
Реализовать это самостоятельно с помощью кода.
Некоторые функции, которые помогут вам начать:
- wp_mail() для отправки письма,
- add_user_meta() для сохранения ключа активации пользователя,
- сгенерировать ссылку, содержащую ключ, и добавить её в письмо, создать страницу в WordPress, которая обработает параметр с ключом (например, используя add_shortcode()),
- использовать get_user_meta() для проверки ключа активации с сохранённым в базе данных, добавить ещё один ключ метаданных пользователя, чтобы отметить его как активированного в случае успеха,
- добавить функцию к фильтру authenticate, чтобы предотвратить вход любого пользователя, который не активирован.

Вы можете получить 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{
//здесь выполните аутентификацию пользователя...
}
