Enviar correo de activación al usuario cuando se crea programáticamente
Me preguntaba si alguien podría ayudarme.
Básicamente, he creado un formulario de registro personalizado que cuando se valida, inserta un usuario en la tabla de usuarios.
function _new_user($data) {
// Separar Datos
$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);
}
Ahora, lo que necesito que haga es, en lugar de enviar el correo electrónico de confirmación que sé que puedo hacer con el siguiente código.
wp_new_user_notification($user_id, $data['user_pass']);
Quiero enviar un correo electrónico de activación en su lugar. He intentado algunas cosas pero no parece que pueda encontrar nada concreto. Espero que alguien haya tenido este problema antes.
Para completar el proceso de activación de usuarios necesitas seguir estos pasos:
- Después de crear un nuevo usuario, añade un campo personalizado que indique que este usuario debe activar su cuenta
- Envía un correo electrónico con el código de activación, incluyendo un enlace en este correo a una página donde el usuario será activado
- Implementa la página de activación
- Cuando un usuario intente iniciar sesión, verifica si existe ese campo personalizado. Si existe, no permitas el acceso y muestra un mensaje de error de activación.
Añadir campo personalizado y enviar correo:
function _new_user($data) {
// Separar Datos
$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( /* TU ID DE PÁGINA DE ACTIVACIÓN AQUÍ */ ));
add_user_meta( $user_id, 'has_to_be_activated', $code, true );
wp_mail( $data['user_email'], 'ASUNTO DE ACTIVACIÓN', 'FELICIDADES BLA BLA BLA. AQUÍ ESTÁ TU ENLACE DE ACTIVACIÓN: ' . $activation_link );
}
}
Verificar activación de usuario al iniciar sesión:
// sobreescribir función core
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 ) {
// TODO ¿cuál debería ser el mensaje de error? (¿O esto siquiera ocurriría?)
// Solo necesario si todos los manejadores de autenticación fallan en devolver algo.
$user = new WP_Error('authentication_failed', __('<strong>ERROR</strong>: Usuario inválido o contraseña incorrecta.'));
} elseif ( get_user_meta( $user->ID, 'has_to_be_activated', true ) != false ) {
$user = new WP_Error('activation_failed', __('<strong>ERROR</strong>: El usuario no está activado.'));
}
$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;
Página de activación:
add_action( 'template_redirect', 'wpse8170_activate_user' );
function wpse8170_activate_user() {
if ( is_page() && get_the_ID() == /* TU ID DE PÁGINA DE ACTIVACIÓN AQUÍ */ ) {
$user_id = filter_input( INPUT_GET, 'user', FILTER_VALIDATE_INT, array( 'options' => array( 'min_range' => 1 ) ) );
if ( $user_id ) {
// obtener campo meta de hash de activación del usuario
$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' );
}
}
}
}
Este es tu punto de partida, adelante y ajústalo según tus necesidades.

Buena publicación. Pero creo que te faltó un detalle. Cuando evitas que usuarios no autorizados inicien sesión, ¿cómo obtienes el user_id de get_current_user_id() en la página de activación?

Gracias por esta fantástica información. Estaba viendo si había alguna solución en el núcleo para simplemente activar el envío de un correo de activación, ya que puedes 'reenviar activación' en el panel de administración. Pensé que al insertar un usuario como pendiente, podría generarse un código de activación e insertarse en la base de datos, pero tras una inspección más detallada descubrí que 'obviamente' no hubo tal suerte :) De todos modos. Todo tiene sentido y gracias nuevamente.

@JoeBuckle Eso es extraño. No deberías tener un enlace de resend activation
en una instalación básica. ¿Podría ser que ya tengas un plugin instalado para esto? BuddyPress también incluye funcionalidad de activación de usuarios por defecto.

@JoeBuckle La página de características del plugin dice: Requerir que los usuarios sean aprobados o confirmen su dirección de correo electrónico al registrarse
http://wordpress.org/plugins/theme-my-login/.

@EugeneManuilov Buen trabajo. Tal vez también deberías usar add_role() para añadir un rol de pendiente sin capacidades. :-)

@s1lv3r ah sí tienes razón. Theme-My-Login es capaz de hacer bastante y ha estado en este sitio por un tiempo. Pero ahora estoy implementando un proceso de suscripción con paywall con un período gratuito etc... es un poco complicado así que tengo que hacerlo nativo. Al final de esto, ese plugin estará desactivado.

@s1lv3r como dije, es solo un punto de partida, todo lo demás está fuera del alcance de mi respuesta :)

estoy recibiendo un error: WP_Error Object ( [errors] => Array ( [empty_user_login] => Array ( [0] => No se puede crear un usuario con un nombre de inicio de sesión vacío. ) ) [error_data] => Array ( ) )

sin embargo, cuando imprimo el inicio de sesión del usuario y el correo del usuario, puedo ver los datos

Tengo una pregunta: quiero hacer un botón externo en el front-end "Reenviar Activación" como en wp-admin -> usuarios -> pendientes (Reenviar Activación). Pero lo necesito en una página del front-end. No voy a crear una página de activación personalizada, solo reenviar el correo con una función predeterminada de WordPress

Dos opciones para elegir:
Usar un plugin, por ejemplo User activation email o New User Approve
Programarlo tú mismo.
Algunas funciones que pueden ayudarte a empezar:
- wp_mail() para enviar el correo electrónico,
- add_user_meta() para guardar una clave de activación para el usuario,
- generar un enlace que contenga la clave y colocarlo en el correo, crear una página en WordPress que capture tu parámetro clave (por ejemplo usando add_shortcode()),
- usar get_user_meta() para verificar la clave de activación con la almacenada en la base de datos, colocar otra clave de metadatos de usuario para marcar a este usuario como activado si tiene éxito,
- agregar una función al filtro authenticate para evitar que cualquier usuario que no esté activado pueda iniciar sesión.

Puedes obtener el user_id haciendo esto durante la autenticación:
$username='correo electrónico proporcionado por el usuario en el panel de inicio de sesión.';
$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">Tu cuenta no ha sido activada aún.<br /> Para activarla revisa tu correo electrónico y haz clic en el enlace de activación.</h4>';
}
else{
//autentica el inicio de sesión de tu usuario aquí...
}
