I am working on login template...but I want to make login with username as well as email.I got code with for that but it is not worked,it is as follow:
function login_with_email_address($username) {
$user = get_user_by('email',$username);
if(!empty($user->user_login))
$username = $user->user_login;
return $username;
}
add_action('wp_authenticate','login_with_email_address',10,1);
I already put action in 'authenticate' for email verification,it is as follow:
function check_user_status($user, $username, $password) {
if (in_array( 'subscriber', (array) $user->roles ) ) {
if (get_user_meta($user->ID, 'confirm_mail', true) == 1) { return $user; }
else{ return new WP_Error('Account Not Active.'); }
}
else{ return $user; }
}
add_filter('authenticate','check_user_status', 30, 3);
Try this
remove_filter( 'authenticate', 'wp_authenticate_username_password', 20, 3 );
add_filter( 'authenticate', 'tcb_authenticate_username_password', 20, 3 );
function tcb_authenticate_username_password( $user, $username, $password ) {
if ( ! empty( $username ) && is_email( $username ) ) :
if ( $user = get_user_by_email( $username ) )
$username = $user->user_login;
endif;
return wp_authenticate_username_password( null, $username, $password );
}
Related
Hi I use this code to redirect users on login based on the user role.
I want to modify it to use redirect based on the user id.
How could i do this?
Thanks
function my_login_redirect( $url, $request, $user ){
if( $user && is_object( $user ) && is_a( $user, 'WP_User' ) ) {
if( $user->has_cap( 'administrator' ) ) {
$url = home_url('mypage.html');
} else {
$url = home_url('/index.php');
}
}
return $url;}add_filter('login_redirect', 'my_login_redirect', 10, 3 );
Your $user object already contains the ID.
Your code would then look like this if you want to check for user with id 79:
function my_login_redirect( $url, $request, $user ){
if ( $user && is_object( $user ) && is_a( $user, 'WP_User' ) ) {
if ( $user->ID == 79 ) {
$url = home_url( '/mypage.html' );
} else {
$url = home_url( '/index.php' );
}
}
return $url;
}
add_filter( 'login_redirect', 'my_login_redirect', 10, 3 );
Put the above in your functions.php. Tested and works.
I'm trying to disable admin login from front end of my wordPress site but my backend login also gets disable both login shows admin cannot login here
<?php
add_filter( 'authenticate', 'wp_admin_prevent_authentication', 30, 3 );
function wp_admin_prevent_authentication( $user, $username, $password ) {
if ( $user instanceof WP_User && is_page( 'my-account' ) ) {
if ( array_intersect( (array) $user->roles, [ 'administrator' ] ) ) {
return new WP_Error( 'admin-error', 'Admins cannot login from here.' );
};
};
return $user;
};
Not sure you can use is_page() inside authenticate but you can get page name using $_SERVER['REQUEST_URI']. check the below code.
function wp_admin_prevent_authentication( $user, $username, $password ) {
$url = explode( '/', rtrim( $_SERVER['REQUEST_URI'], '/') );
// If in My account dashboard page
if( $user instanceof WP_User && end( $url ) == 'my-account' ){
if ( array_intersect( (array) $user->roles, [ 'administrator' ] ) ) {
return new WP_Error( 'admin-error', 'Admins cannot login from here.' );
}
}
return $user;
}
add_filter( 'authenticate', 'wp_admin_prevent_authentication', 30, 3 );
Tested and works.
You can try with the below code, maybe it will work for you.
function wpum_admin_prevent_authentication( $user, $username, $password ) {
if ( $user instanceof WP_User && is_page( wpum_get_core_page_id( 'login' ) ) ) {
if ( array_intersect( (array) $user->roles, [ 'administrator' ] ) ) {
return new WP_Error( 'admin-error', 'Admins cannot login from here.' );
}
}
return $user;
}
add_filter( 'authenticate', 'wpum_admin_prevent_authentication', 30, 3 );
I'm trying to override the authenticate to edit the default error message.
/**
Purposed: Custom Login Error Message
Description: This function override the default error message on login form.
**/
remove_filter( 'authenticate', 'wp_authenticate_username_password' );
add_filter( 'authenticate', 'custom_authenticate_username_password', 30, 3 );
/**
* Remove Wordpress filer and write our own with changed error text.
*/
function custom_authenticate_username_password( $user, $username, $password ) {
if ( is_a($user, 'WP_User') )
return $user;
if ( empty( $username ) || empty( $password ) ) {
if ( is_wp_error( $user ) )
return $user;
$error = new WP_Error();
if ( empty( $username ) )
$error->add('empty_email', __('The username or email field is empty.'));
if ( empty( $password ) )
$error->add('empty_password', __( 'The password field is empty' ));
return $error;
}
$user = get_user_by( 'login', $username );
if ( !$user )
return new WP_Error( 'invalid_username', sprintf( __( 'Invalid username or email address.' ), wp_lostpassword_url() ) );
$user = apply_filters( 'wp_authenticate_user', $user, $password );
if ( is_wp_error( $user ) )
return $user;
if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) )
return new WP_Error( 'incorrect_password', sprintf( __( 'The password you\'ve entered is incorrect.' ),
$username, wp_lostpassword_url() ) );
return $user;
}
Unfortunately, the empty username or password error is not overriding.
The default error message for username and password are;
<strong>Error</strong> : The username field is empty.
<strong>Error</strong> : The password field is empty.
I would like to change it to;
The username or email field is empty.
The password field is empty.
However, the invalid_username and incorrect_password are working and I successfully override it.
You have an or statement and an individual statement, it's only going to return one. Try changing it around a little:
Updated
Regardless of how you would like to structure your code, I added the $error->get_error_messages(); at the end of the error. For more more information, you can have a look at this information: https://code.tutsplus.com/tutorials/wordpress-error-handling-with-wp_error-class-i--cms-21120
if ( empty( $username ) || empty( $password ) ) {
$error = new WP_Error();
if ( empty( $username ) || empty( $password ) ) {
if ( empty( $username ) ) {
$error->add( 'empty_email', __( 'The username or email field is empty.' ) );
}
if (empty( $password ) ) {
$error->add( 'empty_password', __( 'The password field is empty' ) );
}
}
return $error->get_error_messages();
} elseif ( is_wp_error( $user ) ) {
return $user->get_error_message();
}
The following code is the reason why it doesn't overriding.
if ( empty( $username ) || empty( $password ) ) {
if ( is_wp_error( $user ) )
return $user;
...
Try to remove this condition.
if (is_wp_error( $user ) )
return $user;
It should be something like this.
/**
Purposed: Custom Login Error Message
Description: This function override the default error message on login form.
**/
remove_filter( 'authenticate', 'wp_authenticate_username_password' );
add_filter( 'authenticate', 'custom_authenticate_username_password', 30, 3 );
/**
* Remove Wordpress filer and write our own with changed error text.
*/
function custom_authenticate_username_password( $user, $username, $password ) {
if (is_a($user, 'WP_User')){
return $user;
}
if (empty($username) || empty($password)) {
$error = new WP_Error();
if (empty($username )){
$error->add('empty_email', __('The username or email field is empty.'));
}
if (empty($password)){
$error->add('empty_password', __( 'The password field is empty' ));
}
return $error;
}
$user = get_user_by( 'login', $username );
if (!$user){
return new WP_Error( 'invalid_username', sprintf( __( 'Invalid username or email address.' ), wp_lostpassword_url()));
}
$user = apply_filters( 'wp_authenticate_user', $user, $password );
if (is_wp_error($user)){
return $user;
}
if (!wp_check_password( $password, $user->user_pass, $user->ID )){
return new WP_Error( 'incorrect_password', sprintf( __( 'The password you\'ve entered is incorrect.' ),
$username, wp_lostpassword_url() ) );
}
return $user;
}
Notice that I added braces to every condition to make it more clear.
You might also want to override the function wp_authenticate_email_password.
remove_filter( 'authenticate', 'wp_authenticate_email_password' );
add_filter( 'authenticate', 'custom_authenticate_email_password', 31, 3 );
function custom_authenticate_email_password( $user, $email, $password ) {
if ($user instanceof WP_User) {
return $user;
}
if (empty($email) || empty($password)) {
$error = new WP_Error();
if ( empty( $email ) ) {
// Uses 'empty_username' for back-compat with wp_signon().
$error->add( 'empty_username', __( 'The username or email field is empty.' ) );
}
if ( empty( $password ) ) {
$error->add( 'empty_password', __( 'The password field is empty.' ) );
}
return $error;
}
if (!is_email($email)) {
return $user;
}
$user = get_user_by('email', $email);
if (!$user) {
return new WP_Error('invalid_email',__( 'Invalid username or email address.' ));
}
/** This filter is documented in wp-includes/user.php */
$user = apply_filters( 'wp_authenticate_user', $user, $password );
if (is_wp_error($user)){
return $user;
}
if (!wp_check_password( $password, $user->user_pass, $user->ID)){
return new WP_Error('incorrect_password',sprintf( __( 'The password you\'ve entered is incorrect.' ),
$email, wp_lostpassword_url() ) );
}
return $user;
}
There are two functions under authenticate, wp_authenticate_username_password and wp_authenticate_email_password. Try to override both of them, maybe one of them has the error message that is not overriding, use the codes above and examine.
I have updated my code, but the problem is get_the_ID not getting any value. Can you please help. This code was adding function.php in child theme.
// Works in single post outside of the Loop
add_filter( 'authenticate', 'myplugin_auth_signon', 30, 3 );
function myplugin_auth_signon( $user, $username, $password ) {
$user = get_user_by( 'login', $username );
$roles = $user->roles['0'];
$id = get_the_ID();
echo $id;
if ( is_page( $id == 400380 ) )
{
echo "Employee Page";
$user = new WP_Error( 'denied', "Customer have no permission to login from this employee login form" );
}
if ( is_page( $id == 399649 ) )
{
echo "Customer";
$user = new WP_Error( 'denied', "Employee have no permission to login from this customer login form" );
}
return $user;
}
You can restrict other role from login use authenticate filter hook.
add_filter( 'authenticate', 'myplugin_auth_signon', 30, 3 );
function myplugin_auth_signon( $user, $username, $password ) {
$user = get_user_by( 'login', $username );
$roles = $user->roles['0'];
if($roles != 'sales' && is_page('YOUR_SALES_PAGE_ID')){
$user = new WP_Error( 'denied', "You have not permission to login from this form" );
return $user;
}
return $user;
}
Replace YOUR_SALES_PAGE_ID with your current sales login page id.
For more help see this link : Click here
User roles comes from database ? check it before, then do your logic.
I created function for loging in users on frontend using this example: https://gist.github.com/iandunn/8162246
After user logs in is_user_logged_in() function returns true only inside this function where I placed code for login part.
How do I login users globally?
This is my code:
function programmatic_login( $username ) {
if ( is_user_logged_in() ) {
wp_logout();
}
add_filter( 'authenticate', 'allow_programmatic_login', 10, 3 );
$user = wp_signon( array( 'user_login' => $username ) );
remove_filter( 'authenticate', 'allow_programmatic_login', 10, 3 );
if ( is_a( $user, 'WP_User' ) ) {
$user_id = $user->ID;
if( $user ) {
wp_set_current_user( $user_id, $user->user_login );
wp_set_auth_cookie( $user_id );
do_action( 'wp_login', $user->user_login );
}
if ( is_user_logged_in() ) {
return true;
}
}
return false;
}
function allow_programmatic_login( $user, $username, $password ) {
return get_user_by( 'login', $username );
}
function process_login(){
// this comes from login form
$username = $_POST["login_username"];
programmatic_login( $username );
// it returns true only here, on any other function it returns false
if(is_user_logged_in()){
echo "ok";
}else{
echo "not ok";
}
}
This is one example where I try to check if user is logged in, outside previous function:
add_filter('wp_nav_menu_items', 'add_login_logout_link', 10, 2);
function add_login_logout_link($items, $args) {
$loginPage = get_page_by_title("Login");
$registerPage = get_page_by_title("Register");
if(is_user_logged_in()){
$items .= "<li><a href='" . wp_logout_url('index.php') . "' title='Logout'>Logout</a></li>";
}else{
$items .= "<li><a href='". site_url() . '/' . '?page_id=' . $loginPage->ID ."'>Login</a></li><li><a a href='". site_url() . '/' . '?page_id=' . $registerPage->ID ."'>Register</a></li>";
}
return $items;
}
On codex wp_set_current_user there is an example to set the current user and log them in.
$user_id = 12345;
$user = get_user_by( 'id', $user_id );
if( $user ) {
wp_set_current_user( $user_id, $user->user_login );
wp_set_auth_cookie( $user_id );
do_action( 'wp_login', $user->user_login );
}
The simplest fix is to use wp_login_form()
see reference: http://codex.wordpress.org/Function_Reference/wp_login_form
If i understand correctly this should handle everything you want.
This will set the auth cookie and can redirect to the page you want, the login works globally