J’ai récemment eu le cas d’un client qui tentait désespérément de se connecter à l’espace d’administration de WordPress avec son adresse e-mail au lieu de son identifiant. Pour certains utilisateurs, leur mail est plus facile à retenir qu’un énième identifiant. Voyons voir comment faire sans plugin.

Depuis WordPress 4.5, cette fonctionnalité est ajoutée par défaut à la boîte de login. Ce code n’a plus grand intérêt. Cependant si vous souhaitez retirer la possibilité de s’identifier grâce à l’adresse e-mail (l’inverse donc), jetez un oeil à ce commentaire.

Plugin ou functions.php ?

C’est à vous de voir. Je ne le répèterais jamais assez, mais théoriquement le plugin doit permettre l’ajout de fonctionnalités, et le thème doit principalement gérer l’aspect. Cependant il est parfois difficile de séparer les deux.
Je vous conseillerai personnellement de créer un plugin, mais je vous fournirai uniquement la version à insérer rapidement dans votre fichier de thème functions.php, si vous souhaitez tester la chose rapidement. Il sera rapide ensuite de le transformer en plugin.

Permettre l’identification avec son adresse e-mail

WordPress prévoit un super hook pour chopper l’utilisateur pendant sont authentification sur l’espace d’admin.
Nous allons l’utiliser pour faire, dans l’ordre :

  1. vérifier si l’utilisateur rentre une adresse e-mail à la place d’un pseudo
  2. récupérer l’utilisateur WordPress d’après cette adresse e-mail
  3. contrôler si l’utilisateur existe et faire le lien avec l’identifiant
  4. authentifier l’utilisateur comme s’il avait entré son identifiant

Voici le code commenté :

// contrôle si la fonction n'existe pas déjà
if ( !function_exists('juiz_allow_email_login')) {
    add_filter('authenticate', 'juiz_allow_email_login', 20, 3);
 
    function juiz_allow_email_login( $user, $username, $password ) {
 
        // on vérifie si `username` est une adresse e-mail
        if ( is_email( $username ) ) {
            // on récupère l'utilisateur grâce à son email
            $user = get_user_by_email( $username );
            // on vérifie si l'utilisateur existe
            // et on l'associe à son identifiant
            if ( $user ) $username = $user->user_login;
        }
 
        // on retourne la tentative de connexion
        return wp_authenticate_username_password( null, $username, $password );
    }
}

Si vous souhaitez en plus éditer le texte se trouvant au dessus de du champs identifiant en « Identifiant ou e-mail », il va falloir se brancher sur le filtre gettext proposé par WordPress pour la traduction. Ce filtre passe en revue toutes les chaînes pouvant être traduite, il va donc falloir faire attention à ne pas rendre complètement intraduisible la nouvelle chaîne ajoutée, et bien analyse la chaîne d’entrée.

Pour cela nous allons nous baser sur les données suivantes :

  • Faire la modification uniquement sur la page de login
  • Détecter le terme original en anglais
  • Le modifier en tentant de se brancher sur des termes traduits par défaut
  • Rendre les nouveaux termes traductibles
if ( !function_exists('juiz_add_email_to_login')) {
    add_filter( 'gettext', 'juiz_add_email_to_login', 20, 3 );
    function juiz_add_email_to_login( $translated_text, $text, $domain ) {
 
        // si on est pas sur la page wp-login, on retourne la chaîne traduite...
        if ( 'wp-login.php' != basename( $_SERVER['SCRIPT_NAME'] ) ) {
            return $translated_text;
        }
 
        //... sinon on cherche la chaîne "Username" dans le texte original
        if ( "Username" == $text ) {
            // on ajoute "ou e-mail" à la chaîne traduite
            // on décompose pour bénéficier des traductions de WP
            $translated_text .= ' '.__( 'or', $domain); // non traduit par défaut
            $translated_text .= ' '.__( 'Email', $domain); // traduit par WP
        }
 
        // on retourne la chaîne traduite
        return $translated_text;
    }
}

Et voilà vous savez tout.
Si jamais vous souhaitez récupérer cela sous la forme d’un plugin, voici un petit bout de code pour résumer la chose :

/*
Plugin Name: Juiz User Login by email
Plugin URI: https://www.creativejuiz.fr/blog/wordpress/wordpress-autoriser-acces-admin-grace-adresse-e-mail
Description: Allows user to log-in with its email address OR its username
Version: 1.0.0
Author: CreativeJuiz
Author URI: https://geoffreycrofte.com
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html

Copyright 2014 Geoffrey Crofte - Creative Juiz

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
 
if ( ! function_exists( 'juiz_allow_email_login' ) ) {
	add_filter( 'authenticate', 'juiz_allow_email_login', 20, 3 );
	/**
	 * juiz_allow_email_login filter to the authenticate filter hook, to fetch a username based on entered email
	 * @param  obj $user 			the WP user object
	 * @param  string $username 	the data of username input
	 * @param  string $password 	the data of password input
	 * @return boolean
	 */
	function juiz_allow_email_login( $user, $username, $password ) {
 
		if ( is_email( $username ) ) {
			$user = get_user_by_email( $username );
			if ( $user ) {
				$username = $user->user_login;
			}
		}
		return wp_authenticate_username_password( null, $username, $password );
	}
}
 
if ( ! function_exists( 'juiz_add_email_to_login' ) ) {
	add_filter( 'gettext', 'juiz_add_email_to_login', 20, 3 );
	/**
	 * juiz_add_email_to_login function adds "or email" to the "username" label
	 * @param string $translated_text   translated text
	 * @param string $text              original text
	 * @param string $domain            text domain
	 */
	function juiz_add_email_to_login( $translated_text, $text, $domain ) {
 
		if ( 'wp-login.php' != basename( $_SERVER['SCRIPT_NAME'] ) ) {
			return $translated_text;
		}
 
		if ( "Username" == $text ) {
			$translated_text .= ' ' . __( 'or', $domain);
			$translated_text .= ' ' . __( 'Email', $domain);
		}
		return $translated_text;
	}
}

Je vais peut-être le proposer sur l’extend WordPress, mais je ne sais pas si c’est un besoin assez fréquent. Qu’en pensez-vous ?

Après quelques demandes de la part des lecteurs et twittos, le plugin a été publié sur l’extend WordPress.

WordPress User Log-in by email

Sources et liens utiles