Assuming you store the phone number in user_phone meta field. You can use the below code that I use in one of my plugins "Actions Pack" which provides user registration and login facility for Elementor page builder.
// Login through phone number
add_filter( 'authenticate', function ( $user, $phone, $password ){
if ( $user instanceof WP_User ) {
return $user;
}
if ( empty( $phone ) || empty( $password ) ) {
if ( is_wp_error( $user ) ) {
return $user;
}
$error = new WP_Error();
if ( empty( $phone ) ) {
// Uses 'empty_username' for back-compat with wp_signon().
$error->add( 'empty_username', __( '<strong>Error</strong>: The phone field is empty.', 'actions-pack' ) );
}
if ( empty( $password ) ) {
$error->add( 'empty_password', __( '<strong>Error</strong>: The password field is empty.', 'actions-pack' ) );
}
return $error;
}
if ( ! ap_is_phone( $phone ) ) {
return $user;
}
$user = get_users( [ 'meta_key' => 'user_phone', 'meta_value' => $phone, 'number' => 1, 'count_total' => false ] )[0];
if ( ! $user ) {
return new WP_Error(
'invalid_phone',
__( 'Unknown phone number. Check again or try your username.', 'actions-pack' )
);
}
/** 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(
/* translators: %s: Phone Number. */
__( '<strong>Error</strong>: The password you entered for the phone number %s is incorrect.', 'actions-pack' ),
'<strong>' . $phone . '</strong>'
) .
' <a href="' . wp_lostpassword_url() . '">' .
__( 'Lost your password?' ) .
'</a>'
);
}
return $user;
}, 20, 3 );
Here is a phone number validity check function. It depends on how you receive your phone number. Is it with country calling code or not.
/**
* Checks if it is a valid phone number
* @toDo Improvise validity check.
* https://stackoverflow.com/questions/14894899/what-is-the-minimum-length-of-a-valid-international-phone-number
*/
function ap_is_phone( $phone ){
$phone = filter_var($phone, FILTER_SANITIZE_NUMBER_INT);
$phone = str_replace("-", "", $phone);
if (strlen($phone) < 10 || strlen($phone) > 14) {
return false;
}
return $phone;
}