Je me demande simplement pourquoi Wordpress n'envoie pas de courrier de confirmation chaque fois que l'utilisateur change d'adresse électronique.
Comment savons-nous que l'adresse e-mail n'est pas fausse ou mal typée?
Alors, est-ce que quelqu'un peut me donner un extrait pour implémenter cette fonction?
Voici l'idée.
Comme SickHippie a posté cette fonctionnalité est native de WordPress mais uniquement pour une configuration multisite, voici les deux fonctions dont vous avez besoin pour que cela fonctionne sur une configuration de site unique, qui sont principalement du code un pour un du coeur /wp-admin/user-edit.php file
function custom_send_confirmation_on_profile_email() {
global $errors, $wpdb;
$current_user = wp_get_current_user();
if ( ! is_object($errors) )
$errors = new WP_Error();
if ( $current_user->ID != $_POST['user_id'] )
return false;
if ( $current_user->user_email != $_POST['email'] ) {
if ( !is_email( $_POST['email'] ) ) {
$errors->add( 'user_email', __( "<strong>ERROR</strong>: The e-mail address isn't correct." ), array( 'form-field' => 'email' ) );
return;
}
if ( email_exists( $_POST['email'] ) ) {
$errors->add( 'user_email', __( "<strong>ERROR</strong>: The e-mail address is already used." ), array( 'form-field' => 'email' ) );
delete_user_meta( $current_user->ID . '_new_email' );
return;
}
$hash = md5( $_POST['email'] . time() . mt_Rand() );
$new_user_email = array(
'hash' => $hash,
'newemail' => $_POST['email']
);
update_user_meta( $current_user->ID . '_new_email', $new_user_email );
$content = apply_filters( 'new_user_email_content', __( "Dear user,
You recently requested to have the email address on your account changed.
If this is correct, please click on the following link to change it:
###ADMIN_URL###
You can safely ignore and delete this email if you do not want to
take this action.
This email has been sent to ###EMAIL###
Regards,
All at ###SITENAME###
###SITEURL###" ), $new_user_email );
$content = str_replace( '###ADMIN_URL###', esc_url( admin_url( 'profile.php?newuseremail='.$hash ) ), $content );
$content = str_replace( '###EMAIL###', $_POST['email'], $content);
$content = str_replace( '###SITENAME###', get_site_option( 'site_name' ), $content );
$content = str_replace( '###SITEURL###', home_url(), $content );
wp_mail( $_POST['email'], sprintf( __( '[%s] New Email Address' ), get_option( 'blogname' ) ), $content );
$_POST['email'] = $current_user->user_email;
}
}
add_action( 'personal_options_update', 'custom_send_confirmation_on_profile_email' );
// Execute confirmed email change. See send_confirmation_on_profile_email().
function verify_email_change(){
global $errors, $wpdb;
$current_user = wp_get_current_user();
if (in_array($GLOBALS['pagenow'], array('profile.php')) && $current_user->ID > 0) {
if (isset( $_GET[ 'newuseremail' ] ) && $current_user->ID ) {
$new_email = get_user_meta( $current_user->ID . '_new_email' );
if ( $new_email[ 'hash' ] == $_GET[ 'newuseremail' ] ) {
$user->ID = $current_user->ID;
$user->user_email = esc_html( trim( $new_email[ 'newemail' ] ) );
if ( $wpdb->get_var( $wpdb->prepare( "SELECT user_login FROM {$wpdb->users} WHERE user_login = %s", $current_user->user_login ) ) )
$wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->users} SET user_email = %s WHERE user_login = %s", $user->user_email, $current_user->user_login ) );
wp_update_user( get_object_vars( $user ) );
delete_user_meta( $current_user->ID . '_new_email' );
wp_redirect( add_query_arg( array('updated' => 'true'), self_admin_url( 'profile.php' ) ) );
die();
}
} elseif ( !empty( $_GET['dismiss'] ) && $current_user->ID . '_new_email' == $_GET['dismiss'] ) {
delete_user_meta( $current_user->ID . '_new_email' );
wp_redirect( add_query_arg( array('updated' => 'true'), self_admin_url( 'profile.php' ) ) );
die();
}
}
}
add_action('plugins_loaded','verify_email_change');
C'est une "fonctionnalité" étrange. La fonction est actuellement disponible dans WordPress (WordPress.com l’a activée pour leur service de blog géré), mais elle est limitée à plusieurs sites. Si vous regardez dans /wp-admin/includes/ms.php
, vous trouverez la fonction qui gère ceci - ligne 239 send_confirmation_on_profile_email()
.
Vraisemblablement, vous pourriez déplacer cette fonction dans votre functions.php ou dans un plugin pour obtenir cette fonctionnalité, éventuellement avec un peu de peaufinage pour que tout fonctionne correctement. Il ne répond pas au "pourquoi", pas plus que le ticket de train à ce sujet ici .
ETA: Pour en savoir plus, il y a quelques autres fonctions que vous devrez peut-être dupliquer également: les fonctions new_user_email_admin_notice()
et update_option_new_admin_email()
sont signalées comme potentiellement nécessaires.
La réponse de Giri n'a pas fonctionné pour moi. J'ai dû modifier le mien pour que cela fonctionne (Wordpress 3.5)
function cleanup_verify_email_change()
{
global $errors, $wpdb;
$current_user = wp_get_current_user();
// don't execute this if they're trying to dismiss a pending email change
if (in_array($GLOBALS['pagenow'], array('profile.php')) && $current_user->ID > 0 & !isset($_GET["dismiss"]))
{
if (isset( $_POST[ 'email' ] ) && ($current_user->user_email != $_POST['email']) )
{
$user->ID = $current_user->ID;
$user->user_email = esc_html( trim( $_POST[ 'email' ] ) );
if ( $wpdb->get_var( $wpdb->prepare( "SELECT user_login FROM {$wpdb->users} WHERE user_login = %s", $current_user->user_login ) ) ) {
$wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->users} SET user_email = %s WHERE user_login = %s", $user->user_email, $current_user->user_login ) );
}
wp_update_user( get_object_vars( $user ) );
wp_redirect( add_query_arg( array('updated' => 'true', 'multisite_cleanup' => 'true'), self_admin_url( 'profile.php' ) ) );
die();
}
elseif ( !empty( $_GET['dismiss'] ) && $current_user->ID . '_new_email' == $_GET['dismiss'] )
{
delete_user_meta( $current_user->ID . '_new_email' );
wp_redirect( add_query_arg( array('updated' => 'true', 'multisite_cleanup' => 'true'), self_admin_url( 'profile.php' ) ) );
die();
}
}
}
add_action('plugins_loaded','cleanup_verify_email_change');
J'ai modifié le code Giri pour qu'il fonctionne sur Wordpress (version 4.8.1+)
avant:
update_user_meta( $current_user->ID . '_new_email', $new_user_email );
après:
update_user_meta( $current_user->ID, '_new_email', $new_user_email );
La virgule doit remplacer le point.
Également:
$new_email['hash'];
$new_email['newemail'];
est devenu
$new_email[0]['hash'];
$new_email[0]['newemail'];
Donc:
function custom_send_confirmation_on_profile_email() {
global $errors, $wpdb;
$current_user = wp_get_current_user();
if ( ! is_object($errors) )
$errors = new WP_Error();
if ( $current_user->ID != $_POST['user_id'] )
return false;
if ( $current_user->user_email != $_POST['email'] ) {
if ( !is_email( $_POST['email'] ) ) {
$errors->add( 'user_email', __( "<strong>ERROR</strong>: The e-mail address isn't correct." ), array( 'form-field' => 'email' ) );
return;
}
if ( email_exists( $_POST['email'] ) ) {
$errors->add( 'user_email', __( "<strong>ERROR</strong>: The e-mail address is already used." ), array( 'form-field' => 'email' ) );
delete_user_meta( $current_user->ID, '_new_email' );
return;
}
$hash = md5( $_POST['email'] . time() . mt_Rand() );
$new_user_email = array(
'hash' => $hash,
'newemail' => $_POST['email']
);
update_user_meta( $current_user->ID, '_new_email', $new_user_email );
$content = apply_filters( 'new_user_email_content', __( "Dear user,
You recently requested to have the email address on your account changed.
If this is correct, please click on the following link to change it:
###ADMIN_URL###
You can safely ignore and delete this email if you do not want to
take this action.
This email has been sent to ###EMAIL###
Regards,
All at ###SITENAME###
###SITEURL###" ), $new_user_email );
$content = str_replace( '###ADMIN_URL###', esc_url( admin_url( 'profile.php?newuseremail='.$hash ) ), $content );
$content = str_replace( '###EMAIL###', $_POST['email'], $content);
$content = str_replace( '###SITENAME###', get_site_option( 'site_name' ), $content );
$content = str_replace( '###SITEURL###', home_url(), $content );
wp_mail( $_POST['email'], sprintf( __( '[%s] New Email Address' ), get_option( 'blogname' ) ), $content );
$_POST['email'] = $current_user->user_email;
}
}
add_action( 'personal_options_update', 'custom_send_confirmation_on_profile_email' );
// Execute confirmed email change. See send_confirmation_on_profile_email().
function verify_email_change(){
global $errors, $wpdb;
$current_user = wp_get_current_user();
if (in_array($GLOBALS['pagenow'], array('profile.php')) && $current_user->ID > 0) {
if (isset( $_GET[ 'newuseremail' ] ) && $current_user->ID ) {
$new_email = get_user_meta( $current_user->ID, '_new_email' );
if ( $new_email[0]['hash'] == $_GET[ 'newuseremail' ] ) {
$user->ID = $current_user->ID;
$user->user_email = esc_html( trim( $new_email[0][ 'newemail' ] ) );
if ( $wpdb->get_var( $wpdb->prepare( "SELECT user_login FROM {$wpdb->users} WHERE user_login = %s", $current_user->user_login ) ) )
$wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->users} SET user_email = %s WHERE user_login = %s", $user->user_email, $current_user->user_login ) );
wp_update_user( get_object_vars( $user ) );
delete_user_meta( $current_user->ID, '_new_email' );
wp_redirect( add_query_arg( array('updated' => 'true'), self_admin_url( 'profile.php' ) ) );
die();
}
} elseif ( !empty( $_GET['dismiss'] ) && $current_user->ID . '_new_email' == $_GET['dismiss'] ) {
delete_user_meta( $current_user->ID, '_new_email' );
wp_redirect( add_query_arg( array('updated' => 'true'), self_admin_url( 'profile.php' ) ) );
die();
}
}
}
add_action('after_setup_theme','verify_email_change');
À votre santé.