user_id > 0 ) { $user = get_user_by( 'id', (int) $identity->user_id ); } if ( ! $user ) { $user = self::find_legacy( $parsed['value'] ); } } elseif ( 'email' === $parsed['type'] ) { $user = get_user_by( 'email', $parsed['value'] ); } else { $user = get_user_by( 'login', $parsed['value'] ); } /** * Filters the user found for an identifier. Lets other plugins add lookups. * * @param \WP_User|false $user User or false. * @param array $parsed Parsed identifier. */ $user = apply_filters( 'aslansheed_otp_find_user', $user, $parsed ); return $user ? $user : null; } /** * Finds a user by a phone number stored in user meta by another plugin. * * Returns nothing when more than one user matches, because the owner is unclear. * * @param string $e164 Phone number in E.164 format. * @return \WP_User|false */ public static function find_legacy( $e164 ) { $keys = array_filter( array_map( 'sanitize_key', preg_split( '/[\s,]+/', (string) Options::get( 'general.legacy_phone_meta_keys' ) ) ) ); if ( array() === $keys ) { return false; } $digits = ltrim( $e164, '+' ); $national = substr( $digits, strlen( Phone_Countries::match_dial_code( $digits ) ) ); $values = array( '+' . $digits, $digits, '00' . $digits ); if ( '' !== $national ) { $values[] = $national; $values[] = '0' . $national; } $meta_query = array( 'relation' => 'OR' ); foreach ( $keys as $key ) { $meta_query[] = array( 'key' => $key, 'value' => $values, 'compare' => 'IN', ); } $users = get_users( array( 'meta_query' => $meta_query, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Rare lookup, only for phone numbers not linked yet. 'number' => 2, ) ); return 1 === count( $users ) ? $users[0] : false; } /** * Creates a user for a verified identifier. * * @param array{type: string, value: string} $parsed Parsed identifier (phone or email). * @param array $data Optional keys: name, first_name, last_name, email, username, password. * @return \WP_User|WP_Error */ public static function create( array $parsed, array $data = array() ) { $name = isset( $data['name'] ) ? sanitize_text_field( $data['name'] ) : ''; $first_name = isset( $data['first_name'] ) ? sanitize_text_field( $data['first_name'] ) : ''; $last_name = isset( $data['last_name'] ) ? sanitize_text_field( $data['last_name'] ) : ''; $password = isset( $data['password'] ) && '' !== $data['password'] ? (string) $data['password'] : wp_generate_password( 24, true, true ); // The display name is its own field. Without it, the real name is shown. $display = '' !== $name ? $name : trim( $first_name . ' ' . $last_name ); $email = 'email' === $parsed['type'] ? $parsed['value'] : ( isset( $data['email'] ) ? (string) $data['email'] : '' ); $login = isset( $data['username'] ) && '' !== $data['username'] ? (string) $data['username'] : self::unique_login( $parsed ); $args = array( 'user_login' => $login, 'user_pass' => $password, 'user_email' => $email, 'display_name' => $display, 'nickname' => '' !== $display ? $display : $login, 'first_name' => $first_name, 'last_name' => $last_name, 'role' => (string) get_option( 'default_role', 'subscriber' ), ); $user_id = wp_insert_user( $args ); if ( is_wp_error( $user_id ) ) { return $user_id; } if ( 'phone' === $parsed['type'] ) { Identity_Store::save( (int) $user_id, 'phone', $parsed['value'] ); } $user = get_user_by( 'id', (int) $user_id ); if ( ! $user ) { return new WP_Error( 'aslansheed_user_create', __( 'The account could not be created.', 'aslansheed-login' ) ); } /** * Fires after the plugin created a user. * * @param \WP_User $user New user. * @param array $parsed Parsed identifier. */ do_action( 'aslansheed_otp_user_registered', $user, $parsed ); return $user; } /** * Builds a login name that is not taken yet. * * @param array{type: string, value: string} $parsed Parsed identifier. * @return string */ public static function unique_login( array $parsed ) { if ( 'phone' === $parsed['type'] ) { $base = 'u' . preg_replace( '/\D+/', '', $parsed['value'] ); } else { $parts = explode( '@', $parsed['value'] ); $base = sanitize_user( $parts[0], true ); $base = '' === $base ? 'user' : $base; } $login = $base; while ( username_exists( $login ) ) { $login = $base . wp_rand( 100, 99999 ); } return $login; } }