Search code examples
wordpressauthenticationwoocommerce

Woocommerce authentication with phone number OR normal login


I have a lot of issues with our customers forgetting which email they used for login. Wordpress doesn't let you change the login unless you go into the database. I don't want to change every login to the customer's phone number. I want to write some code to do it for me when they login. So I am trying to write code that allows them to log in normally OR they can use their phone number and normal password.

I got the idea from a post here but the code just gave a fatal error on my site. Woocommerce login through phone number

Here is the code I have so far. I have tried variations. Each one will either allow the phone number login, but disallow the normal user/email. Or, it will allow the normal method but disallow the phone number. I can't seem to get it to work with both. I have been putting it in the functions.php file of the theme. But maybe I need to put it somewhere else? Maybe the code is all off.

I'm also not sure why this question is getting demoted. I have done a lot of research on finding a solution. I mentioned the previous post, I want to login with username,email id and phone number in wordpress This one doesn't work. Every solution on here has not worked. So to demote my question when there isn't an answer on here doesn't seem fair.

/**
 * Allow login with phone number, username, or email
 */
add_filter('authenticate', 'vnmAdmin_loginWithPhoneNumber', 20, 3);
function vnmAdmin_loginWithPhoneNumber($user, $username, $password) {

    // If a user is already authenticated or password is empty, skip
    if (!empty($user) || empty($password)) {
        return $user;
    }

    // Remove non-numeric characters from the username (for phone numbers)
    $normalizedPhone = preg_replace('/\D/', '', $username);

    // If the username is numeric, we treat it as a phone number
    if (is_numeric($normalizedPhone)) {

        // Get users whose billing phone number matches the normalized phone number
        $matchingUsers = get_users(array(
            'meta_key'     => 'billing_phone',
            'meta_value'   => $normalizedPhone,
            'meta_compare' => '='
        ));

        // Check if we have a matching user
        if (!empty($matchingUsers) && is_array($matchingUsers)) {

            // Use the first matching user
            $firstMatchingUser = reset($matchingUsers);

            // Set the username to the matched user's login name
            $username = $firstMatchingUser->user_login;

        } else {
            // If no matching user is found, return an error
            return new WP_Error('invalid_phone', __('No user found with this phone number.'));
        }
    }

    // Proceed with the normal WordPress authentication using the username (either modified for phone or original)
    return wp_authenticate_username_password(null, $username, $password);
}


Solution

  • Ok so I found the solution myself. The issue was the code returning a null which would break the cycle. The key is to have it check if the username that was typed in was all numbers or not. All numbers will trigger the code to pull up the phone number and match it to the user and allow login with the password. If it detects anything other than numbers it will not intercept anything and return the user/email that was already typed in there by the customer.

    // login with phone number only if the username is all numbers
    add_filter('authenticate', 'vnmAdmin_loginWithPhoneNumber', 20, 3);
    function vnmAdmin_loginWithPhoneNumber($user, $username, $password) {
    
        // Check if the input username is entirely numeric (i.e., a phone number)
        if (ctype_digit($username)) {
    
            // Get users whose billing phone number matches the entered phone number
            $matchingUsers = get_users(array(
                'meta_key'     => 'billing_phone',
                'meta_value'   => $username,
                'meta_compare' => '=' // Exact match
            ));
    
            // Check if we have a matching user
            if (!empty($matchingUsers) && is_array($matchingUsers)) {
    
                // Use the first matching user
                $firstMatchingUser = reset($matchingUsers);
    
                // Set the username to the matched user's login name
                $username = $firstMatchingUser->user_login;
            } else {
                // If no matching user is found, return an error
                return new WP_Error('invalid_phone', __('No user found with this phone number.'));
            }
    
            // Proceed with the normal authentication using the matched user's login name
            return wp_authenticate_username_password(null, $username, $password);
    
        } else {
            // If it's not a phone number, do nothing and let the default login flow continue
            return $user;
        }
    }