WordPress登录时只能用用户名,用户名可能被忘记,但一般的用户都对自己的电子邮箱比较了解,一个简单的hack就可以允许用户用用户名或者电子邮件登陆。
代码
代码很简单,在functions.php中添加如下代码
function login_with_email_address($username) { $user = get_user_by('email',$username); if(!empty($user->user_login)) $username = $user->user_login; } add_action('wp_authenticate','login_with_email_address'); function change_username_wps_text($text){ if(in_array($GLOBALS['pagenow'], array('wp-login.php'))){ if ($text == 'Username'){ $text = 'Username / Email'; } } return $text; } add_filter( 'gettext', 'change_username_wps_text' );
代码来自wpsnipp.com,我有疑问的一个地方就是在login_with_email_address function中是否还需要return $username,这里用到的action传递的是引用。
这段代码只能针对英文版本,如果使用其他语言,需要使更改的字符串可翻译,可以这样改一下第二个函数
function change_username_wps_text($translated_text, $untranslated_text, $domain){ if(in_array($GLOBALS['pagenow'], array('wp-login.php'))){ if ($untranslated_text == 'Username'){ $translated_text = __( 'Username / Email', 'theme_text_domain' ); } } return $translated_text; } add_filter( 'gettext', 'change_username_wps_text',20,3 );
theme_text_domain需要替换成自己主题的text-domain
原理
一开始看到这段代码,确实不明白什么意思。所以找了一下wp_authenticate的位置。在wp-includes/user.php的wp_signon function中,调用方式如下所示
do_action_ref_array('wp_authenticate', array(&$credentials['user_login'], &$credentials['user_password']));
在WordPress官网找到了wp_authenticate说明,原来这个action可以用来修改用户认证过程。
This action is located inside of wp_signon. In contrast to the wp_login action, it is executed before the WordPress authentication process.
看了这些资料,大概明白上面那段代码的意思了
WordPress验证时需要使用用户名而不是电子邮箱,所以在验证之前,用get_user_by()函数获取用户名,该函数可以接受一个email地址作为参数,获取该email对应的用户名。如果没有获取到,则不改变$username,用户还可以通过用户名登陆。
现在我唯一不明白的就是这个调用方式,do action ref array与do_action的区别仅在于传递参数的形式,但我还不十分明了,得加强练习啊。
补充:
经过一番思考,发现自己小白了,忘记给action或者filter传参数时,如果参数多于1个需要制定参数的个数,一直傻乎乎的看着这段报错不知所措
Warning: Missing argument 2 for login_with_email_address()
原来忘记指定参数个数了,改成这样就不会出错了。
add_action('wp_authenticate','login_with_email_address',20,2);