wp/wp-includes/user.php
changeset 16 a86126ab1dd4
parent 9 177826044cd9
child 18 be944660c56a
equal deleted inserted replaced
15:3d4e9c994f10 16:a86126ab1dd4
    33 function wp_signon( $credentials = array(), $secure_cookie = '' ) {
    33 function wp_signon( $credentials = array(), $secure_cookie = '' ) {
    34 	if ( empty( $credentials ) ) {
    34 	if ( empty( $credentials ) ) {
    35 		$credentials = array(); // Back-compat for plugins passing an empty string.
    35 		$credentials = array(); // Back-compat for plugins passing an empty string.
    36 
    36 
    37 		if ( ! empty( $_POST['log'] ) ) {
    37 		if ( ! empty( $_POST['log'] ) ) {
    38 			$credentials['user_login'] = $_POST['log'];
    38 			$credentials['user_login'] = wp_unslash( $_POST['log'] );
    39 		}
    39 		}
    40 		if ( ! empty( $_POST['pwd'] ) ) {
    40 		if ( ! empty( $_POST['pwd'] ) ) {
    41 			$credentials['user_password'] = $_POST['pwd'];
    41 			$credentials['user_password'] = $_POST['pwd'];
    42 		}
    42 		}
    43 		if ( ! empty( $_POST['rememberme'] ) ) {
    43 		if ( ! empty( $_POST['rememberme'] ) ) {
    85 	 *                                 that the cookie will be kept. Default false.
    85 	 *                                 that the cookie will be kept. Default false.
    86 	 * }
    86 	 * }
    87 	 */
    87 	 */
    88 	$secure_cookie = apply_filters( 'secure_signon_cookie', $secure_cookie, $credentials );
    88 	$secure_cookie = apply_filters( 'secure_signon_cookie', $secure_cookie, $credentials );
    89 
    89 
    90 	global $auth_secure_cookie; // XXX ugly hack to pass this to wp_authenticate_cookie
    90 	global $auth_secure_cookie; // XXX ugly hack to pass this to wp_authenticate_cookie().
    91 	$auth_secure_cookie = $secure_cookie;
    91 	$auth_secure_cookie = $secure_cookie;
    92 
    92 
    93 	add_filter( 'authenticate', 'wp_authenticate_cookie', 30, 3 );
    93 	add_filter( 'authenticate', 'wp_authenticate_cookie', 30, 3 );
    94 
    94 
    95 	$user = wp_authenticate( $credentials['user_login'], $credentials['user_password'] );
    95 	$user = wp_authenticate( $credentials['user_login'], $credentials['user_password'] );
   132 		}
   132 		}
   133 
   133 
   134 		$error = new WP_Error();
   134 		$error = new WP_Error();
   135 
   135 
   136 		if ( empty( $username ) ) {
   136 		if ( empty( $username ) ) {
   137 			$error->add( 'empty_username', __( '<strong>ERROR</strong>: The username field is empty.' ) );
   137 			$error->add( 'empty_username', __( '<strong>Error</strong>: The username field is empty.' ) );
   138 		}
   138 		}
   139 
   139 
   140 		if ( empty( $password ) ) {
   140 		if ( empty( $password ) ) {
   141 			$error->add( 'empty_password', __( '<strong>ERROR</strong>: The password field is empty.' ) );
   141 			$error->add( 'empty_password', __( '<strong>Error</strong>: The password field is empty.' ) );
   142 		}
   142 		}
   143 
   143 
   144 		return $error;
   144 		return $error;
   145 	}
   145 	}
   146 
   146 
   147 	$user = get_user_by( 'login', $username );
   147 	$user = get_user_by( 'login', $username );
   148 
   148 
   149 	if ( ! $user ) {
   149 	if ( ! $user ) {
   150 		return new WP_Error(
   150 		return new WP_Error(
   151 			'invalid_username',
   151 			'invalid_username',
   152 			__( '<strong>ERROR</strong>: Invalid username.' ) .
   152 			__( 'Unknown username. Check again or try your email address.' )
   153 			' <a href="' . wp_lostpassword_url() . '">' .
       
   154 			__( 'Lost your password?' ) .
       
   155 			'</a>'
       
   156 		);
   153 		);
   157 	}
   154 	}
   158 
   155 
   159 	/**
   156 	/**
   160 	 * Filters whether the given user can be authenticated with the provided $password.
   157 	 * Filters whether the given user can be authenticated with the provided $password.
   172 
   169 
   173 	if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) {
   170 	if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) {
   174 		return new WP_Error(
   171 		return new WP_Error(
   175 			'incorrect_password',
   172 			'incorrect_password',
   176 			sprintf(
   173 			sprintf(
   177 				/* translators: %s: user name */
   174 				/* translators: %s: User name. */
   178 				__( '<strong>ERROR</strong>: The password you entered for the username %s is incorrect.' ),
   175 				__( '<strong>Error</strong>: The password you entered for the username %s is incorrect.' ),
   179 				'<strong>' . $username . '</strong>'
   176 				'<strong>' . $username . '</strong>'
   180 			) .
   177 			) .
   181 			' <a href="' . wp_lostpassword_url() . '">' .
   178 			' <a href="' . wp_lostpassword_url() . '">' .
   182 			__( 'Lost your password?' ) .
   179 			__( 'Lost your password?' ) .
   183 			'</a>'
   180 			'</a>'
   209 		}
   206 		}
   210 
   207 
   211 		$error = new WP_Error();
   208 		$error = new WP_Error();
   212 
   209 
   213 		if ( empty( $email ) ) {
   210 		if ( empty( $email ) ) {
   214 			$error->add( 'empty_username', __( '<strong>ERROR</strong>: The email field is empty.' ) ); // Uses 'empty_username' for back-compat with wp_signon()
   211 			// Uses 'empty_username' for back-compat with wp_signon().
       
   212 			$error->add( 'empty_username', __( '<strong>Error</strong>: The email field is empty.' ) );
   215 		}
   213 		}
   216 
   214 
   217 		if ( empty( $password ) ) {
   215 		if ( empty( $password ) ) {
   218 			$error->add( 'empty_password', __( '<strong>ERROR</strong>: The password field is empty.' ) );
   216 			$error->add( 'empty_password', __( '<strong>Error</strong>: The password field is empty.' ) );
   219 		}
   217 		}
   220 
   218 
   221 		return $error;
   219 		return $error;
   222 	}
   220 	}
   223 
   221 
   228 	$user = get_user_by( 'email', $email );
   226 	$user = get_user_by( 'email', $email );
   229 
   227 
   230 	if ( ! $user ) {
   228 	if ( ! $user ) {
   231 		return new WP_Error(
   229 		return new WP_Error(
   232 			'invalid_email',
   230 			'invalid_email',
   233 			__( '<strong>ERROR</strong>: Invalid email address.' ) .
   231 			__( 'Unknown email address. Check again or try your username.' )
   234 			' <a href="' . wp_lostpassword_url() . '">' .
       
   235 			__( 'Lost your password?' ) .
       
   236 			'</a>'
       
   237 		);
   232 		);
   238 	}
   233 	}
   239 
   234 
   240 	/** This filter is documented in wp-includes/user.php */
   235 	/** This filter is documented in wp-includes/user.php */
   241 	$user = apply_filters( 'wp_authenticate_user', $user, $password );
   236 	$user = apply_filters( 'wp_authenticate_user', $user, $password );
   246 
   241 
   247 	if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) {
   242 	if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) {
   248 		return new WP_Error(
   243 		return new WP_Error(
   249 			'incorrect_password',
   244 			'incorrect_password',
   250 			sprintf(
   245 			sprintf(
   251 				/* translators: %s: email address */
   246 				/* translators: %s: Email address. */
   252 				__( '<strong>ERROR</strong>: The password you entered for the email address %s is incorrect.' ),
   247 				__( '<strong>Error</strong>: The password you entered for the email address %s is incorrect.' ),
   253 				'<strong>' . $email . '</strong>'
   248 				'<strong>' . $email . '</strong>'
   254 			) .
   249 			) .
   255 			' <a href="' . wp_lostpassword_url() . '">' .
   250 			' <a href="' . wp_lostpassword_url() . '">' .
   256 			__( 'Lost your password?' ) .
   251 			__( 'Lost your password?' ) .
   257 			'</a>'
   252 			'</a>'
   322 		 * @param WP_User $user    User to check against.
   317 		 * @param WP_User $user    User to check against.
   323 		 */
   318 		 */
   324 		$spammed = apply_filters( 'check_is_user_spammed', is_user_spammy( $user ), $user );
   319 		$spammed = apply_filters( 'check_is_user_spammed', is_user_spammy( $user ), $user );
   325 
   320 
   326 		if ( $spammed ) {
   321 		if ( $spammed ) {
   327 			return new WP_Error( 'spammer_account', __( '<strong>ERROR</strong>: Your account has been marked as a spammer.' ) );
   322 			return new WP_Error( 'spammer_account', __( '<strong>Error</strong>: Your account has been marked as a spammer.' ) );
   328 		}
   323 		}
   329 	}
   324 	}
   330 	return $user;
   325 	return $user;
   331 }
   326 }
   332 
   327 
   338  *
   333  *
   339  * This is a callback for the {@see 'determine_current_user'} filter, rather than API.
   334  * This is a callback for the {@see 'determine_current_user'} filter, rather than API.
   340  *
   335  *
   341  * @since 3.9.0
   336  * @since 3.9.0
   342  *
   337  *
   343  * @param int|bool $user_id The user ID (or false) as received from the
   338  * @param int|bool $user_id The user ID (or false) as received from
   344  *                       determine_current_user filter.
   339  *                          the `determine_current_user` filter.
   345  * @return int|false User ID if validated, false otherwise. If a user ID from
   340  * @return int|false User ID if validated, false otherwise. If a user ID from
   346  *                   an earlier filter callback is received, that value is returned.
   341  *                   an earlier filter callback is received, that value is returned.
   347  */
   342  */
   348 function wp_validate_logged_in_cookie( $user_id ) {
   343 function wp_validate_logged_in_cookie( $user_id ) {
   349 	if ( $user_id ) {
   344 	if ( $user_id ) {
   399  *
   394  *
   400  * @since 3.0.0
   395  * @since 3.0.0
   401  *
   396  *
   402  * @global wpdb $wpdb WordPress database abstraction object.
   397  * @global wpdb $wpdb WordPress database abstraction object.
   403  *
   398  *
   404  * @param array        $users       Array of user IDs.
   399  * @param int[]           $users       Array of user IDs.
   405  * @param string|array $post_type   Optional. Single post type or array of post types to check. Defaults to 'post'.
   400  * @param string|string[] $post_type   Optional. Single post type or array of post types to check. Defaults to 'post'.
   406  * @param bool         $public_only Optional. Only return counts for public posts.  Defaults to false.
   401  * @param bool            $public_only Optional. Only return counts for public posts.  Defaults to false.
   407  * @return array Amount of posts each user has written.
   402  * @return string[] Amount of posts each user has written, as strings, keyed by user ID.
   408  */
   403  */
   409 function count_many_users_posts( $users, $post_type = 'post', $public_only = false ) {
   404 function count_many_users_posts( $users, $post_type = 'post', $public_only = false ) {
   410 	global $wpdb;
   405 	global $wpdb;
   411 
   406 
   412 	$count = array();
   407 	$count = array();
   430 
   425 
   431 	return $count;
   426 	return $count;
   432 }
   427 }
   433 
   428 
   434 //
   429 //
   435 // User option functions
   430 // User option functions.
   436 //
   431 //
   437 
   432 
   438 /**
   433 /**
   439  * Get the current user's ID
   434  * Get the current user's ID
   440  *
   435  *
   478 
   473 
   479 	if ( empty( $user ) ) {
   474 	if ( empty( $user ) ) {
   480 		$user = get_current_user_id();
   475 		$user = get_current_user_id();
   481 	}
   476 	}
   482 
   477 
   483 	if ( ! $user = get_userdata( $user ) ) {
   478 	$user = get_userdata( $user );
       
   479 	if ( ! $user ) {
   484 		return false;
   480 		return false;
   485 	}
   481 	}
   486 
   482 
   487 	$prefix = $wpdb->get_blog_prefix();
   483 	$prefix = $wpdb->get_blog_prefix();
   488 	if ( $user->has_prop( $prefix . $option ) ) { // Blog specific
   484 	if ( $user->has_prop( $prefix . $option ) ) { // Blog-specific.
   489 		$result = $user->get( $prefix . $option );
   485 		$result = $user->get( $prefix . $option );
   490 	} elseif ( $user->has_prop( $option ) ) { // User specific and cross-blog
   486 	} elseif ( $user->has_prop( $option ) ) { // User-specific and cross-blog.
   491 		$result = $user->get( $option );
   487 		$result = $user->get( $option );
   492 	} else {
   488 	} else {
   493 		$result = false;
   489 		$result = false;
   494 	}
   490 	}
   495 
   491 
   602 function get_blogs_of_user( $user_id, $all = false ) {
   598 function get_blogs_of_user( $user_id, $all = false ) {
   603 	global $wpdb;
   599 	global $wpdb;
   604 
   600 
   605 	$user_id = (int) $user_id;
   601 	$user_id = (int) $user_id;
   606 
   602 
   607 	// Logged out users can't have sites
   603 	// Logged out users can't have sites.
   608 	if ( empty( $user_id ) ) {
   604 	if ( empty( $user_id ) ) {
   609 		return array();
   605 		return array();
   610 	}
   606 	}
   611 
   607 
   612 	/**
   608 	/**
   613 	 * Filters the list of a user's sites before it is populated.
   609 	 * Filters the list of a user's sites before it is populated.
   614 	 *
   610 	 *
   615 	 * Passing a non-null value to the filter will effectively short circuit
   611 	 * Returning a non-null value from the filter will effectively short circuit
   616 	 * get_blogs_of_user(), returning that value instead.
   612 	 * get_blogs_of_user(), returning that value instead.
   617 	 *
   613 	 *
   618 	 * @since 4.6.0
   614 	 * @since 4.6.0
   619 	 *
   615 	 *
   620 	 * @param null|array $sites   An array of site objects of which the user is a member.
   616 	 * @param null|array $sites   An array of site objects of which the user is a member.
   736 
   732 
   737 	if ( empty( $user_id ) ) {
   733 	if ( empty( $user_id ) ) {
   738 		$user_id = get_current_user_id();
   734 		$user_id = get_current_user_id();
   739 	}
   735 	}
   740 
   736 
   741 	// Technically not needed, but does save calls to get_site and get_user_meta
   737 	// Technically not needed, but does save calls to get_site() and get_user_meta()
   742 	// in the event that the function is called when a user isn't logged in
   738 	// in the event that the function is called when a user isn't logged in.
   743 	if ( empty( $user_id ) ) {
   739 	if ( empty( $user_id ) ) {
   744 		return false;
   740 		return false;
   745 	} else {
   741 	} else {
   746 		$user = get_userdata( $user_id );
   742 		$user = get_userdata( $user_id );
   747 		if ( ! $user instanceof WP_User ) {
   743 		if ( ! $user instanceof WP_User ) {
   766 	$keys = get_user_meta( $user_id );
   762 	$keys = get_user_meta( $user_id );
   767 	if ( empty( $keys ) ) {
   763 	if ( empty( $keys ) ) {
   768 		return false;
   764 		return false;
   769 	}
   765 	}
   770 
   766 
   771 	// no underscore before capabilities in $base_capabilities_key
   767 	// No underscore before capabilities in $base_capabilities_key.
   772 	$base_capabilities_key = $wpdb->base_prefix . 'capabilities';
   768 	$base_capabilities_key = $wpdb->base_prefix . 'capabilities';
   773 	$site_capabilities_key = $wpdb->base_prefix . $blog_id . '_capabilities';
   769 	$site_capabilities_key = $wpdb->base_prefix . $blog_id . '_capabilities';
   774 
   770 
   775 	if ( isset( $keys[ $base_capabilities_key ] ) && $blog_id == 1 ) {
   771 	if ( isset( $keys[ $base_capabilities_key ] ) && 1 == $blog_id ) {
   776 		return true;
   772 		return true;
   777 	}
   773 	}
   778 
   774 
   779 	if ( isset( $keys[ $site_capabilities_key ] ) ) {
   775 	if ( isset( $keys[ $site_capabilities_key ] ) ) {
   780 		return true;
   776 		return true;
   788  *
   784  *
   789  * @since 3.0.0
   785  * @since 3.0.0
   790  *
   786  *
   791  * @param int    $user_id    User ID.
   787  * @param int    $user_id    User ID.
   792  * @param string $meta_key   Metadata name.
   788  * @param string $meta_key   Metadata name.
   793  * @param mixed  $meta_value Metadata value.
   789  * @param mixed  $meta_value Metadata value. Must be serializable if non-scalar.
   794  * @param bool   $unique     Optional. Whether the same key should not be added. Default false.
   790  * @param bool   $unique     Optional. Whether the same key should not be added.
       
   791  *                           Default false.
   795  * @return int|false Meta ID on success, false on failure.
   792  * @return int|false Meta ID on success, false on failure.
   796  */
   793  */
   797 function add_user_meta( $user_id, $meta_key, $meta_value, $unique = false ) {
   794 function add_user_meta( $user_id, $meta_key, $meta_value, $unique = false ) {
   798 	return add_metadata( 'user', $user_id, $meta_key, $meta_value, $unique );
   795 	return add_metadata( 'user', $user_id, $meta_key, $meta_value, $unique );
   799 }
   796 }
   804  * You can match based on the key, or key and value. Removing based on key and
   801  * You can match based on the key, or key and value. Removing based on key and
   805  * value, will keep from removing duplicate metadata with the same key. It also
   802  * value, will keep from removing duplicate metadata with the same key. It also
   806  * allows removing all metadata matching key, if needed.
   803  * allows removing all metadata matching key, if needed.
   807  *
   804  *
   808  * @since 3.0.0
   805  * @since 3.0.0
   809  * @link https://codex.wordpress.org/Function_Reference/delete_user_meta
   806  *
       
   807  * @link https://developer.wordpress.org/reference/functions/delete_user_meta/
   810  *
   808  *
   811  * @param int    $user_id    User ID
   809  * @param int    $user_id    User ID
   812  * @param string $meta_key   Metadata name.
   810  * @param string $meta_key   Metadata name.
   813  * @param mixed  $meta_value Optional. Metadata value.
   811  * @param mixed  $meta_value Optional. Metadata value. If provided,
       
   812  *                           rows will only be removed that match the value.
       
   813  *                           Must be serializable if non-scalar. Default empty.
   814  * @return bool True on success, false on failure.
   814  * @return bool True on success, false on failure.
   815  */
   815  */
   816 function delete_user_meta( $user_id, $meta_key, $meta_value = '' ) {
   816 function delete_user_meta( $user_id, $meta_key, $meta_value = '' ) {
   817 	return delete_metadata( 'user', $user_id, $meta_key, $meta_value );
   817 	return delete_metadata( 'user', $user_id, $meta_key, $meta_value );
   818 }
   818 }
   819 
   819 
   820 /**
   820 /**
   821  * Retrieve user meta field for a user.
   821  * Retrieve user meta field for a user.
   822  *
   822  *
   823  * @since 3.0.0
   823  * @since 3.0.0
   824  * @link https://codex.wordpress.org/Function_Reference/get_user_meta
   824  *
       
   825  * @link https://developer.wordpress.org/reference/functions/get_user_meta/
   825  *
   826  *
   826  * @param int    $user_id User ID.
   827  * @param int    $user_id User ID.
   827  * @param string $key     Optional. The meta key to retrieve. By default, returns data for all keys.
   828  * @param string $key     Optional. The meta key to retrieve. By default,
   828  * @param bool   $single  Whether to return a single value.
   829  *                        returns data for all keys.
   829  * @return mixed Will be an array if $single is false. Will be value of meta data field if $single is true.
   830  * @param bool   $single  Optional. Whether to return a single value.
       
   831  *                        This parameter has no effect if $key is not specified.
       
   832  *                        Default false.
       
   833  * @return mixed An array if $single is false. The value of meta data field
       
   834  *               if $single is true. False for an invalid $user_id.
   830  */
   835  */
   831 function get_user_meta( $user_id, $key = '', $single = false ) {
   836 function get_user_meta( $user_id, $key = '', $single = false ) {
   832 	return get_metadata( 'user', $user_id, $key, $single );
   837 	return get_metadata( 'user', $user_id, $key, $single );
   833 }
   838 }
   834 
   839 
   839  * same key and user ID.
   844  * same key and user ID.
   840  *
   845  *
   841  * If the meta field for the user does not exist, it will be added.
   846  * If the meta field for the user does not exist, it will be added.
   842  *
   847  *
   843  * @since 3.0.0
   848  * @since 3.0.0
   844  * @link https://codex.wordpress.org/Function_Reference/update_user_meta
   849  *
       
   850  * @link https://developer.wordpress.org/reference/functions/update_user_meta/
   845  *
   851  *
   846  * @param int    $user_id    User ID.
   852  * @param int    $user_id    User ID.
   847  * @param string $meta_key   Metadata key.
   853  * @param string $meta_key   Metadata key.
   848  * @param mixed  $meta_value Metadata value.
   854  * @param mixed  $meta_value Metadata value. Must be serializable if non-scalar.
   849  * @param mixed  $prev_value Optional. Previous value to check before removing.
   855  * @param mixed  $prev_value Optional. Previous value to check before updating.
   850  * @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure.
   856  *                           If specified, only update existing metadata entries with
       
   857  *                           this value. Otherwise, update all entries. Default empty.
       
   858  * @return int|bool Meta ID if the key didn't exist, true on successful update,
       
   859  *                  false on failure or if the value passed to the function
       
   860  *                  is the same as the one that is already in the database.
   851  */
   861  */
   852 function update_user_meta( $user_id, $meta_key, $meta_value, $prev_value = '' ) {
   862 function update_user_meta( $user_id, $meta_key, $meta_value, $prev_value = '' ) {
   853 	return update_metadata( 'user', $user_id, $meta_key, $meta_value, $prev_value );
   863 	return update_metadata( 'user', $user_id, $meta_key, $meta_value, $prev_value );
   854 }
   864 }
   855 
   865 
   868  * @global wpdb $wpdb WordPress database abstraction object.
   878  * @global wpdb $wpdb WordPress database abstraction object.
   869  *
   879  *
   870  * @param string   $strategy Optional. The computational strategy to use when counting the users.
   880  * @param string   $strategy Optional. The computational strategy to use when counting the users.
   871  *                           Accepts either 'time' or 'memory'. Default 'time'.
   881  *                           Accepts either 'time' or 'memory'. Default 'time'.
   872  * @param int|null $site_id  Optional. The site ID to count users for. Defaults to the current site.
   882  * @param int|null $site_id  Optional. The site ID to count users for. Defaults to the current site.
   873  * @return array Includes a grand total and an array of counts indexed by role strings.
   883  * @return array {
       
   884  *     User counts.
       
   885  *
       
   886  *     @type int   $total_users Total number of users on the site.
       
   887  *     @type int[] $avail_roles Array of user counts keyed by user role.
       
   888  * }
   874  */
   889  */
   875 function count_users( $strategy = 'time', $site_id = null ) {
   890 function count_users( $strategy = 'time', $site_id = null ) {
   876 	global $wpdb;
   891 	global $wpdb;
   877 
   892 
   878 	// Initialize
   893 	// Initialize.
   879 	if ( ! $site_id ) {
   894 	if ( ! $site_id ) {
   880 		$site_id = get_current_blog_id();
   895 		$site_id = get_current_blog_id();
   881 	}
   896 	}
   882 
   897 
   883 	/**
   898 	/**
   884 	 * Filter the user count before queries are run. Return a non-null value to cause count_users()
   899 	 * Filter the user count before queries are run. Return a non-null value to cause count_users()
   885 	 * to return early.
   900 	 * to return early.
   886 	 *
   901 	 *
   887 	 * @since 5.1.0
   902 	 * @since 5.1.0
   888 	 *
   903 	 *
   889 	 * @param null|string $result   Default null.
   904 	 * @param null|string $result   The value to return instead. Default null to continue with the query.
   890 	 * @param string      $strategy Optional. The computational strategy to use when counting the users.
   905 	 * @param string      $strategy Optional. The computational strategy to use when counting the users.
   891 	 *                              Accepts either 'time' or 'memory'. Default 'time'.
   906 	 *                              Accepts either 'time' or 'memory'. Default 'time'.
   892 	 * @param int|null    $site_id  Optional. The site ID to count users for. Defaults to the current site.
   907 	 * @param int|null    $site_id  Optional. The site ID to count users for. Defaults to the current site.
   893 	 */
   908 	 */
   894 	$pre = apply_filters( 'pre_count_users', null, $strategy, $site_id );
   909 	$pre = apply_filters( 'pre_count_users', null, $strategy, $site_id );
   898 	}
   913 	}
   899 
   914 
   900 	$blog_prefix = $wpdb->get_blog_prefix( $site_id );
   915 	$blog_prefix = $wpdb->get_blog_prefix( $site_id );
   901 	$result      = array();
   916 	$result      = array();
   902 
   917 
   903 	if ( 'time' == $strategy ) {
   918 	if ( 'time' === $strategy ) {
   904 		if ( is_multisite() && $site_id != get_current_blog_id() ) {
   919 		if ( is_multisite() && get_current_blog_id() != $site_id ) {
   905 			switch_to_blog( $site_id );
   920 			switch_to_blog( $site_id );
   906 			$avail_roles = wp_roles()->get_names();
   921 			$avail_roles = wp_roles()->get_names();
   907 			restore_current_blog();
   922 			restore_current_blog();
   908 		} else {
   923 		} else {
   909 			$avail_roles = wp_roles()->get_names();
   924 			$avail_roles = wp_roles()->get_names();
   982 
   997 
   983 	return $result;
   998 	return $result;
   984 }
   999 }
   985 
  1000 
   986 //
  1001 //
   987 // Private helper functions
  1002 // Private helper functions.
   988 //
  1003 //
   989 
  1004 
   990 /**
  1005 /**
   991  * Set up global user vars.
  1006  * Set up global user vars.
   992  *
  1007  *
  1011 		$for_user_id = get_current_user_id();
  1026 		$for_user_id = get_current_user_id();
  1012 	}
  1027 	}
  1013 	$user = get_userdata( $for_user_id );
  1028 	$user = get_userdata( $for_user_id );
  1014 
  1029 
  1015 	if ( ! $user ) {
  1030 	if ( ! $user ) {
  1016 		$user_ID    = 0;
  1031 		$user_ID       = 0;
  1017 		$user_level = 0;
  1032 		$user_level    = 0;
  1018 		$userdata   = null;
  1033 		$userdata      = null;
  1019 		$user_login = $user_email = $user_url = $user_identity = '';
  1034 		$user_login    = '';
       
  1035 		$user_email    = '';
       
  1036 		$user_url      = '';
       
  1037 		$user_identity = '';
  1020 		return;
  1038 		return;
  1021 	}
  1039 	}
  1022 
  1040 
  1023 	$user_ID       = (int) $user->ID;
  1041 	$user_ID       = (int) $user->ID;
  1024 	$user_level    = (int) $user->user_level;
  1042 	$user_level    = (int) $user->user_level;
  1088  *     @type array        $role__in                An array of role names. Matched users must have at least one of
  1106  *     @type array        $role__in                An array of role names. Matched users must have at least one of
  1089  *                                                 these roles. Default empty array.
  1107  *                                                 these roles. Default empty array.
  1090  *     @type array        $role__not_in            An array of role names to exclude. Users matching one or more of
  1108  *     @type array        $role__not_in            An array of role names to exclude. Users matching one or more of
  1091  *                                                 these roles will not be included in results. Default empty array.
  1109  *                                                 these roles will not be included in results. Default empty array.
  1092  * }
  1110  * }
  1093  * @return string String of HTML content.
  1111  * @return string HTML dropdown list of users.
  1094  */
  1112  */
  1095 function wp_dropdown_users( $args = '' ) {
  1113 function wp_dropdown_users( $args = '' ) {
  1096 	$defaults = array(
  1114 	$defaults = array(
  1097 		'show_option_all'         => '',
  1115 		'show_option_all'         => '',
  1098 		'show_option_none'        => '',
  1116 		'show_option_none'        => '',
  1117 		'role__not_in'            => array(),
  1135 		'role__not_in'            => array(),
  1118 	);
  1136 	);
  1119 
  1137 
  1120 	$defaults['selected'] = is_author() ? get_query_var( 'author' ) : 0;
  1138 	$defaults['selected'] = is_author() ? get_query_var( 'author' ) : 0;
  1121 
  1139 
  1122 	$r = wp_parse_args( $args, $defaults );
  1140 	$parsed_args = wp_parse_args( $args, $defaults );
  1123 
  1141 
  1124 	$query_args = wp_array_slice_assoc( $r, array( 'blog_id', 'include', 'exclude', 'orderby', 'order', 'who', 'role', 'role__in', 'role__not_in' ) );
  1142 	$query_args = wp_array_slice_assoc( $parsed_args, array( 'blog_id', 'include', 'exclude', 'orderby', 'order', 'who', 'role', 'role__in', 'role__not_in' ) );
  1125 
  1143 
  1126 	$fields = array( 'ID', 'user_login' );
  1144 	$fields = array( 'ID', 'user_login' );
  1127 
  1145 
  1128 	$show = ! empty( $r['show'] ) ? $r['show'] : 'display_name';
  1146 	$show = ! empty( $parsed_args['show'] ) ? $parsed_args['show'] : 'display_name';
  1129 	if ( 'display_name_with_login' === $show ) {
  1147 	if ( 'display_name_with_login' === $show ) {
  1130 		$fields[] = 'display_name';
  1148 		$fields[] = 'display_name';
  1131 	} else {
  1149 	} else {
  1132 		$fields[] = $show;
  1150 		$fields[] = $show;
  1133 	}
  1151 	}
  1134 
  1152 
  1135 	$query_args['fields'] = $fields;
  1153 	$query_args['fields'] = $fields;
  1136 
  1154 
  1137 	$show_option_all   = $r['show_option_all'];
  1155 	$show_option_all   = $parsed_args['show_option_all'];
  1138 	$show_option_none  = $r['show_option_none'];
  1156 	$show_option_none  = $parsed_args['show_option_none'];
  1139 	$option_none_value = $r['option_none_value'];
  1157 	$option_none_value = $parsed_args['option_none_value'];
  1140 
  1158 
  1141 	/**
  1159 	/**
  1142 	 * Filters the query arguments for the list of users in the dropdown.
  1160 	 * Filters the query arguments for the list of users in the dropdown.
  1143 	 *
  1161 	 *
  1144 	 * @since 4.4.0
  1162 	 * @since 4.4.0
  1145 	 *
  1163 	 *
  1146 	 * @param array $query_args The query arguments for get_users().
  1164 	 * @param array $query_args  The query arguments for get_users().
  1147 	 * @param array $r          The arguments passed to wp_dropdown_users() combined with the defaults.
  1165 	 * @param array $parsed_args The arguments passed to wp_dropdown_users() combined with the defaults.
  1148 	 */
  1166 	 */
  1149 	$query_args = apply_filters( 'wp_dropdown_users_args', $query_args, $r );
  1167 	$query_args = apply_filters( 'wp_dropdown_users_args', $query_args, $parsed_args );
  1150 
  1168 
  1151 	$users = get_users( $query_args );
  1169 	$users = get_users( $query_args );
  1152 
  1170 
  1153 	$output = '';
  1171 	$output = '';
  1154 	if ( ! empty( $users ) && ( empty( $r['hide_if_only_one_author'] ) || count( $users ) > 1 ) ) {
  1172 	if ( ! empty( $users ) && ( empty( $parsed_args['hide_if_only_one_author'] ) || count( $users ) > 1 ) ) {
  1155 		$name = esc_attr( $r['name'] );
  1173 		$name = esc_attr( $parsed_args['name'] );
  1156 		if ( $r['multi'] && ! $r['id'] ) {
  1174 		if ( $parsed_args['multi'] && ! $parsed_args['id'] ) {
  1157 			$id = '';
  1175 			$id = '';
  1158 		} else {
  1176 		} else {
  1159 			$id = $r['id'] ? " id='" . esc_attr( $r['id'] ) . "'" : " id='$name'";
  1177 			$id = $parsed_args['id'] ? " id='" . esc_attr( $parsed_args['id'] ) . "'" : " id='$name'";
  1160 		}
  1178 		}
  1161 		$output = "<select name='{$name}'{$id} class='" . $r['class'] . "'>\n";
  1179 		$output = "<select name='{$name}'{$id} class='" . $parsed_args['class'] . "'>\n";
  1162 
  1180 
  1163 		if ( $show_option_all ) {
  1181 		if ( $show_option_all ) {
  1164 			$output .= "\t<option value='0'>$show_option_all</option>\n";
  1182 			$output .= "\t<option value='0'>$show_option_all</option>\n";
  1165 		}
  1183 		}
  1166 
  1184 
  1167 		if ( $show_option_none ) {
  1185 		if ( $show_option_none ) {
  1168 			$_selected = selected( $option_none_value, $r['selected'], false );
  1186 			$_selected = selected( $option_none_value, $parsed_args['selected'], false );
  1169 			$output   .= "\t<option value='" . esc_attr( $option_none_value ) . "'$_selected>$show_option_none</option>\n";
  1187 			$output   .= "\t<option value='" . esc_attr( $option_none_value ) . "'$_selected>$show_option_none</option>\n";
  1170 		}
  1188 		}
  1171 
  1189 
  1172 		if ( $r['include_selected'] && ( $r['selected'] > 0 ) ) {
  1190 		if ( $parsed_args['include_selected'] && ( $parsed_args['selected'] > 0 ) ) {
  1173 			$found_selected = false;
  1191 			$found_selected          = false;
  1174 			$r['selected']  = (int) $r['selected'];
  1192 			$parsed_args['selected'] = (int) $parsed_args['selected'];
  1175 			foreach ( (array) $users as $user ) {
  1193 			foreach ( (array) $users as $user ) {
  1176 				$user->ID = (int) $user->ID;
  1194 				$user->ID = (int) $user->ID;
  1177 				if ( $user->ID === $r['selected'] ) {
  1195 				if ( $user->ID === $parsed_args['selected'] ) {
  1178 					$found_selected = true;
  1196 					$found_selected = true;
  1179 				}
  1197 				}
  1180 			}
  1198 			}
  1181 
  1199 
  1182 			if ( ! $found_selected ) {
  1200 			if ( ! $found_selected ) {
  1183 				$users[] = get_userdata( $r['selected'] );
  1201 				$users[] = get_userdata( $parsed_args['selected'] );
  1184 			}
  1202 			}
  1185 		}
  1203 		}
  1186 
  1204 
  1187 		foreach ( (array) $users as $user ) {
  1205 		foreach ( (array) $users as $user ) {
  1188 			if ( 'display_name_with_login' === $show ) {
  1206 			if ( 'display_name_with_login' === $show ) {
  1189 				/* translators: 1: display name, 2: user_login */
  1207 				/* translators: 1: User's display name, 2: User login. */
  1190 				$display = sprintf( _x( '%1$s (%2$s)', 'user dropdown' ), $user->display_name, $user->user_login );
  1208 				$display = sprintf( _x( '%1$s (%2$s)', 'user dropdown' ), $user->display_name, $user->user_login );
  1191 			} elseif ( ! empty( $user->$show ) ) {
  1209 			} elseif ( ! empty( $user->$show ) ) {
  1192 				$display = $user->$show;
  1210 				$display = $user->$show;
  1193 			} else {
  1211 			} else {
  1194 				$display = '(' . $user->user_login . ')';
  1212 				$display = '(' . $user->user_login . ')';
  1195 			}
  1213 			}
  1196 
  1214 
  1197 			$_selected = selected( $user->ID, $r['selected'], false );
  1215 			$_selected = selected( $user->ID, $parsed_args['selected'], false );
  1198 			$output   .= "\t<option value='$user->ID'$_selected>" . esc_html( $display ) . "</option>\n";
  1216 			$output   .= "\t<option value='$user->ID'$_selected>" . esc_html( $display ) . "</option>\n";
  1199 		}
  1217 		}
  1200 
  1218 
  1201 		$output .= '</select>';
  1219 		$output .= '</select>';
  1202 	}
  1220 	}
  1208 	 *
  1226 	 *
  1209 	 * @param string $output HTML output generated by wp_dropdown_users().
  1227 	 * @param string $output HTML output generated by wp_dropdown_users().
  1210 	 */
  1228 	 */
  1211 	$html = apply_filters( 'wp_dropdown_users', $output );
  1229 	$html = apply_filters( 'wp_dropdown_users', $output );
  1212 
  1230 
  1213 	if ( $r['echo'] ) {
  1231 	if ( $parsed_args['echo'] ) {
  1214 		echo $html;
  1232 		echo $html;
  1215 	}
  1233 	}
  1216 	return $html;
  1234 	return $html;
  1217 }
  1235 }
  1218 
  1236 
  1232  *                        'attribute' and 'js'.
  1250  *                        'attribute' and 'js'.
  1233  * @return mixed Sanitized value.
  1251  * @return mixed Sanitized value.
  1234  */
  1252  */
  1235 function sanitize_user_field( $field, $value, $user_id, $context ) {
  1253 function sanitize_user_field( $field, $value, $user_id, $context ) {
  1236 	$int_fields = array( 'ID' );
  1254 	$int_fields = array( 'ID' );
  1237 	if ( in_array( $field, $int_fields ) ) {
  1255 	if ( in_array( $field, $int_fields, true ) ) {
  1238 		$value = (int) $value;
  1256 		$value = (int) $value;
  1239 	}
  1257 	}
  1240 
  1258 
  1241 	if ( 'raw' == $context ) {
  1259 	if ( 'raw' === $context ) {
  1242 		return $value;
  1260 		return $value;
  1243 	}
  1261 	}
  1244 
  1262 
  1245 	if ( ! is_string( $value ) && ! is_numeric( $value ) ) {
  1263 	if ( ! is_string( $value ) && ! is_numeric( $value ) ) {
  1246 		return $value;
  1264 		return $value;
  1247 	}
  1265 	}
  1248 
  1266 
  1249 	$prefixed = false !== strpos( $field, 'user_' );
  1267 	$prefixed = false !== strpos( $field, 'user_' );
  1250 
  1268 
  1251 	if ( 'edit' == $context ) {
  1269 	if ( 'edit' === $context ) {
  1252 		if ( $prefixed ) {
  1270 		if ( $prefixed ) {
  1253 
  1271 
  1254 			/** This filter is documented in wp-includes/post.php */
  1272 			/** This filter is documented in wp-includes/post.php */
  1255 			$value = apply_filters( "edit_{$field}", $value, $user_id );
  1273 			$value = apply_filters( "edit_{$field}", $value, $user_id );
  1256 		} else {
  1274 		} else {
  1267 			 * @param int   $user_id User ID.
  1285 			 * @param int   $user_id User ID.
  1268 			 */
  1286 			 */
  1269 			$value = apply_filters( "edit_user_{$field}", $value, $user_id );
  1287 			$value = apply_filters( "edit_user_{$field}", $value, $user_id );
  1270 		}
  1288 		}
  1271 
  1289 
  1272 		if ( 'description' == $field ) {
  1290 		if ( 'description' === $field ) {
  1273 			$value = esc_html( $value ); // textarea_escaped?
  1291 			$value = esc_html( $value ); // textarea_escaped?
  1274 		} else {
  1292 		} else {
  1275 			$value = esc_attr( $value );
  1293 			$value = esc_attr( $value );
  1276 		}
  1294 		}
  1277 	} elseif ( 'db' == $context ) {
  1295 	} elseif ( 'db' === $context ) {
  1278 		if ( $prefixed ) {
  1296 		if ( $prefixed ) {
  1279 			/** This filter is documented in wp-includes/post.php */
  1297 			/** This filter is documented in wp-includes/post.php */
  1280 			$value = apply_filters( "pre_{$field}", $value );
  1298 			$value = apply_filters( "pre_{$field}", $value );
  1281 		} else {
  1299 		} else {
  1282 
  1300 
  1314 			 */
  1332 			 */
  1315 			$value = apply_filters( "user_{$field}", $value, $user_id, $context );
  1333 			$value = apply_filters( "user_{$field}", $value, $user_id, $context );
  1316 		}
  1334 		}
  1317 	}
  1335 	}
  1318 
  1336 
  1319 	if ( 'user_url' == $field ) {
  1337 	if ( 'user_url' === $field ) {
  1320 		$value = esc_url( $value );
  1338 		$value = esc_url( $value );
  1321 	}
  1339 	}
  1322 
  1340 
  1323 	if ( 'attribute' == $context ) {
  1341 	if ( 'attribute' === $context ) {
  1324 		$value = esc_attr( $value );
  1342 		$value = esc_attr( $value );
  1325 	} elseif ( 'js' == $context ) {
  1343 	} elseif ( 'js' === $context ) {
  1326 		$value = esc_js( $value );
  1344 		$value = esc_js( $value );
  1327 	}
  1345 	}
  1328 	return $value;
  1346 	return $value;
  1329 }
  1347 }
  1330 
  1348 
  1462 /**
  1480 /**
  1463  * Insert a user into the database.
  1481  * Insert a user into the database.
  1464  *
  1482  *
  1465  * Most of the `$userdata` array fields have filters associated with the values. Exceptions are
  1483  * Most of the `$userdata` array fields have filters associated with the values. Exceptions are
  1466  * 'ID', 'rich_editing', 'syntax_highlighting', 'comment_shortcuts', 'admin_color', 'use_ssl',
  1484  * 'ID', 'rich_editing', 'syntax_highlighting', 'comment_shortcuts', 'admin_color', 'use_ssl',
  1467  * 'user_registered', and 'role'. The filters have the prefix 'pre_user_' followed by the field
  1485  * 'user_registered', 'user_activation_key', 'spam', and 'role'. The filters have the prefix
  1468  * name. An example using 'description' would have the filter called, 'pre_user_description' that
  1486  * 'pre_user_' followed by the field name. An example using 'description' would have the filter
  1469  * can be hooked into.
  1487  * called 'pre_user_description' that can be hooked into.
  1470  *
  1488  *
  1471  * @since 2.0.0
  1489  * @since 2.0.0
  1472  * @since 3.6.0 The `aim`, `jabber`, and `yim` fields were removed as default user contact
  1490  * @since 3.6.0 The `aim`, `jabber`, and `yim` fields were removed as default user contact
  1473  *              methods for new installations. See wp_get_user_contact_methods().
  1491  *              methods for new installations. See wp_get_user_contact_methods().
  1474  * @since 4.7.0 The user's locale can be passed to `$userdata`.
  1492  * @since 4.7.0 The user's locale can be passed to `$userdata`.
       
  1493  * @since 5.3.0 The `user_activation_key` field can be passed to `$userdata`.
       
  1494  * @since 5.3.0 The `spam` field can be passed to `$userdata` (Multisite only).
  1475  *
  1495  *
  1476  * @global wpdb $wpdb WordPress database abstraction object.
  1496  * @global wpdb $wpdb WordPress database abstraction object.
  1477  *
  1497  *
  1478  * @param array|object|WP_User $userdata {
  1498  * @param array|object|WP_User $userdata {
  1479  *     An array, object, or WP_User object of user data arguments.
  1499  *     An array, object, or WP_User object of user data arguments.
  1480  *
  1500  *
  1481  *     @type int         $ID                   User ID. If supplied, the user will be updated.
  1501  *     @type int    $ID                   User ID. If supplied, the user will be updated.
  1482  *     @type string      $user_pass            The plain-text user password.
  1502  *     @type string $user_pass            The plain-text user password.
  1483  *     @type string      $user_login           The user's login username.
  1503  *     @type string $user_login           The user's login username.
  1484  *     @type string      $user_nicename        The URL-friendly user name.
  1504  *     @type string $user_nicename        The URL-friendly user name.
  1485  *     @type string      $user_url             The user URL.
  1505  *     @type string $user_url             The user URL.
  1486  *     @type string      $user_email           The user email address.
  1506  *     @type string $user_email           The user email address.
  1487  *     @type string      $display_name         The user's display name.
  1507  *     @type string $display_name         The user's display name.
  1488  *                                             Default is the user's username.
  1508  *                                        Default is the user's username.
  1489  *     @type string      $nickname             The user's nickname.
  1509  *     @type string $nickname             The user's nickname.
  1490  *                                             Default is the user's username.
  1510  *                                        Default is the user's username.
  1491  *     @type string      $first_name           The user's first name. For new users, will be used
  1511  *     @type string $first_name           The user's first name. For new users, will be used
  1492  *                                             to build the first part of the user's display name
  1512  *                                        to build the first part of the user's display name
  1493  *                                             if `$display_name` is not specified.
  1513  *                                        if `$display_name` is not specified.
  1494  *     @type string      $last_name            The user's last name. For new users, will be used
  1514  *     @type string $last_name            The user's last name. For new users, will be used
  1495  *                                             to build the second part of the user's display name
  1515  *                                        to build the second part of the user's display name
  1496  *                                             if `$display_name` is not specified.
  1516  *                                        if `$display_name` is not specified.
  1497  *     @type string      $description          The user's biographical description.
  1517  *     @type string $description          The user's biographical description.
  1498  *     @type string|bool $rich_editing         Whether to enable the rich-editor for the user.
  1518  *     @type string $rich_editing         Whether to enable the rich-editor for the user.
  1499  *                                             False if not empty.
  1519  *                                        Accepts 'true' or 'false' as a string literal,
  1500  *     @type string|bool $syntax_highlighting  Whether to enable the rich code editor for the user.
  1520  *                                        not boolean. Default 'true'.
  1501  *                                             False if not empty.
  1521  *     @type string $syntax_highlighting  Whether to enable the rich code editor for the user.
  1502  *     @type string|bool $comment_shortcuts    Whether to enable comment moderation keyboard
  1522  *                                        Accepts 'true' or 'false' as a string literal,
  1503  *                                             shortcuts for the user. Default false.
  1523  *                                        not boolean. Default 'true'.
  1504  *     @type string      $admin_color          Admin color scheme for the user. Default 'fresh'.
  1524  *     @type string $comment_shortcuts    Whether to enable comment moderation keyboard
  1505  *     @type bool        $use_ssl              Whether the user should always access the admin over
  1525  *                                        shortcuts for the user. Accepts 'true' or 'false'
  1506  *                                             https. Default false.
  1526  *                                        as a string literal, not boolean. Default 'false'.
  1507  *     @type string      $user_registered      Date the user registered. Format is 'Y-m-d H:i:s'.
  1527  *     @type string $admin_color          Admin color scheme for the user. Default 'fresh'.
  1508  *     @type string|bool $show_admin_bar_front Whether to display the Admin Bar for the user on the
  1528  *     @type bool   $use_ssl              Whether the user should always access the admin over
  1509  *                                             site's front end. Default true.
  1529  *                                        https. Default false.
  1510  *     @type string      $role                 User's role.
  1530  *     @type string $user_registered      Date the user registered. Format is 'Y-m-d H:i:s'.
  1511  *     @type string      $locale               User's locale. Default empty.
  1531  *     @type string $user_activation_key  Password reset key. Default empty.
       
  1532  *     @type bool   $spam                 Multisite only. Whether the user is marked as spam.
       
  1533  *                                        Default false.
       
  1534  *     @type string $show_admin_bar_front Whether to display the Admin Bar for the user
       
  1535  *                                        on the site's front end. Accepts 'true' or 'false'
       
  1536  *                                        as a string literal, not boolean. Default 'true'.
       
  1537  *     @type string $role                 User's role.
       
  1538  *     @type string $locale               User's locale. Default empty.
  1512  * }
  1539  * }
  1513  * @return int|WP_Error The newly created user's ID or a WP_Error object if the user could not
  1540  * @return int|WP_Error The newly created user's ID or a WP_Error object if the user could not
  1514  *                      be created.
  1541  *                      be created.
  1515  */
  1542  */
  1516 function wp_insert_user( $userdata ) {
  1543 function wp_insert_user( $userdata ) {
  1530 
  1557 
  1531 		if ( ! $old_user_data ) {
  1558 		if ( ! $old_user_data ) {
  1532 			return new WP_Error( 'invalid_user_id', __( 'Invalid user ID.' ) );
  1559 			return new WP_Error( 'invalid_user_id', __( 'Invalid user ID.' ) );
  1533 		}
  1560 		}
  1534 
  1561 
  1535 		// hashed in wp_update_user(), plaintext if called directly
  1562 		// Hashed in wp_update_user(), plaintext if called directly.
  1536 		$user_pass = ! empty( $userdata['user_pass'] ) ? $userdata['user_pass'] : $old_user_data->user_pass;
  1563 		$user_pass = ! empty( $userdata['user_pass'] ) ? $userdata['user_pass'] : $old_user_data->user_pass;
  1537 	} else {
  1564 	} else {
  1538 		$update = false;
  1565 		$update = false;
  1539 		// Hash the password
  1566 		// Hash the password.
  1540 		$user_pass = wp_hash_password( $userdata['user_pass'] );
  1567 		$user_pass = wp_hash_password( $userdata['user_pass'] );
  1541 	}
  1568 	}
  1542 
  1569 
  1543 	$sanitized_user_login = sanitize_user( $userdata['user_login'], true );
  1570 	$sanitized_user_login = sanitize_user( $userdata['user_login'], true );
  1544 
  1571 
  1551 	 *
  1578 	 *
  1552 	 * @param string $sanitized_user_login Username after it has been sanitized.
  1579 	 * @param string $sanitized_user_login Username after it has been sanitized.
  1553 	 */
  1580 	 */
  1554 	$pre_user_login = apply_filters( 'pre_user_login', $sanitized_user_login );
  1581 	$pre_user_login = apply_filters( 'pre_user_login', $sanitized_user_login );
  1555 
  1582 
  1556 	//Remove any non-printable chars from the login string to see if we have ended up with an empty username
  1583 	// Remove any non-printable chars from the login string to see if we have ended up with an empty username.
  1557 	$user_login = trim( $pre_user_login );
  1584 	$user_login = trim( $pre_user_login );
  1558 
  1585 
  1559 	// user_login must be between 0 and 60 characters.
  1586 	// user_login must be between 0 and 60 characters.
  1560 	if ( empty( $user_login ) ) {
  1587 	if ( empty( $user_login ) ) {
  1561 		return new WP_Error( 'empty_user_login', __( 'Cannot create a user with an empty login name.' ) );
  1588 		return new WP_Error( 'empty_user_login', __( 'Cannot create a user with an empty login name.' ) );
  1566 	if ( ! $update && username_exists( $user_login ) ) {
  1593 	if ( ! $update && username_exists( $user_login ) ) {
  1567 		return new WP_Error( 'existing_user_login', __( 'Sorry, that username already exists!' ) );
  1594 		return new WP_Error( 'existing_user_login', __( 'Sorry, that username already exists!' ) );
  1568 	}
  1595 	}
  1569 
  1596 
  1570 	/**
  1597 	/**
  1571 	 * Filters the list of blacklisted usernames.
  1598 	 * Filters the list of disallowed usernames.
  1572 	 *
  1599 	 *
  1573 	 * @since 4.4.0
  1600 	 * @since 4.4.0
  1574 	 *
  1601 	 *
  1575 	 * @param array $usernames Array of blacklisted usernames.
  1602 	 * @param array $usernames Array of disallowed usernames.
  1576 	 */
  1603 	 */
  1577 	$illegal_logins = (array) apply_filters( 'illegal_user_logins', array() );
  1604 	$illegal_logins = (array) apply_filters( 'illegal_user_logins', array() );
  1578 
  1605 
  1579 	if ( in_array( strtolower( $user_login ), array_map( 'strtolower', $illegal_logins ) ) ) {
  1606 	if ( in_array( strtolower( $user_login ), array_map( 'strtolower', $illegal_logins ), true ) ) {
  1580 		return new WP_Error( 'invalid_username', __( 'Sorry, that username is not allowed.' ) );
  1607 		return new WP_Error( 'invalid_username', __( 'Sorry, that username is not allowed.' ) );
  1581 	}
  1608 	}
  1582 
  1609 
  1583 	/*
  1610 	/*
  1584 	 * If a nicename is provided, remove unsafe user characters before using it.
  1611 	 * If a nicename is provided, remove unsafe user characters before using it.
  1593 		$user_nicename = mb_substr( $user_login, 0, 50 );
  1620 		$user_nicename = mb_substr( $user_login, 0, 50 );
  1594 	}
  1621 	}
  1595 
  1622 
  1596 	$user_nicename = sanitize_title( $user_nicename );
  1623 	$user_nicename = sanitize_title( $user_nicename );
  1597 
  1624 
  1598 	// Store values to save in user meta.
       
  1599 	$meta = array();
       
  1600 
       
  1601 	/**
  1625 	/**
  1602 	 * Filters a user's nicename before the user is created or updated.
  1626 	 * Filters a user's nicename before the user is created or updated.
  1603 	 *
  1627 	 *
  1604 	 * @since 2.0.3
  1628 	 * @since 2.0.3
  1605 	 *
  1629 	 *
  1606 	 * @param string $user_nicename The user's nicename.
  1630 	 * @param string $user_nicename The user's nicename.
  1607 	 */
  1631 	 */
  1608 	$user_nicename = apply_filters( 'pre_user_nicename', $user_nicename );
  1632 	$user_nicename = apply_filters( 'pre_user_nicename', $user_nicename );
  1609 
       
  1610 	$raw_user_url = empty( $userdata['user_url'] ) ? '' : $userdata['user_url'];
       
  1611 
       
  1612 	/**
       
  1613 	 * Filters a user's URL before the user is created or updated.
       
  1614 	 *
       
  1615 	 * @since 2.0.3
       
  1616 	 *
       
  1617 	 * @param string $raw_user_url The user's URL.
       
  1618 	 */
       
  1619 	$user_url = apply_filters( 'pre_user_url', $raw_user_url );
       
  1620 
       
  1621 	$raw_user_email = empty( $userdata['user_email'] ) ? '' : $userdata['user_email'];
       
  1622 
       
  1623 	/**
       
  1624 	 * Filters a user's email before the user is created or updated.
       
  1625 	 *
       
  1626 	 * @since 2.0.3
       
  1627 	 *
       
  1628 	 * @param string $raw_user_email The user's email.
       
  1629 	 */
       
  1630 	$user_email = apply_filters( 'pre_user_email', $raw_user_email );
       
  1631 
       
  1632 	/*
       
  1633 	 * If there is no update, just check for `email_exists`. If there is an update,
       
  1634 	 * check if current email and new email are the same, or not, and check `email_exists`
       
  1635 	 * accordingly.
       
  1636 	 */
       
  1637 	if ( ( ! $update || ( ! empty( $old_user_data ) && 0 !== strcasecmp( $user_email, $old_user_data->user_email ) ) )
       
  1638 		&& ! defined( 'WP_IMPORTING' )
       
  1639 		&& email_exists( $user_email )
       
  1640 	) {
       
  1641 		return new WP_Error( 'existing_user_email', __( 'Sorry, that email address is already used!' ) );
       
  1642 	}
       
  1643 	$nickname = empty( $userdata['nickname'] ) ? $user_login : $userdata['nickname'];
       
  1644 
       
  1645 	/**
       
  1646 	 * Filters a user's nickname before the user is created or updated.
       
  1647 	 *
       
  1648 	 * @since 2.0.3
       
  1649 	 *
       
  1650 	 * @param string $nickname The user's nickname.
       
  1651 	 */
       
  1652 	$meta['nickname'] = apply_filters( 'pre_user_nickname', $nickname );
       
  1653 
       
  1654 	$first_name = empty( $userdata['first_name'] ) ? '' : $userdata['first_name'];
       
  1655 
       
  1656 	/**
       
  1657 	 * Filters a user's first name before the user is created or updated.
       
  1658 	 *
       
  1659 	 * @since 2.0.3
       
  1660 	 *
       
  1661 	 * @param string $first_name The user's first name.
       
  1662 	 */
       
  1663 	$meta['first_name'] = apply_filters( 'pre_user_first_name', $first_name );
       
  1664 
       
  1665 	$last_name = empty( $userdata['last_name'] ) ? '' : $userdata['last_name'];
       
  1666 
       
  1667 	/**
       
  1668 	 * Filters a user's last name before the user is created or updated.
       
  1669 	 *
       
  1670 	 * @since 2.0.3
       
  1671 	 *
       
  1672 	 * @param string $last_name The user's last name.
       
  1673 	 */
       
  1674 	$meta['last_name'] = apply_filters( 'pre_user_last_name', $last_name );
       
  1675 
       
  1676 	if ( empty( $userdata['display_name'] ) ) {
       
  1677 		if ( $update ) {
       
  1678 			$display_name = $user_login;
       
  1679 		} elseif ( $meta['first_name'] && $meta['last_name'] ) {
       
  1680 			/* translators: 1: first name, 2: last name */
       
  1681 			$display_name = sprintf( _x( '%1$s %2$s', 'Display name based on first name and last name' ), $meta['first_name'], $meta['last_name'] );
       
  1682 		} elseif ( $meta['first_name'] ) {
       
  1683 			$display_name = $meta['first_name'];
       
  1684 		} elseif ( $meta['last_name'] ) {
       
  1685 			$display_name = $meta['last_name'];
       
  1686 		} else {
       
  1687 			$display_name = $user_login;
       
  1688 		}
       
  1689 	} else {
       
  1690 		$display_name = $userdata['display_name'];
       
  1691 	}
       
  1692 
       
  1693 	/**
       
  1694 	 * Filters a user's display name before the user is created or updated.
       
  1695 	 *
       
  1696 	 * @since 2.0.3
       
  1697 	 *
       
  1698 	 * @param string $display_name The user's display name.
       
  1699 	 */
       
  1700 	$display_name = apply_filters( 'pre_user_display_name', $display_name );
       
  1701 
       
  1702 	$description = empty( $userdata['description'] ) ? '' : $userdata['description'];
       
  1703 
       
  1704 	/**
       
  1705 	 * Filters a user's description before the user is created or updated.
       
  1706 	 *
       
  1707 	 * @since 2.0.3
       
  1708 	 *
       
  1709 	 * @param string $description The user's description.
       
  1710 	 */
       
  1711 	$meta['description'] = apply_filters( 'pre_user_description', $description );
       
  1712 
       
  1713 	$meta['rich_editing'] = empty( $userdata['rich_editing'] ) ? 'true' : $userdata['rich_editing'];
       
  1714 
       
  1715 	$meta['syntax_highlighting'] = empty( $userdata['syntax_highlighting'] ) ? 'true' : $userdata['syntax_highlighting'];
       
  1716 
       
  1717 	$meta['comment_shortcuts'] = empty( $userdata['comment_shortcuts'] ) || 'false' === $userdata['comment_shortcuts'] ? 'false' : 'true';
       
  1718 
       
  1719 	$admin_color         = empty( $userdata['admin_color'] ) ? 'fresh' : $userdata['admin_color'];
       
  1720 	$meta['admin_color'] = preg_replace( '|[^a-z0-9 _.\-@]|i', '', $admin_color );
       
  1721 
       
  1722 	$meta['use_ssl'] = empty( $userdata['use_ssl'] ) ? 0 : $userdata['use_ssl'];
       
  1723 
       
  1724 	$user_registered = empty( $userdata['user_registered'] ) ? gmdate( 'Y-m-d H:i:s' ) : $userdata['user_registered'];
       
  1725 
       
  1726 	$meta['show_admin_bar_front'] = empty( $userdata['show_admin_bar_front'] ) ? 'true' : $userdata['show_admin_bar_front'];
       
  1727 
       
  1728 	$meta['locale'] = isset( $userdata['locale'] ) ? $userdata['locale'] : '';
       
  1729 
  1633 
  1730 	$user_nicename_check = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->users WHERE user_nicename = %s AND user_login != %s LIMIT 1", $user_nicename, $user_login ) );
  1634 	$user_nicename_check = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->users WHERE user_nicename = %s AND user_login != %s LIMIT 1", $user_nicename, $user_login ) );
  1731 
  1635 
  1732 	if ( $user_nicename_check ) {
  1636 	if ( $user_nicename_check ) {
  1733 		$suffix = 2;
  1637 		$suffix = 2;
  1739 			$suffix++;
  1643 			$suffix++;
  1740 		}
  1644 		}
  1741 		$user_nicename = $alt_user_nicename;
  1645 		$user_nicename = $alt_user_nicename;
  1742 	}
  1646 	}
  1743 
  1647 
  1744 	$compacted = compact( 'user_pass', 'user_email', 'user_url', 'user_nicename', 'display_name', 'user_registered' );
  1648 	$raw_user_email = empty( $userdata['user_email'] ) ? '' : $userdata['user_email'];
       
  1649 
       
  1650 	/**
       
  1651 	 * Filters a user's email before the user is created or updated.
       
  1652 	 *
       
  1653 	 * @since 2.0.3
       
  1654 	 *
       
  1655 	 * @param string $raw_user_email The user's email.
       
  1656 	 */
       
  1657 	$user_email = apply_filters( 'pre_user_email', $raw_user_email );
       
  1658 
       
  1659 	/*
       
  1660 	 * If there is no update, just check for `email_exists`. If there is an update,
       
  1661 	 * check if current email and new email are the same, or not, and check `email_exists`
       
  1662 	 * accordingly.
       
  1663 	 */
       
  1664 	if ( ( ! $update || ( ! empty( $old_user_data ) && 0 !== strcasecmp( $user_email, $old_user_data->user_email ) ) )
       
  1665 		&& ! defined( 'WP_IMPORTING' )
       
  1666 		&& email_exists( $user_email )
       
  1667 	) {
       
  1668 		return new WP_Error( 'existing_user_email', __( 'Sorry, that email address is already used!' ) );
       
  1669 	}
       
  1670 
       
  1671 	$raw_user_url = empty( $userdata['user_url'] ) ? '' : $userdata['user_url'];
       
  1672 
       
  1673 	/**
       
  1674 	 * Filters a user's URL before the user is created or updated.
       
  1675 	 *
       
  1676 	 * @since 2.0.3
       
  1677 	 *
       
  1678 	 * @param string $raw_user_url The user's URL.
       
  1679 	 */
       
  1680 	$user_url = apply_filters( 'pre_user_url', $raw_user_url );
       
  1681 
       
  1682 	$user_registered = empty( $userdata['user_registered'] ) ? gmdate( 'Y-m-d H:i:s' ) : $userdata['user_registered'];
       
  1683 
       
  1684 	$user_activation_key = empty( $userdata['user_activation_key'] ) ? '' : $userdata['user_activation_key'];
       
  1685 
       
  1686 	if ( ! empty( $userdata['spam'] ) && ! is_multisite() ) {
       
  1687 		return new WP_Error( 'no_spam', __( 'Sorry, marking a user as spam is only supported on Multisite.' ) );
       
  1688 	}
       
  1689 
       
  1690 	$spam = empty( $userdata['spam'] ) ? 0 : (bool) $userdata['spam'];
       
  1691 
       
  1692 	// Store values to save in user meta.
       
  1693 	$meta = array();
       
  1694 
       
  1695 	$nickname = empty( $userdata['nickname'] ) ? $user_login : $userdata['nickname'];
       
  1696 
       
  1697 	/**
       
  1698 	 * Filters a user's nickname before the user is created or updated.
       
  1699 	 *
       
  1700 	 * @since 2.0.3
       
  1701 	 *
       
  1702 	 * @param string $nickname The user's nickname.
       
  1703 	 */
       
  1704 	$meta['nickname'] = apply_filters( 'pre_user_nickname', $nickname );
       
  1705 
       
  1706 	$first_name = empty( $userdata['first_name'] ) ? '' : $userdata['first_name'];
       
  1707 
       
  1708 	/**
       
  1709 	 * Filters a user's first name before the user is created or updated.
       
  1710 	 *
       
  1711 	 * @since 2.0.3
       
  1712 	 *
       
  1713 	 * @param string $first_name The user's first name.
       
  1714 	 */
       
  1715 	$meta['first_name'] = apply_filters( 'pre_user_first_name', $first_name );
       
  1716 
       
  1717 	$last_name = empty( $userdata['last_name'] ) ? '' : $userdata['last_name'];
       
  1718 
       
  1719 	/**
       
  1720 	 * Filters a user's last name before the user is created or updated.
       
  1721 	 *
       
  1722 	 * @since 2.0.3
       
  1723 	 *
       
  1724 	 * @param string $last_name The user's last name.
       
  1725 	 */
       
  1726 	$meta['last_name'] = apply_filters( 'pre_user_last_name', $last_name );
       
  1727 
       
  1728 	if ( empty( $userdata['display_name'] ) ) {
       
  1729 		if ( $update ) {
       
  1730 			$display_name = $user_login;
       
  1731 		} elseif ( $meta['first_name'] && $meta['last_name'] ) {
       
  1732 			/* translators: 1: User's first name, 2: Last name. */
       
  1733 			$display_name = sprintf( _x( '%1$s %2$s', 'Display name based on first name and last name' ), $meta['first_name'], $meta['last_name'] );
       
  1734 		} elseif ( $meta['first_name'] ) {
       
  1735 			$display_name = $meta['first_name'];
       
  1736 		} elseif ( $meta['last_name'] ) {
       
  1737 			$display_name = $meta['last_name'];
       
  1738 		} else {
       
  1739 			$display_name = $user_login;
       
  1740 		}
       
  1741 	} else {
       
  1742 		$display_name = $userdata['display_name'];
       
  1743 	}
       
  1744 
       
  1745 	/**
       
  1746 	 * Filters a user's display name before the user is created or updated.
       
  1747 	 *
       
  1748 	 * @since 2.0.3
       
  1749 	 *
       
  1750 	 * @param string $display_name The user's display name.
       
  1751 	 */
       
  1752 	$display_name = apply_filters( 'pre_user_display_name', $display_name );
       
  1753 
       
  1754 	$description = empty( $userdata['description'] ) ? '' : $userdata['description'];
       
  1755 
       
  1756 	/**
       
  1757 	 * Filters a user's description before the user is created or updated.
       
  1758 	 *
       
  1759 	 * @since 2.0.3
       
  1760 	 *
       
  1761 	 * @param string $description The user's description.
       
  1762 	 */
       
  1763 	$meta['description'] = apply_filters( 'pre_user_description', $description );
       
  1764 
       
  1765 	$meta['rich_editing'] = empty( $userdata['rich_editing'] ) ? 'true' : $userdata['rich_editing'];
       
  1766 
       
  1767 	$meta['syntax_highlighting'] = empty( $userdata['syntax_highlighting'] ) ? 'true' : $userdata['syntax_highlighting'];
       
  1768 
       
  1769 	$meta['comment_shortcuts'] = empty( $userdata['comment_shortcuts'] ) || 'false' === $userdata['comment_shortcuts'] ? 'false' : 'true';
       
  1770 
       
  1771 	$admin_color         = empty( $userdata['admin_color'] ) ? 'fresh' : $userdata['admin_color'];
       
  1772 	$meta['admin_color'] = preg_replace( '|[^a-z0-9 _.\-@]|i', '', $admin_color );
       
  1773 
       
  1774 	$meta['use_ssl'] = empty( $userdata['use_ssl'] ) ? 0 : (bool) $userdata['use_ssl'];
       
  1775 
       
  1776 	$meta['show_admin_bar_front'] = empty( $userdata['show_admin_bar_front'] ) ? 'true' : $userdata['show_admin_bar_front'];
       
  1777 
       
  1778 	$meta['locale'] = isset( $userdata['locale'] ) ? $userdata['locale'] : '';
       
  1779 
       
  1780 	$compacted = compact( 'user_pass', 'user_nicename', 'user_email', 'user_url', 'user_registered', 'user_activation_key', 'display_name' );
  1745 	$data      = wp_unslash( $compacted );
  1781 	$data      = wp_unslash( $compacted );
  1746 
  1782 
  1747 	if ( ! $update ) {
  1783 	if ( ! $update ) {
  1748 		$data = $data + compact( 'user_login' );
  1784 		$data = $data + compact( 'user_login' );
       
  1785 	}
       
  1786 
       
  1787 	if ( is_multisite() ) {
       
  1788 		$data = $data + compact( 'spam' );
  1749 	}
  1789 	}
  1750 
  1790 
  1751 	/**
  1791 	/**
  1752 	 * Filters user data before the record is created or updated.
  1792 	 * Filters user data before the record is created or updated.
  1753 	 *
  1793 	 *
  1770 	 * @param bool     $update Whether the user is being updated rather than created.
  1810 	 * @param bool     $update Whether the user is being updated rather than created.
  1771 	 * @param int|null $id     ID of the user to be updated, or NULL if the user is being created.
  1811 	 * @param int|null $id     ID of the user to be updated, or NULL if the user is being created.
  1772 	 */
  1812 	 */
  1773 	$data = apply_filters( 'wp_pre_insert_user_data', $data, $update, $update ? (int) $ID : null );
  1813 	$data = apply_filters( 'wp_pre_insert_user_data', $data, $update, $update ? (int) $ID : null );
  1774 
  1814 
       
  1815 	if ( empty( $data ) || ! is_array( $data ) ) {
       
  1816 		return new WP_Error( 'empty_data', __( 'Not enough data to create this user.' ) );
       
  1817 	}
       
  1818 
  1775 	if ( $update ) {
  1819 	if ( $update ) {
  1776 		if ( $user_email !== $old_user_data->user_email ) {
  1820 		if ( $user_email !== $old_user_data->user_email || $user_pass !== $old_user_data->user_pass ) {
  1777 			$data['user_activation_key'] = '';
  1821 			$data['user_activation_key'] = '';
  1778 		}
  1822 		}
  1779 		$wpdb->update( $wpdb->users, $data, compact( 'ID' ) );
  1823 		$wpdb->update( $wpdb->users, $data, compact( 'ID' ) );
  1780 		$user_id = (int) $ID;
  1824 		$user_id = (int) $ID;
  1781 	} else {
  1825 	} else {
  1798 	 *
  1842 	 *
  1799 	 *     @type string   $nickname             The user's nickname. Default is the user's username.
  1843 	 *     @type string   $nickname             The user's nickname. Default is the user's username.
  1800 	 *     @type string   $first_name           The user's first name.
  1844 	 *     @type string   $first_name           The user's first name.
  1801 	 *     @type string   $last_name            The user's last name.
  1845 	 *     @type string   $last_name            The user's last name.
  1802 	 *     @type string   $description          The user's description.
  1846 	 *     @type string   $description          The user's description.
  1803 	 *     @type bool     $rich_editing         Whether to enable the rich-editor for the user. False if not empty.
  1847 	 *     @type string   $rich_editing         Whether to enable the rich-editor for the user. Default 'true'.
  1804 	 *     @type bool     $syntax_highlighting  Whether to enable the rich code editor for the user. False if not empty.
  1848 	 *     @type string   $syntax_highlighting  Whether to enable the rich code editor for the user. Default 'true'.
  1805 	 *     @type bool     $comment_shortcuts    Whether to enable keyboard shortcuts for the user. Default false.
  1849 	 *     @type string   $comment_shortcuts    Whether to enable keyboard shortcuts for the user. Default 'false'.
  1806 	 *     @type string   $admin_color          The color scheme for a user's admin screen. Default 'fresh'.
  1850 	 *     @type string   $admin_color          The color scheme for a user's admin screen. Default 'fresh'.
  1807 	 *     @type int|bool $use_ssl              Whether to force SSL on the user's admin area. 0|false if SSL is
  1851 	 *     @type int|bool $use_ssl              Whether to force SSL on the user's admin area. 0|false if SSL
  1808 	 *                                          not forced.
  1852 	 *                                          is not forced.
  1809 	 *     @type bool     $show_admin_bar_front Whether to show the admin bar on the front end for the user.
  1853 	 *     @type string   $show_admin_bar_front Whether to show the admin bar on the front end for the user.
  1810 	 *                                          Default true.
  1854 	 *                                          Default 'true'.
       
  1855 	 *     @type string   $locale               User's locale. Default empty.
  1811 	 * }
  1856 	 * }
  1812 	 * @param WP_User $user   User object.
  1857 	 * @param WP_User $user   User object.
  1813 	 * @param bool    $update Whether the user is being updated rather than created.
  1858 	 * @param bool    $update Whether the user is being updated rather than created.
  1814 	 */
  1859 	 */
  1815 	$meta = apply_filters( 'insert_user_meta', $meta, $user, $update );
  1860 	$meta = apply_filters( 'insert_user_meta', $meta, $user, $update );
  1828 	if ( isset( $userdata['role'] ) ) {
  1873 	if ( isset( $userdata['role'] ) ) {
  1829 		$user->set_role( $userdata['role'] );
  1874 		$user->set_role( $userdata['role'] );
  1830 	} elseif ( ! $update ) {
  1875 	} elseif ( ! $update ) {
  1831 		$user->set_role( get_option( 'default_role' ) );
  1876 		$user->set_role( get_option( 'default_role' ) );
  1832 	}
  1877 	}
  1833 	wp_cache_delete( $user_id, 'users' );
  1878 
  1834 	wp_cache_delete( $user_login, 'userlogins' );
  1879 	clean_user_cache( $user_id );
  1835 
  1880 
  1836 	if ( $update ) {
  1881 	if ( $update ) {
  1837 		/**
  1882 		/**
  1838 		 * Fires immediately after an existing user is updated.
  1883 		 * Fires immediately after an existing user is updated.
  1839 		 *
  1884 		 *
  1841 		 *
  1886 		 *
  1842 		 * @param int     $user_id       User ID.
  1887 		 * @param int     $user_id       User ID.
  1843 		 * @param WP_User $old_user_data Object containing user's data prior to update.
  1888 		 * @param WP_User $old_user_data Object containing user's data prior to update.
  1844 		 */
  1889 		 */
  1845 		do_action( 'profile_update', $user_id, $old_user_data );
  1890 		do_action( 'profile_update', $user_id, $old_user_data );
       
  1891 
       
  1892 		if ( isset( $userdata['spam'] ) && $userdata['spam'] != $old_user_data->spam ) {
       
  1893 			if ( 1 == $userdata['spam'] ) {
       
  1894 				/**
       
  1895 				 * Fires after the user is marked as a SPAM user.
       
  1896 				 *
       
  1897 				 * @since 3.0.0
       
  1898 				 *
       
  1899 				 * @param int $user_id ID of the user marked as SPAM.
       
  1900 				 */
       
  1901 				do_action( 'make_spam_user', $user_id );
       
  1902 			} else {
       
  1903 				/**
       
  1904 				 * Fires after the user is marked as a HAM user. Opposite of SPAM.
       
  1905 				 *
       
  1906 				 * @since 3.0.0
       
  1907 				 *
       
  1908 				 * @param int $user_id ID of the user marked as HAM.
       
  1909 				 */
       
  1910 				do_action( 'make_ham_user', $user_id );
       
  1911 			}
       
  1912 		}
  1846 	} else {
  1913 	} else {
  1847 		/**
  1914 		/**
  1848 		 * Fires immediately after a new user is registered.
  1915 		 * Fires immediately after a new user is registered.
  1849 		 *
  1916 		 *
  1850 		 * @since 1.5.0
  1917 		 * @since 1.5.0
  1883 	$ID = isset( $userdata['ID'] ) ? (int) $userdata['ID'] : 0;
  1950 	$ID = isset( $userdata['ID'] ) ? (int) $userdata['ID'] : 0;
  1884 	if ( ! $ID ) {
  1951 	if ( ! $ID ) {
  1885 		return new WP_Error( 'invalid_user_id', __( 'Invalid user ID.' ) );
  1952 		return new WP_Error( 'invalid_user_id', __( 'Invalid user ID.' ) );
  1886 	}
  1953 	}
  1887 
  1954 
  1888 	// First, get all of the original fields
  1955 	// First, get all of the original fields.
  1889 	$user_obj = get_userdata( $ID );
  1956 	$user_obj = get_userdata( $ID );
  1890 	if ( ! $user_obj ) {
  1957 	if ( ! $user_obj ) {
  1891 		return new WP_Error( 'invalid_user_id', __( 'Invalid user ID.' ) );
  1958 		return new WP_Error( 'invalid_user_id', __( 'Invalid user ID.' ) );
  1892 	}
  1959 	}
  1893 
  1960 
  1894 	$user = $user_obj->to_array();
  1961 	$user = $user_obj->to_array();
  1895 
  1962 
  1896 	// Add additional custom fields
  1963 	// Add additional custom fields.
  1897 	foreach ( _get_additional_user_keys( $user_obj ) as $key ) {
  1964 	foreach ( _get_additional_user_keys( $user_obj ) as $key ) {
  1898 		$user[ $key ] = get_user_meta( $ID, $key, true );
  1965 		$user[ $key ] = get_user_meta( $ID, $key, true );
  1899 	}
  1966 	}
  1900 
  1967 
  1901 	// Escape data pulled from DB.
  1968 	// Escape data pulled from DB.
  1902 	$user = add_magic_quotes( $user );
  1969 	$user = add_magic_quotes( $user );
  1903 
  1970 
  1904 	if ( ! empty( $userdata['user_pass'] ) && $userdata['user_pass'] !== $user_obj->user_pass ) {
  1971 	if ( ! empty( $userdata['user_pass'] ) && $userdata['user_pass'] !== $user_obj->user_pass ) {
  1905 		// If password is changing, hash it now
  1972 		// If password is changing, hash it now.
  1906 		$plaintext_pass        = $userdata['user_pass'];
  1973 		$plaintext_pass        = $userdata['user_pass'];
  1907 		$userdata['user_pass'] = wp_hash_password( $userdata['user_pass'] );
  1974 		$userdata['user_pass'] = wp_hash_password( $userdata['user_pass'] );
  1908 
  1975 
  1909 		/**
  1976 		/**
  1910 		 * Filters whether to send the password change email.
  1977 		 * Filters whether to send the password change email.
  1933 		 * @param array $userdata The updated user array.
  2000 		 * @param array $userdata The updated user array.
  1934 		 */
  2001 		 */
  1935 		$send_email_change_email = apply_filters( 'send_email_change_email', true, $user, $userdata );
  2002 		$send_email_change_email = apply_filters( 'send_email_change_email', true, $user, $userdata );
  1936 	}
  2003 	}
  1937 
  2004 
  1938 	wp_cache_delete( $user['user_email'], 'useremail' );
  2005 	clean_user_cache( $user_obj );
  1939 	wp_cache_delete( $user['user_nicename'], 'userslugs' );
       
  1940 
  2006 
  1941 	// Merge old and new fields with new fields overwriting old ones.
  2007 	// Merge old and new fields with new fields overwriting old ones.
  1942 	$userdata = array_merge( $user, $userdata );
  2008 	$userdata = array_merge( $user, $userdata );
  1943 	$user_id  = wp_insert_user( $userdata );
  2009 	$user_id  = wp_insert_user( $userdata );
  1944 
  2010 
  1968 ###SITEURL###'
  2034 ###SITEURL###'
  1969 			);
  2035 			);
  1970 
  2036 
  1971 			$pass_change_email = array(
  2037 			$pass_change_email = array(
  1972 				'to'      => $user['user_email'],
  2038 				'to'      => $user['user_email'],
  1973 				/* translators: Password change notification email subject. %s: Site name */
  2039 				/* translators: Password change notification email subject. %s: Site title. */
  1974 				'subject' => __( '[%s] Password Changed' ),
  2040 				'subject' => __( '[%s] Password Changed' ),
  1975 				'message' => $pass_change_text,
  2041 				'message' => $pass_change_text,
  1976 				'headers' => '',
  2042 				'headers' => '',
  1977 			);
  2043 			);
  1978 
  2044 
  1981 			 *
  2047 			 *
  1982 			 * @since 4.3.0
  2048 			 * @since 4.3.0
  1983 			 *
  2049 			 *
  1984 			 * @param array $pass_change_email {
  2050 			 * @param array $pass_change_email {
  1985 			 *            Used to build wp_mail().
  2051 			 *            Used to build wp_mail().
       
  2052 			 *
  1986 			 *            @type string $to      The intended recipients. Add emails in a comma separated string.
  2053 			 *            @type string $to      The intended recipients. Add emails in a comma separated string.
  1987 			 *            @type string $subject The subject of the email.
  2054 			 *            @type string $subject The subject of the email.
  1988 			 *            @type string $message The content of the email.
  2055 			 *            @type string $message The content of the email.
  1989 			 *                The following strings have a special meaning and will get replaced dynamically:
  2056 			 *                The following strings have a special meaning and will get replaced dynamically:
  1990 			 *                - ###USERNAME###    The current user's username.
  2057 			 *                - ###USERNAME###    The current user's username.
  2025 ###SITEURL###'
  2092 ###SITEURL###'
  2026 			);
  2093 			);
  2027 
  2094 
  2028 			$email_change_email = array(
  2095 			$email_change_email = array(
  2029 				'to'      => $user['user_email'],
  2096 				'to'      => $user['user_email'],
  2030 				/* translators: Email change notification email subject. %s: Site name */
  2097 				/* translators: Email change notification email subject. %s: Site title. */
  2031 				'subject' => __( '[%s] Email Changed' ),
  2098 				'subject' => __( '[%s] Email Changed' ),
  2032 				'message' => $email_change_text,
  2099 				'message' => $email_change_text,
  2033 				'headers' => '',
  2100 				'headers' => '',
  2034 			);
  2101 			);
  2035 
  2102 
  2038 			 *
  2105 			 *
  2039 			 * @since 4.3.0
  2106 			 * @since 4.3.0
  2040 			 *
  2107 			 *
  2041 			 * @param array $email_change_email {
  2108 			 * @param array $email_change_email {
  2042 			 *            Used to build wp_mail().
  2109 			 *            Used to build wp_mail().
       
  2110 			 *
  2043 			 *            @type string $to      The intended recipients.
  2111 			 *            @type string $to      The intended recipients.
  2044 			 *            @type string $subject The subject of the email.
  2112 			 *            @type string $subject The subject of the email.
  2045 			 *            @type string $message The content of the email.
  2113 			 *            @type string $message The content of the email.
  2046 			 *                The following strings have a special meaning and will get replaced dynamically:
  2114 			 *                The following strings have a special meaning and will get replaced dynamically:
  2047 			 *                - ###USERNAME###    The current user's username.
  2115 			 *                - ###USERNAME###    The current user's username.
  2050 			 *                - ###EMAIL###       The old email address.
  2118 			 *                - ###EMAIL###       The old email address.
  2051 			 *                - ###SITENAME###    The name of the site.
  2119 			 *                - ###SITENAME###    The name of the site.
  2052 			 *                - ###SITEURL###     The URL to the site.
  2120 			 *                - ###SITEURL###     The URL to the site.
  2053 			 *            @type string $headers Headers.
  2121 			 *            @type string $headers Headers.
  2054 			 *        }
  2122 			 *        }
  2055 			 * @param array $user The original user array.
  2123 			 * @param array $user     The original user array.
  2056 			 * @param array $userdata The updated user array.
  2124 			 * @param array $userdata The updated user array.
  2057 			 */
  2125 			 */
  2058 			$email_change_email = apply_filters( 'email_change_email', $email_change_email, $user, $userdata );
  2126 			$email_change_email = apply_filters( 'email_change_email', $email_change_email, $user, $userdata );
  2059 
  2127 
  2060 			$email_change_email['message'] = str_replace( '###USERNAME###', $user['user_login'], $email_change_email['message'] );
  2128 			$email_change_email['message'] = str_replace( '###USERNAME###', $user['user_login'], $email_change_email['message'] );
  2081 			// Here we calculate the expiration length of the current auth cookie and compare it to the default expiration.
  2149 			// Here we calculate the expiration length of the current auth cookie and compare it to the default expiration.
  2082 			// If it's greater than this, then we know the user checked 'Remember Me' when they logged in.
  2150 			// If it's greater than this, then we know the user checked 'Remember Me' when they logged in.
  2083 			$logged_in_cookie = wp_parse_auth_cookie( '', 'logged_in' );
  2151 			$logged_in_cookie = wp_parse_auth_cookie( '', 'logged_in' );
  2084 			/** This filter is documented in wp-includes/pluggable.php */
  2152 			/** This filter is documented in wp-includes/pluggable.php */
  2085 			$default_cookie_life = apply_filters( 'auth_cookie_expiration', ( 2 * DAY_IN_SECONDS ), $ID, false );
  2153 			$default_cookie_life = apply_filters( 'auth_cookie_expiration', ( 2 * DAY_IN_SECONDS ), $ID, false );
  2086 			$remember            = ( ( $logged_in_cookie['expiration'] - time() ) > $default_cookie_life );
  2154 			$remember            = false;
       
  2155 			if ( false !== $logged_in_cookie && ( $logged_in_cookie['expiration'] - time() ) > $default_cookie_life ) {
       
  2156 				$remember = true;
       
  2157 			}
  2087 
  2158 
  2088 			wp_set_auth_cookie( $ID, $remember );
  2159 			wp_set_auth_cookie( $ID, $remember );
  2089 		}
  2160 		}
  2090 	}
  2161 	}
  2091 
  2162 
  2097  *
  2168  *
  2098  * Creates a new user with just the username, password, and email. For more
  2169  * Creates a new user with just the username, password, and email. For more
  2099  * complex user creation use wp_insert_user() to specify more information.
  2170  * complex user creation use wp_insert_user() to specify more information.
  2100  *
  2171  *
  2101  * @since 2.0.0
  2172  * @since 2.0.0
  2102  * @see wp_insert_user() More complete way to create a new user
  2173  *
       
  2174  * @see wp_insert_user() More complete way to create a new user.
  2103  *
  2175  *
  2104  * @param string $username The user's username.
  2176  * @param string $username The user's username.
  2105  * @param string $password The user's password.
  2177  * @param string $password The user's password.
  2106  * @param string $email    Optional. The user's email. Default empty.
  2178  * @param string $email    Optional. The user's email. Default empty.
  2107  * @return int|WP_Error The newly created user's ID or a WP_Error object if the user could not
  2179  * @return int|WP_Error The newly created user's ID or a WP_Error object if the user could not
  2124  *
  2196  *
  2125  * @since 3.3.0
  2197  * @since 3.3.0
  2126  * @access private
  2198  * @access private
  2127  *
  2199  *
  2128  * @param WP_User $user WP_User instance.
  2200  * @param WP_User $user WP_User instance.
  2129  * @return array List of user keys to be populated in wp_update_user().
  2201  * @return string[] List of user keys to be populated in wp_update_user().
  2130  */
  2202  */
  2131 function _get_additional_user_keys( $user ) {
  2203 function _get_additional_user_keys( $user ) {
  2132 	$keys = array( 'first_name', 'last_name', 'nickname', 'description', 'rich_editing', 'syntax_highlighting', 'comment_shortcuts', 'admin_color', 'use_ssl', 'show_admin_bar_front', 'locale' );
  2204 	$keys = array( 'first_name', 'last_name', 'nickname', 'description', 'rich_editing', 'syntax_highlighting', 'comment_shortcuts', 'admin_color', 'use_ssl', 'show_admin_bar_front', 'locale' );
  2133 	return array_merge( $keys, array_keys( wp_get_user_contact_methods( $user ) ) );
  2205 	return array_merge( $keys, array_keys( wp_get_user_contact_methods( $user ) ) );
  2134 }
  2206 }
  2139  * Default contact methods were removed in 3.6. A filter dictates contact methods.
  2211  * Default contact methods were removed in 3.6. A filter dictates contact methods.
  2140  *
  2212  *
  2141  * @since 3.7.0
  2213  * @since 3.7.0
  2142  *
  2214  *
  2143  * @param WP_User $user Optional. WP_User object.
  2215  * @param WP_User $user Optional. WP_User object.
  2144  * @return array Array of contact methods and their labels.
  2216  * @return string[] Array of contact method labels keyed by contact method.
  2145  */
  2217  */
  2146 function wp_get_user_contact_methods( $user = null ) {
  2218 function wp_get_user_contact_methods( $user = null ) {
  2147 	$methods = array();
  2219 	$methods = array();
  2148 	if ( get_site_option( 'initial_db_version' ) < 23588 ) {
  2220 	if ( get_site_option( 'initial_db_version' ) < 23588 ) {
  2149 		$methods = array(
  2221 		$methods = array(
  2156 	/**
  2228 	/**
  2157 	 * Filters the user contact methods.
  2229 	 * Filters the user contact methods.
  2158 	 *
  2230 	 *
  2159 	 * @since 2.9.0
  2231 	 * @since 2.9.0
  2160 	 *
  2232 	 *
  2161 	 * @param array   $methods Array of contact methods and their labels.
  2233 	 * @param string[] $methods Array of contact method labels keyed by contact method.
  2162 	 * @param WP_User $user    WP_User object.
  2234 	 * @param WP_User  $user    WP_User object.
  2163 	 */
  2235 	 */
  2164 	return apply_filters( 'user_contactmethods', $methods, $user );
  2236 	return apply_filters( 'user_contactmethods', $methods, $user );
  2165 }
  2237 }
  2166 
  2238 
  2167 /**
  2239 /**
  2171  *
  2243  *
  2172  * @since 2.9.0
  2244  * @since 2.9.0
  2173  * @access private
  2245  * @access private
  2174  *
  2246  *
  2175  * @param WP_User $user Optional. WP_User object. Default null.
  2247  * @param WP_User $user Optional. WP_User object. Default null.
  2176  * @return array Array of contact methods and their labels.
  2248  * @return string[] Array of contact method labels keyed by contact method.
  2177  */
  2249  */
  2178 function _wp_get_user_contactmethods( $user = null ) {
  2250 function _wp_get_user_contactmethods( $user = null ) {
  2179 	return wp_get_user_contact_methods( $user );
  2251 	return wp_get_user_contact_methods( $user );
  2180 }
  2252 }
  2181 
  2253 
  2202 /**
  2274 /**
  2203  * Creates, stores, then returns a password reset key for user.
  2275  * Creates, stores, then returns a password reset key for user.
  2204  *
  2276  *
  2205  * @since 4.4.0
  2277  * @since 4.4.0
  2206  *
  2278  *
  2207  * @global wpdb         $wpdb      WordPress database abstraction object.
       
  2208  * @global PasswordHash $wp_hasher Portable PHP password hashing framework.
  2279  * @global PasswordHash $wp_hasher Portable PHP password hashing framework.
  2209  *
  2280  *
  2210  * @param WP_User $user User to retrieve password reset key for.
  2281  * @param WP_User $user User to retrieve password reset key for.
  2211  *
       
  2212  * @return string|WP_Error Password reset key on success. WP_Error on error.
  2282  * @return string|WP_Error Password reset key on success. WP_Error on error.
  2213  */
  2283  */
  2214 function get_password_reset_key( $user ) {
  2284 function get_password_reset_key( $user ) {
  2215 	global $wpdb, $wp_hasher;
  2285 	global $wp_hasher;
  2216 
  2286 
  2217 	if ( ! ( $user instanceof WP_User ) ) {
  2287 	if ( ! ( $user instanceof WP_User ) ) {
  2218 		return new WP_Error( 'invalidcombo', __( '<strong>ERROR</strong>: There is no account with that username or email address.' ) );
  2288 		return new WP_Error( 'invalidcombo', __( '<strong>Error</strong>: There is no account with that username or email address.' ) );
  2219 	}
  2289 	}
  2220 
  2290 
  2221 	/**
  2291 	/**
  2222 	 * Fires before a new password is retrieved.
  2292 	 * Fires before a new password is retrieved.
  2223 	 *
  2293 	 *
  2224 	 * Use the {@see 'retrieve_password'} hook instead.
  2294 	 * Use the {@see 'retrieve_password'} hook instead.
  2225 	 *
  2295 	 *
  2226 	 * @since 1.5.0
  2296 	 * @since 1.5.0
  2227 	 * @deprecated 1.5.1 Misspelled. Use 'retrieve_password' hook instead.
  2297 	 * @deprecated 1.5.1 Misspelled. Use {@see 'retrieve_password'} hook instead.
  2228 	 *
  2298 	 *
  2229 	 * @param string $user_login The user login name.
  2299 	 * @param string $user_login The user login name.
  2230 	 */
  2300 	 */
  2231 	do_action( 'retreive_password', $user->user_login );
  2301 	do_action_deprecated( 'retreive_password', array( $user->user_login ), '1.5.1', 'retrieve_password' );
  2232 
  2302 
  2233 	/**
  2303 	/**
  2234 	 * Fires before a new password is retrieved.
  2304 	 * Fires before a new password is retrieved.
  2235 	 *
  2305 	 *
  2236 	 * @since 1.5.1
  2306 	 * @since 1.5.1
  2247 	/**
  2317 	/**
  2248 	 * Filters whether to allow a password to be reset.
  2318 	 * Filters whether to allow a password to be reset.
  2249 	 *
  2319 	 *
  2250 	 * @since 2.7.0
  2320 	 * @since 2.7.0
  2251 	 *
  2321 	 *
  2252 	 * @param bool $allow         Whether to allow the password to be reset. Default true.
  2322 	 * @param bool $allow Whether to allow the password to be reset. Default true.
  2253 	 * @param int  $user_data->ID The ID of the user attempting to reset a password.
  2323 	 * @param int  $ID    The ID of the user attempting to reset a password.
  2254 	 */
  2324 	 */
  2255 	$allow = apply_filters( 'allow_password_reset', $allow, $user->ID );
  2325 	$allow = apply_filters( 'allow_password_reset', $allow, $user->ID );
  2256 
  2326 
  2257 	if ( ! $allow ) {
  2327 	if ( ! $allow ) {
  2258 		return new WP_Error( 'no_password_reset', __( 'Password reset is not allowed for this user' ) );
  2328 		return new WP_Error( 'no_password_reset', __( 'Password reset is not allowed for this user' ) );
  2276 	// Now insert the key, hashed, into the DB.
  2346 	// Now insert the key, hashed, into the DB.
  2277 	if ( empty( $wp_hasher ) ) {
  2347 	if ( empty( $wp_hasher ) ) {
  2278 		require_once ABSPATH . WPINC . '/class-phpass.php';
  2348 		require_once ABSPATH . WPINC . '/class-phpass.php';
  2279 		$wp_hasher = new PasswordHash( 8, true );
  2349 		$wp_hasher = new PasswordHash( 8, true );
  2280 	}
  2350 	}
  2281 	$hashed    = time() . ':' . $wp_hasher->HashPassword( $key );
  2351 
  2282 	$key_saved = $wpdb->update( $wpdb->users, array( 'user_activation_key' => $hashed ), array( 'user_login' => $user->user_login ) );
  2352 	$hashed = time() . ':' . $wp_hasher->HashPassword( $key );
  2283 	if ( false === $key_saved ) {
  2353 
  2284 		return new WP_Error( 'no_password_key_update', __( 'Could not save password reset key to database.' ) );
  2354 	$key_saved = wp_update_user(
       
  2355 		array(
       
  2356 			'ID'                  => $user->ID,
       
  2357 			'user_activation_key' => $hashed,
       
  2358 		)
       
  2359 	);
       
  2360 
       
  2361 	if ( is_wp_error( $key_saved ) ) {
       
  2362 		return $key_saved;
  2285 	}
  2363 	}
  2286 
  2364 
  2287 	return $key;
  2365 	return $key;
  2288 }
  2366 }
  2289 
  2367 
  2315 
  2393 
  2316 	if ( empty( $login ) || ! is_string( $login ) ) {
  2394 	if ( empty( $login ) || ! is_string( $login ) ) {
  2317 		return new WP_Error( 'invalid_key', __( 'Invalid key.' ) );
  2395 		return new WP_Error( 'invalid_key', __( 'Invalid key.' ) );
  2318 	}
  2396 	}
  2319 
  2397 
  2320 	$row = $wpdb->get_row( $wpdb->prepare( "SELECT ID, user_activation_key FROM $wpdb->users WHERE user_login = %s", $login ) );
  2398 	$user = get_user_by( 'login', $login );
  2321 	if ( ! $row ) {
  2399 
       
  2400 	if ( ! $user ) {
  2322 		return new WP_Error( 'invalid_key', __( 'Invalid key.' ) );
  2401 		return new WP_Error( 'invalid_key', __( 'Invalid key.' ) );
  2323 	}
  2402 	}
  2324 
  2403 
  2325 	if ( empty( $wp_hasher ) ) {
  2404 	if ( empty( $wp_hasher ) ) {
  2326 		require_once ABSPATH . WPINC . '/class-phpass.php';
  2405 		require_once ABSPATH . WPINC . '/class-phpass.php';
  2334 	 *
  2413 	 *
  2335 	 * @param int $expiration The expiration time in seconds.
  2414 	 * @param int $expiration The expiration time in seconds.
  2336 	 */
  2415 	 */
  2337 	$expiration_duration = apply_filters( 'password_reset_expiration', DAY_IN_SECONDS );
  2416 	$expiration_duration = apply_filters( 'password_reset_expiration', DAY_IN_SECONDS );
  2338 
  2417 
  2339 	if ( false !== strpos( $row->user_activation_key, ':' ) ) {
  2418 	if ( false !== strpos( $user->user_activation_key, ':' ) ) {
  2340 		list( $pass_request_time, $pass_key ) = explode( ':', $row->user_activation_key, 2 );
  2419 		list( $pass_request_time, $pass_key ) = explode( ':', $user->user_activation_key, 2 );
  2341 		$expiration_time                      = $pass_request_time + $expiration_duration;
  2420 		$expiration_time                      = $pass_request_time + $expiration_duration;
  2342 	} else {
  2421 	} else {
  2343 		$pass_key        = $row->user_activation_key;
  2422 		$pass_key        = $user->user_activation_key;
  2344 		$expiration_time = false;
  2423 		$expiration_time = false;
  2345 	}
  2424 	}
  2346 
  2425 
  2347 	if ( ! $pass_key ) {
  2426 	if ( ! $pass_key ) {
  2348 		return new WP_Error( 'invalid_key', __( 'Invalid key.' ) );
  2427 		return new WP_Error( 'invalid_key', __( 'Invalid key.' ) );
  2349 	}
  2428 	}
  2350 
  2429 
  2351 	$hash_is_correct = $wp_hasher->CheckPassword( $key, $pass_key );
  2430 	$hash_is_correct = $wp_hasher->CheckPassword( $key, $pass_key );
  2352 
  2431 
  2353 	if ( $hash_is_correct && $expiration_time && time() < $expiration_time ) {
  2432 	if ( $hash_is_correct && $expiration_time && time() < $expiration_time ) {
  2354 		return get_userdata( $row->ID );
  2433 		return $user;
  2355 	} elseif ( $hash_is_correct && $expiration_time ) {
  2434 	} elseif ( $hash_is_correct && $expiration_time ) {
  2356 		// Key has an expiration time that's passed
  2435 		// Key has an expiration time that's passed.
  2357 		return new WP_Error( 'expired_key', __( 'Invalid key.' ) );
  2436 		return new WP_Error( 'expired_key', __( 'Invalid key.' ) );
  2358 	}
  2437 	}
  2359 
  2438 
  2360 	if ( hash_equals( $row->user_activation_key, $key ) || ( $hash_is_correct && ! $expiration_time ) ) {
  2439 	if ( hash_equals( $user->user_activation_key, $key ) || ( $hash_is_correct && ! $expiration_time ) ) {
  2361 		$return  = new WP_Error( 'expired_key', __( 'Invalid key.' ) );
  2440 		$return  = new WP_Error( 'expired_key', __( 'Invalid key.' ) );
  2362 		$user_id = $row->ID;
  2441 		$user_id = $user->ID;
  2363 
  2442 
  2364 		/**
  2443 		/**
  2365 		 * Filters the return value of check_password_reset_key() when an
  2444 		 * Filters the return value of check_password_reset_key() when an
  2366 		 * old-style key is used.
  2445 		 * old-style key is used.
  2367 		 *
  2446 		 *
  2382  * Handles resetting the user's password.
  2461  * Handles resetting the user's password.
  2383  *
  2462  *
  2384  * @since 2.5.0
  2463  * @since 2.5.0
  2385  *
  2464  *
  2386  * @param WP_User $user     The user
  2465  * @param WP_User $user     The user
  2387  * @param string $new_pass New password for the user in plaintext
  2466  * @param string  $new_pass New password for the user in plaintext
  2388  */
  2467  */
  2389 function reset_password( $user, $new_pass ) {
  2468 function reset_password( $user, $new_pass ) {
  2390 	/**
  2469 	/**
  2391 	 * Fires before the user's password is reset.
  2470 	 * Fires before the user's password is reset.
  2392 	 *
  2471 	 *
  2393 	 * @since 1.5.0
  2472 	 * @since 1.5.0
  2394 	 *
  2473 	 *
  2395 	 * @param object $user     The user.
  2474 	 * @param WP_User $user     The user.
  2396 	 * @param string $new_pass New user password.
  2475 	 * @param string  $new_pass New user password.
  2397 	 */
  2476 	 */
  2398 	do_action( 'password_reset', $user, $new_pass );
  2477 	do_action( 'password_reset', $user, $new_pass );
  2399 
  2478 
  2400 	wp_set_password( $new_pass, $user->ID );
  2479 	wp_set_password( $new_pass, $user->ID );
  2401 	update_user_option( $user->ID, 'default_password_nag', false, true );
  2480 	update_user_option( $user->ID, 'default_password_nag', false, true );
  2431 	 *
  2510 	 *
  2432 	 * @param string $user_email The email address of the new user.
  2511 	 * @param string $user_email The email address of the new user.
  2433 	 */
  2512 	 */
  2434 	$user_email = apply_filters( 'user_registration_email', $user_email );
  2513 	$user_email = apply_filters( 'user_registration_email', $user_email );
  2435 
  2514 
  2436 	// Check the username
  2515 	// Check the username.
  2437 	if ( $sanitized_user_login == '' ) {
  2516 	if ( '' === $sanitized_user_login ) {
  2438 		$errors->add( 'empty_username', __( '<strong>ERROR</strong>: Please enter a username.' ) );
  2517 		$errors->add( 'empty_username', __( '<strong>Error</strong>: Please enter a username.' ) );
  2439 	} elseif ( ! validate_username( $user_login ) ) {
  2518 	} elseif ( ! validate_username( $user_login ) ) {
  2440 		$errors->add( 'invalid_username', __( '<strong>ERROR</strong>: This username is invalid because it uses illegal characters. Please enter a valid username.' ) );
  2519 		$errors->add( 'invalid_username', __( '<strong>Error</strong>: This username is invalid because it uses illegal characters. Please enter a valid username.' ) );
  2441 		$sanitized_user_login = '';
  2520 		$sanitized_user_login = '';
  2442 	} elseif ( username_exists( $sanitized_user_login ) ) {
  2521 	} elseif ( username_exists( $sanitized_user_login ) ) {
  2443 		$errors->add( 'username_exists', __( '<strong>ERROR</strong>: This username is already registered. Please choose another one.' ) );
  2522 		$errors->add( 'username_exists', __( '<strong>Error</strong>: This username is already registered. Please choose another one.' ) );
  2444 
  2523 
  2445 	} else {
  2524 	} else {
  2446 		/** This filter is documented in wp-includes/user.php */
  2525 		/** This filter is documented in wp-includes/user.php */
  2447 		$illegal_user_logins = array_map( 'strtolower', (array) apply_filters( 'illegal_user_logins', array() ) );
  2526 		$illegal_user_logins = (array) apply_filters( 'illegal_user_logins', array() );
  2448 		if ( in_array( strtolower( $sanitized_user_login ), $illegal_user_logins ) ) {
  2527 		if ( in_array( strtolower( $sanitized_user_login ), array_map( 'strtolower', $illegal_user_logins ), true ) ) {
  2449 			$errors->add( 'invalid_username', __( '<strong>ERROR</strong>: Sorry, that username is not allowed.' ) );
  2528 			$errors->add( 'invalid_username', __( '<strong>Error</strong>: Sorry, that username is not allowed.' ) );
  2450 		}
  2529 		}
  2451 	}
  2530 	}
  2452 
  2531 
  2453 	// Check the email address
  2532 	// Check the email address.
  2454 	if ( $user_email == '' ) {
  2533 	if ( '' === $user_email ) {
  2455 		$errors->add( 'empty_email', __( '<strong>ERROR</strong>: Please type your email address.' ) );
  2534 		$errors->add( 'empty_email', __( '<strong>Error</strong>: Please type your email address.' ) );
  2456 	} elseif ( ! is_email( $user_email ) ) {
  2535 	} elseif ( ! is_email( $user_email ) ) {
  2457 		$errors->add( 'invalid_email', __( '<strong>ERROR</strong>: The email address isn&#8217;t correct.' ) );
  2536 		$errors->add( 'invalid_email', __( '<strong>Error</strong>: The email address isn&#8217;t correct.' ) );
  2458 		$user_email = '';
  2537 		$user_email = '';
  2459 	} elseif ( email_exists( $user_email ) ) {
  2538 	} elseif ( email_exists( $user_email ) ) {
  2460 		$errors->add( 'email_exists', __( '<strong>ERROR</strong>: This email is already registered, please choose another one.' ) );
  2539 		$errors->add( 'email_exists', __( '<strong>Error</strong>: This email is already registered. Please choose another one.' ) );
  2461 	}
  2540 	}
  2462 
  2541 
  2463 	/**
  2542 	/**
  2464 	 * Fires when submitting registration form data, before the user is created.
  2543 	 * Fires when submitting registration form data, before the user is created.
  2465 	 *
  2544 	 *
  2475 
  2554 
  2476 	/**
  2555 	/**
  2477 	 * Filters the errors encountered when a new user is being registered.
  2556 	 * Filters the errors encountered when a new user is being registered.
  2478 	 *
  2557 	 *
  2479 	 * The filtered WP_Error object may, for example, contain errors for an invalid
  2558 	 * The filtered WP_Error object may, for example, contain errors for an invalid
  2480 	 * or existing username or email address. A WP_Error object should always returned,
  2559 	 * or existing username or email address. A WP_Error object should always be returned,
  2481 	 * but may or may not contain errors.
  2560 	 * but may or may not contain errors.
  2482 	 *
  2561 	 *
  2483 	 * If any errors are present in $errors, this will abort the user's registration.
  2562 	 * If any errors are present in $errors, this will abort the user's registration.
  2484 	 *
  2563 	 *
  2485 	 * @since 2.1.0
  2564 	 * @since 2.1.0
  2496 	}
  2575 	}
  2497 
  2576 
  2498 	$user_pass = wp_generate_password( 12, false );
  2577 	$user_pass = wp_generate_password( 12, false );
  2499 	$user_id   = wp_create_user( $sanitized_user_login, $user_pass, $user_email );
  2578 	$user_id   = wp_create_user( $sanitized_user_login, $user_pass, $user_email );
  2500 	if ( ! $user_id || is_wp_error( $user_id ) ) {
  2579 	if ( ! $user_id || is_wp_error( $user_id ) ) {
  2501 		$errors->add( 'registerfail', sprintf( __( '<strong>ERROR</strong>: Couldn&#8217;t register you&hellip; please contact the <a href="mailto:%s">webmaster</a> !' ), get_option( 'admin_email' ) ) );
  2580 		$errors->add(
       
  2581 			'registerfail',
       
  2582 			sprintf(
       
  2583 				/* translators: %s: Admin email address. */
       
  2584 				__( '<strong>Error</strong>: Couldn&#8217;t register you&hellip; please contact the <a href="mailto:%s">site admin</a>!' ),
       
  2585 				get_option( 'admin_email' )
       
  2586 			)
       
  2587 		);
  2502 		return $errors;
  2588 		return $errors;
  2503 	}
  2589 	}
  2504 
  2590 
  2505 	update_user_option( $user_id, 'default_password_nag', true, true ); //Set up the Password change nag.
  2591 	update_user_option( $user_id, 'default_password_nag', true, true ); // Set up the password change nag.
  2506 
  2592 
  2507 	/**
  2593 	/**
  2508 	 * Fires after a new user registration has been recorded.
  2594 	 * Fires after a new user registration has been recorded.
  2509 	 *
  2595 	 *
  2510 	 * @since 4.4.0
  2596 	 * @since 4.4.0
  2548 
  2634 
  2549 /**
  2635 /**
  2550  * Retrieve a list of sessions for the current user.
  2636  * Retrieve a list of sessions for the current user.
  2551  *
  2637  *
  2552  * @since 4.0.0
  2638  * @since 4.0.0
       
  2639  *
  2553  * @return array Array of sessions.
  2640  * @return array Array of sessions.
  2554  */
  2641  */
  2555 function wp_get_all_sessions() {
  2642 function wp_get_all_sessions() {
  2556 	$manager = WP_Session_Tokens::get_instance( get_current_user_id() );
  2643 	$manager = WP_Session_Tokens::get_instance( get_current_user_id() );
  2557 	return $manager->get_all();
  2644 	return $manager->get_all();
  2598  *
  2685  *
  2599  * @since 4.4.0
  2686  * @since 4.4.0
  2600  * @since 4.9.0 The `$site_id` parameter was added to support multisite.
  2687  * @since 4.9.0 The `$site_id` parameter was added to support multisite.
  2601  *
  2688  *
  2602  * @param int|null $site_id Optional. The site ID to get users with no role for. Defaults to the current site.
  2689  * @param int|null $site_id Optional. The site ID to get users with no role for. Defaults to the current site.
  2603  * @return array Array of user IDs.
  2690  * @return string[] Array of user IDs as strings.
  2604  */
  2691  */
  2605 function wp_get_users_with_no_role( $site_id = null ) {
  2692 function wp_get_users_with_no_role( $site_id = null ) {
  2606 	global $wpdb;
  2693 	global $wpdb;
  2607 
  2694 
  2608 	if ( ! $site_id ) {
  2695 	if ( ! $site_id ) {
  2609 		$site_id = get_current_blog_id();
  2696 		$site_id = get_current_blog_id();
  2610 	}
  2697 	}
  2611 
  2698 
  2612 	$prefix = $wpdb->get_blog_prefix( $site_id );
  2699 	$prefix = $wpdb->get_blog_prefix( $site_id );
  2613 
  2700 
  2614 	if ( is_multisite() && $site_id != get_current_blog_id() ) {
  2701 	if ( is_multisite() && get_current_blog_id() != $site_id ) {
  2615 		switch_to_blog( $site_id );
  2702 		switch_to_blog( $site_id );
  2616 		$role_names = wp_roles()->get_names();
  2703 		$role_names = wp_roles()->get_names();
  2617 		restore_current_blog();
  2704 		restore_current_blog();
  2618 	} else {
  2705 	} else {
  2619 		$role_names = wp_roles()->get_names();
  2706 		$role_names = wp_roles()->get_names();
  2661 	if ( ! empty( $current_user ) ) {
  2748 	if ( ! empty( $current_user ) ) {
  2662 		if ( $current_user instanceof WP_User ) {
  2749 		if ( $current_user instanceof WP_User ) {
  2663 			return $current_user;
  2750 			return $current_user;
  2664 		}
  2751 		}
  2665 
  2752 
  2666 		// Upgrade stdClass to WP_User
  2753 		// Upgrade stdClass to WP_User.
  2667 		if ( is_object( $current_user ) && isset( $current_user->ID ) ) {
  2754 		if ( is_object( $current_user ) && isset( $current_user->ID ) ) {
  2668 			$cur_id       = $current_user->ID;
  2755 			$cur_id       = $current_user->ID;
  2669 			$current_user = null;
  2756 			$current_user = null;
  2670 			wp_set_current_user( $cur_id );
  2757 			wp_set_current_user( $cur_id );
  2671 			return $current_user;
  2758 			return $current_user;
  2728 
  2815 
  2729 	if ( $current_user->user_email != $_POST['email'] ) {
  2816 	if ( $current_user->user_email != $_POST['email'] ) {
  2730 		if ( ! is_email( $_POST['email'] ) ) {
  2817 		if ( ! is_email( $_POST['email'] ) ) {
  2731 			$errors->add(
  2818 			$errors->add(
  2732 				'user_email',
  2819 				'user_email',
  2733 				__( '<strong>ERROR</strong>: The email address isn&#8217;t correct.' ),
  2820 				__( '<strong>Error</strong>: The email address isn&#8217;t correct.' ),
  2734 				array(
  2821 				array(
  2735 					'form-field' => 'email',
  2822 					'form-field' => 'email',
  2736 				)
  2823 				)
  2737 			);
  2824 			);
  2738 
  2825 
  2740 		}
  2827 		}
  2741 
  2828 
  2742 		if ( email_exists( $_POST['email'] ) ) {
  2829 		if ( email_exists( $_POST['email'] ) ) {
  2743 			$errors->add(
  2830 			$errors->add(
  2744 				'user_email',
  2831 				'user_email',
  2745 				__( '<strong>ERROR</strong>: The email address is already used.' ),
  2832 				__( '<strong>Error</strong>: The email address is already used.' ),
  2746 				array(
  2833 				array(
  2747 					'form-field' => 'email',
  2834 					'form-field' => 'email',
  2748 				)
  2835 				)
  2749 			);
  2836 			);
  2750 			delete_user_meta( $current_user->ID, '_new_email' );
  2837 			delete_user_meta( $current_user->ID, '_new_email' );
  2782 
  2869 
  2783 		/**
  2870 		/**
  2784 		 * Filters the text of the email sent when a change of user email address is attempted.
  2871 		 * Filters the text of the email sent when a change of user email address is attempted.
  2785 		 *
  2872 		 *
  2786 		 * The following strings have a special meaning and will get replaced dynamically:
  2873 		 * The following strings have a special meaning and will get replaced dynamically:
  2787 		 * ###USERNAME###  The current user's username.
  2874 		 * - ###USERNAME###  The current user's username.
  2788 		 * ###ADMIN_URL### The link to click on to confirm the email change.
  2875 		 * - ###ADMIN_URL### The link to click on to confirm the email change.
  2789 		 * ###EMAIL###     The new email.
  2876 		 * - ###EMAIL###     The new email.
  2790 		 * ###SITENAME###  The name of the site.
  2877 		 * - ###SITENAME###  The name of the site.
  2791 		 * ###SITEURL###   The URL to the site.
  2878 		 * - ###SITEURL###   The URL to the site.
  2792 		 *
  2879 		 *
  2793 		 * @since MU (3.0.0)
  2880 		 * @since MU (3.0.0)
  2794 		 * @since 4.9.0 This filter is no longer Multisite specific.
  2881 		 * @since 4.9.0 This filter is no longer Multisite specific.
  2795 		 *
  2882 		 *
  2796 		 * @param string $email_text     Text in the email.
  2883 		 * @param string $email_text     Text in the email.
  2807 		$content = str_replace( '###ADMIN_URL###', esc_url( admin_url( 'profile.php?newuseremail=' . $hash ) ), $content );
  2894 		$content = str_replace( '###ADMIN_URL###', esc_url( admin_url( 'profile.php?newuseremail=' . $hash ) ), $content );
  2808 		$content = str_replace( '###EMAIL###', $_POST['email'], $content );
  2895 		$content = str_replace( '###EMAIL###', $_POST['email'], $content );
  2809 		$content = str_replace( '###SITENAME###', $sitename, $content );
  2896 		$content = str_replace( '###SITENAME###', $sitename, $content );
  2810 		$content = str_replace( '###SITEURL###', home_url(), $content );
  2897 		$content = str_replace( '###SITEURL###', home_url(), $content );
  2811 
  2898 
  2812 		/* translators: New email address notification email subject. %s: Site name */
  2899 		/* translators: New email address notification email subject. %s: Site title. */
  2813 		wp_mail( $_POST['email'], sprintf( __( '[%s] Email Change Request' ), $sitename ), $content );
  2900 		wp_mail( $_POST['email'], sprintf( __( '[%s] Email Change Request' ), $sitename ), $content );
  2814 
  2901 
  2815 		$_POST['email'] = $current_user->user_email;
  2902 		$_POST['email'] = $current_user->user_email;
  2816 	}
  2903 	}
  2817 }
  2904 }
  2829 	global $pagenow;
  2916 	global $pagenow;
  2830 
  2917 
  2831 	if ( 'profile.php' === $pagenow && isset( $_GET['updated'] ) ) {
  2918 	if ( 'profile.php' === $pagenow && isset( $_GET['updated'] ) ) {
  2832 		$email = get_user_meta( get_current_user_id(), '_new_email', true );
  2919 		$email = get_user_meta( get_current_user_id(), '_new_email', true );
  2833 		if ( $email ) {
  2920 		if ( $email ) {
  2834 			/* translators: %s: New email address */
  2921 			/* translators: %s: New email address. */
  2835 			echo '<div class="notice notice-info"><p>' . sprintf( __( 'Your email address has not been updated yet. Please check your inbox at %s for a confirmation email.' ), '<code>' . esc_html( $email['newemail'] ) . '</code>' ) . '</p></div>';
  2922 			echo '<div class="notice notice-info"><p>' . sprintf( __( 'Your email address has not been updated yet. Please check your inbox at %s for a confirmation email.' ), '<code>' . esc_html( $email['newemail'] ) . '</code>' ) . '</p></div>';
  2836 		}
  2923 		}
  2837 	}
  2924 	}
  2838 }
  2925 }
  2839 
  2926 
  2871 
  2958 
  2872 /**
  2959 /**
  2873  * Finds and exports personal data associated with an email address from the user and user_meta table.
  2960  * Finds and exports personal data associated with an email address from the user and user_meta table.
  2874  *
  2961  *
  2875  * @since 4.9.6
  2962  * @since 4.9.6
  2876  *
  2963  * @since 5.4.0 Added 'Community Events Location' group to the export data.
  2877  * @param string $email_address  The users email address.
  2964  * @since 5.4.0 Added 'Session Tokens' group to the export data.
       
  2965  *
       
  2966  * @param string $email_address  The user's email address.
  2878  * @return array An array of personal data.
  2967  * @return array An array of personal data.
  2879  */
  2968  */
  2880 function wp_user_personal_data_exporter( $email_address ) {
  2969 function wp_user_personal_data_exporter( $email_address ) {
  2881 	$email_address = trim( $email_address );
  2970 	$email_address = trim( $email_address );
  2882 
  2971 
  2891 		);
  2980 		);
  2892 	}
  2981 	}
  2893 
  2982 
  2894 	$user_meta = get_user_meta( $user->ID );
  2983 	$user_meta = get_user_meta( $user->ID );
  2895 
  2984 
  2896 	$user_prop_to_export = array(
  2985 	$user_props_to_export = array(
  2897 		'ID'              => __( 'User ID' ),
  2986 		'ID'              => __( 'User ID' ),
  2898 		'user_login'      => __( 'User Login Name' ),
  2987 		'user_login'      => __( 'User Login Name' ),
  2899 		'user_nicename'   => __( 'User Nice Name' ),
  2988 		'user_nicename'   => __( 'User Nice Name' ),
  2900 		'user_email'      => __( 'User Email' ),
  2989 		'user_email'      => __( 'User Email' ),
  2901 		'user_url'        => __( 'User URL' ),
  2990 		'user_url'        => __( 'User URL' ),
  2907 		'description'     => __( 'User Description' ),
  2996 		'description'     => __( 'User Description' ),
  2908 	);
  2997 	);
  2909 
  2998 
  2910 	$user_data_to_export = array();
  2999 	$user_data_to_export = array();
  2911 
  3000 
  2912 	foreach ( $user_prop_to_export as $key => $name ) {
  3001 	foreach ( $user_props_to_export as $key => $name ) {
  2913 		$value = '';
  3002 		$value = '';
  2914 
  3003 
  2915 		switch ( $key ) {
  3004 		switch ( $key ) {
  2916 			case 'ID':
  3005 			case 'ID':
  2917 			case 'user_login':
  3006 			case 'user_login':
  2936 				'value' => $value,
  3025 				'value' => $value,
  2937 			);
  3026 			);
  2938 		}
  3027 		}
  2939 	}
  3028 	}
  2940 
  3029 
       
  3030 	// Get the list of reserved names.
       
  3031 	$reserved_names = array_values( $user_props_to_export );
       
  3032 
       
  3033 	/**
       
  3034 	 * Filter to extend the user's profile data for the privacy exporter.
       
  3035 	 *
       
  3036 	 * @since 5.4.0
       
  3037 	 *
       
  3038 	 * @param array    $additional_user_profile_data {
       
  3039 	 *     An array of name-value pairs of additional user data items. Default empty array.
       
  3040 	 *
       
  3041 	 *     @type string $name  The user-facing name of an item name-value pair,e.g. 'IP Address'.
       
  3042 	 *     @type string $value The user-facing value of an item data pair, e.g. '50.60.70.0'.
       
  3043 	 * }
       
  3044 	 * @param WP_User  $user           The user whose data is being exported.
       
  3045 	 * @param string[] $reserved_names An array of reserved names. Any item in `$additional_user_data`
       
  3046 	 *                                 that uses one of these for its `name` will not be included in the export.
       
  3047 	 */
       
  3048 	$_extra_data = apply_filters( 'wp_privacy_additional_user_profile_data', array(), $user, $reserved_names );
       
  3049 
       
  3050 	if ( is_array( $_extra_data ) && ! empty( $_extra_data ) ) {
       
  3051 		// Remove items that use reserved names.
       
  3052 		$extra_data = array_filter(
       
  3053 			$_extra_data,
       
  3054 			function( $item ) use ( $reserved_names ) {
       
  3055 				return ! in_array( $item['name'], $reserved_names, true );
       
  3056 			}
       
  3057 		);
       
  3058 
       
  3059 		if ( count( $extra_data ) !== count( $_extra_data ) ) {
       
  3060 			_doing_it_wrong(
       
  3061 				__FUNCTION__,
       
  3062 				sprintf(
       
  3063 					/* translators: %s: wp_privacy_additional_user_profile_data */
       
  3064 					__( 'Filter %s returned items with reserved names.' ),
       
  3065 					'<code>wp_privacy_additional_user_profile_data</code>'
       
  3066 				),
       
  3067 				'5.4.0'
       
  3068 			);
       
  3069 		}
       
  3070 
       
  3071 		if ( ! empty( $extra_data ) ) {
       
  3072 			$user_data_to_export = array_merge( $user_data_to_export, $extra_data );
       
  3073 		}
       
  3074 	}
       
  3075 
  2941 	$data_to_export[] = array(
  3076 	$data_to_export[] = array(
  2942 		'group_id'    => 'user',
  3077 		'group_id'          => 'user',
  2943 		'group_label' => __( 'User' ),
  3078 		'group_label'       => __( 'User' ),
  2944 		'item_id'     => "user-{$user->ID}",
  3079 		'group_description' => __( 'User&#8217;s profile data.' ),
  2945 		'data'        => $user_data_to_export,
  3080 		'item_id'           => "user-{$user->ID}",
       
  3081 		'data'              => $user_data_to_export,
  2946 	);
  3082 	);
       
  3083 
       
  3084 	if ( isset( $user_meta['community-events-location'] ) ) {
       
  3085 		$location = maybe_unserialize( $user_meta['community-events-location'][0] );
       
  3086 
       
  3087 		$location_props_to_export = array(
       
  3088 			'description' => __( 'City' ),
       
  3089 			'country'     => __( 'Country' ),
       
  3090 			'latitude'    => __( 'Latitude' ),
       
  3091 			'longitude'   => __( 'Longitude' ),
       
  3092 			'ip'          => __( 'IP' ),
       
  3093 		);
       
  3094 
       
  3095 		$location_data_to_export = array();
       
  3096 
       
  3097 		foreach ( $location_props_to_export as $key => $name ) {
       
  3098 			if ( ! empty( $location[ $key ] ) ) {
       
  3099 				$location_data_to_export[] = array(
       
  3100 					'name'  => $name,
       
  3101 					'value' => $location[ $key ],
       
  3102 				);
       
  3103 			}
       
  3104 		}
       
  3105 
       
  3106 		$data_to_export[] = array(
       
  3107 			'group_id'          => 'community-events-location',
       
  3108 			'group_label'       => __( 'Community Events Location' ),
       
  3109 			'group_description' => __( 'User&#8217;s location data used for the Community Events in the WordPress Events and News dashboard widget.' ),
       
  3110 			'item_id'           => "community-events-location-{$user->ID}",
       
  3111 			'data'              => $location_data_to_export,
       
  3112 		);
       
  3113 	}
       
  3114 
       
  3115 	if ( isset( $user_meta['session_tokens'] ) ) {
       
  3116 		$session_tokens = maybe_unserialize( $user_meta['session_tokens'][0] );
       
  3117 
       
  3118 		$session_tokens_props_to_export = array(
       
  3119 			'expiration' => __( 'Expiration' ),
       
  3120 			'ip'         => __( 'IP' ),
       
  3121 			'ua'         => __( 'User Agent' ),
       
  3122 			'login'      => __( 'Last Login' ),
       
  3123 		);
       
  3124 
       
  3125 		foreach ( $session_tokens as $token_key => $session_token ) {
       
  3126 			$session_tokens_data_to_export = array();
       
  3127 
       
  3128 			foreach ( $session_tokens_props_to_export as $key => $name ) {
       
  3129 				if ( ! empty( $session_token[ $key ] ) ) {
       
  3130 					$value = $session_token[ $key ];
       
  3131 					if ( in_array( $key, array( 'expiration', 'login' ), true ) ) {
       
  3132 						$value = date_i18n( 'F d, Y H:i A', $value );
       
  3133 					}
       
  3134 					$session_tokens_data_to_export[] = array(
       
  3135 						'name'  => $name,
       
  3136 						'value' => $value,
       
  3137 					);
       
  3138 				}
       
  3139 			}
       
  3140 
       
  3141 			$data_to_export[] = array(
       
  3142 				'group_id'          => 'session-tokens',
       
  3143 				'group_label'       => __( 'Session Tokens' ),
       
  3144 				'group_description' => __( 'User&#8217;s Session Tokens data.' ),
       
  3145 				'item_id'           => "session-tokens-{$user->ID}-{$token_key}",
       
  3146 				'data'              => $session_tokens_data_to_export,
       
  3147 			);
       
  3148 		}
       
  3149 	}
  2947 
  3150 
  2948 	return array(
  3151 	return array(
  2949 		'data' => $data_to_export,
  3152 		'data' => $data_to_export,
  2950 		'done' => true,
  3153 		'done' => true,
  2951 	);
  3154 	);
  2958  * @access private
  3161  * @access private
  2959  *
  3162  *
  2960  * @param int $request_id ID of the request.
  3163  * @param int $request_id ID of the request.
  2961  */
  3164  */
  2962 function _wp_privacy_account_request_confirmed( $request_id ) {
  3165 function _wp_privacy_account_request_confirmed( $request_id ) {
  2963 	$request = wp_get_user_request_data( $request_id );
  3166 	$request = wp_get_user_request( $request_id );
  2964 
  3167 
  2965 	if ( ! $request ) {
  3168 	if ( ! $request ) {
  2966 		return;
  3169 		return;
  2967 	}
  3170 	}
  2968 
  3171 
  2988  * @since 4.9.6
  3191  * @since 4.9.6
  2989  *
  3192  *
  2990  * @param int $request_id The ID of the request.
  3193  * @param int $request_id The ID of the request.
  2991  */
  3194  */
  2992 function _wp_privacy_send_request_confirmation_notification( $request_id ) {
  3195 function _wp_privacy_send_request_confirmation_notification( $request_id ) {
  2993 	$request = wp_get_user_request_data( $request_id );
  3196 	$request = wp_get_user_request( $request_id );
  2994 
  3197 
  2995 	if ( ! is_a( $request, 'WP_User_Request' ) || 'request-confirmed' !== $request->status ) {
  3198 	if ( ! is_a( $request, 'WP_User_Request' ) || 'request-confirmed' !== $request->status ) {
  2996 		return;
  3199 		return;
  2997 	}
  3200 	}
  2998 
  3201 
  3000 
  3203 
  3001 	if ( $already_notified ) {
  3204 	if ( $already_notified ) {
  3002 		return;
  3205 		return;
  3003 	}
  3206 	}
  3004 
  3207 
  3005 	$manage_url         = add_query_arg( 'page', $request->action_name, admin_url( 'tools.php' ) );
  3208 	if ( 'export_personal_data' === $request->action_name ) {
       
  3209 		$manage_url = admin_url( 'export-personal-data.php' );
       
  3210 	} elseif ( 'remove_personal_data' === $request->action_name ) {
       
  3211 		$manage_url = admin_url( 'erase-personal-data.php' );
       
  3212 	}
  3006 	$action_description = wp_user_request_action_description( $request->action_name );
  3213 	$action_description = wp_user_request_action_description( $request->action_name );
  3007 
  3214 
  3008 	/**
  3215 	/**
  3009 	 * Filters the recipient of the data request confirmation notification.
  3216 	 * Filters the recipient of the data request confirmation notification.
  3010 	 *
  3217 	 *
  3110 	 *     @type string          $admin_email The administrator email receiving the mail.
  3317 	 *     @type string          $admin_email The administrator email receiving the mail.
  3111 	 * }
  3318 	 * }
  3112 	 */
  3319 	 */
  3113 	$subject = apply_filters( 'user_request_confirmed_email_subject', $subject, $email_data['sitename'], $email_data );
  3320 	$subject = apply_filters( 'user_request_confirmed_email_subject', $subject, $email_data['sitename'], $email_data );
  3114 
  3321 
  3115 	$email_sent = wp_mail( $email_data['admin_email'], $subject, $content );
  3322 	$headers = '';
       
  3323 
       
  3324 	/**
       
  3325 	 * Filters the headers of the user request confirmation email.
       
  3326 	 *
       
  3327 	 * @since 5.4.0
       
  3328 	 *
       
  3329 	 * @param string|array $headers    The email headers.
       
  3330 	 * @param string       $subject    The email subject.
       
  3331 	 * @param string       $content    The email content.
       
  3332 	 * @param int          $request_id The request ID.
       
  3333 	 * @param array        $email_data {
       
  3334 	 *     Data relating to the account action email.
       
  3335 	 *
       
  3336 	 *     @type WP_User_Request $request     User request object.
       
  3337 	 *     @type string          $user_email  The email address confirming a request
       
  3338 	 *     @type string          $description Description of the action being performed so the user knows what the email is for.
       
  3339 	 *     @type string          $manage_url  The link to click manage privacy requests of this type.
       
  3340 	 *     @type string          $sitename    The site name sending the mail.
       
  3341 	 *     @type string          $siteurl     The site URL sending the mail.
       
  3342 	 *     @type string          $admin_email The administrator email receiving the mail.
       
  3343 	 * }
       
  3344 	 */
       
  3345 	$headers = apply_filters( 'user_request_confirmed_email_headers', $headers, $subject, $content, $request_id, $email_data );
       
  3346 
       
  3347 	$email_sent = wp_mail( $email_data['admin_email'], $subject, $content, $headers );
  3116 
  3348 
  3117 	if ( $email_sent ) {
  3349 	if ( $email_sent ) {
  3118 		update_post_meta( $request_id, '_wp_admin_notified', true );
  3350 		update_post_meta( $request_id, '_wp_admin_notified', true );
  3119 	}
  3351 	}
  3120 }
  3352 }
  3127  * @since 4.9.6
  3359  * @since 4.9.6
  3128  *
  3360  *
  3129  * @param int $request_id The privacy request post ID associated with this request.
  3361  * @param int $request_id The privacy request post ID associated with this request.
  3130  */
  3362  */
  3131 function _wp_privacy_send_erasure_fulfillment_notification( $request_id ) {
  3363 function _wp_privacy_send_erasure_fulfillment_notification( $request_id ) {
  3132 	$request = wp_get_user_request_data( $request_id );
  3364 	$request = wp_get_user_request( $request_id );
  3133 
  3365 
  3134 	if ( ! is_a( $request, 'WP_User_Request' ) || 'request-completed' !== $request->status ) {
  3366 	if ( ! is_a( $request, 'WP_User_Request' ) || 'request-completed' !== $request->status ) {
  3135 		return;
  3367 		return;
  3136 	}
  3368 	}
  3137 
  3369 
  3167 		'sitename'           => wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ),
  3399 		'sitename'           => wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ),
  3168 		'siteurl'            => home_url(),
  3400 		'siteurl'            => home_url(),
  3169 	);
  3401 	);
  3170 
  3402 
  3171 	$subject = sprintf(
  3403 	$subject = sprintf(
  3172 		/* translators: Erasure request fulfilled notification email subject. %s: Site name. */
  3404 		/* translators: Erasure request fulfilled notification email subject. %s: Site title. */
  3173 		__( '[%s] Erasure Request Fulfilled' ),
  3405 		__( '[%s] Erasure Request Fulfilled' ),
  3174 		$email_data['sitename']
  3406 		$email_data['sitename']
  3175 	);
  3407 	);
  3176 
  3408 
  3177 	/**
  3409 	/**
  3256 
  3488 
  3257 	$content = str_replace( '###SITENAME###', $email_data['sitename'], $content );
  3489 	$content = str_replace( '###SITENAME###', $email_data['sitename'], $content );
  3258 	$content = str_replace( '###PRIVACY_POLICY_URL###', $email_data['privacy_policy_url'], $content );
  3490 	$content = str_replace( '###PRIVACY_POLICY_URL###', $email_data['privacy_policy_url'], $content );
  3259 	$content = str_replace( '###SITEURL###', esc_url_raw( $email_data['siteurl'] ), $content );
  3491 	$content = str_replace( '###SITEURL###', esc_url_raw( $email_data['siteurl'] ), $content );
  3260 
  3492 
  3261 	$email_sent = wp_mail( $user_email, $subject, $content );
  3493 	$headers = '';
       
  3494 
       
  3495 	/**
       
  3496 	 * Filters the headers of the data erasure fulfillment notification.
       
  3497 	 *
       
  3498 	 * @since 5.4.0
       
  3499 	 *
       
  3500 	 * @param string|array $headers    The email headers.
       
  3501 	 * @param string       $subject    The email subject.
       
  3502 	 * @param string       $content    The email content.
       
  3503 	 * @param int          $request_id The request ID.
       
  3504 	 * @param array        $email_data {
       
  3505 	 *     Data relating to the account action email.
       
  3506 	 *
       
  3507 	 *     @type WP_User_Request $request            User request object.
       
  3508 	 *     @type string          $message_recipient  The address that the email will be sent to. Defaults
       
  3509 	 *                                               to the value of `$request->email`, but can be changed
       
  3510 	 *                                               by the `user_erasure_fulfillment_email_to` filter.
       
  3511 	 *     @type string          $privacy_policy_url Privacy policy URL.
       
  3512 	 *     @type string          $sitename           The site name sending the mail.
       
  3513 	 *     @type string          $siteurl            The site URL sending the mail.
       
  3514 	 * }
       
  3515 	 */
       
  3516 	$headers = apply_filters( 'user_erasure_complete_email_headers', $headers, $subject, $content, $request_id, $email_data );
       
  3517 
       
  3518 	$email_sent = wp_mail( $user_email, $subject, $content, $headers );
  3262 
  3519 
  3263 	if ( $switched_locale ) {
  3520 	if ( $switched_locale ) {
  3264 		restore_previous_locale();
  3521 		restore_previous_locale();
  3265 	}
  3522 	}
  3266 
  3523 
  3274  *
  3531  *
  3275  * @since 4.9.6
  3532  * @since 4.9.6
  3276  * @access private
  3533  * @access private
  3277  *
  3534  *
  3278  * @param int $request_id The request ID being confirmed.
  3535  * @param int $request_id The request ID being confirmed.
  3279  * @return string $message The confirmation message.
  3536  * @return string The confirmation message.
  3280  */
  3537  */
  3281 function _wp_privacy_account_request_confirmed_message( $request_id ) {
  3538 function _wp_privacy_account_request_confirmed_message( $request_id ) {
  3282 	$request = wp_get_user_request_data( $request_id );
  3539 	$request = wp_get_user_request( $request_id );
  3283 
  3540 
  3284 	$message  = '<p class="success">' . __( 'Action has been confirmed.' ) . '</p>';
  3541 	$message  = '<p class="success">' . __( 'Action has been confirmed.' ) . '</p>';
  3285 	$message .= '<p>' . __( 'The site administrator has been notified and will fulfill your request as soon as possible.' ) . '</p>';
  3542 	$message .= '<p>' . __( 'The site administrator has been notified and will fulfill your request as soon as possible.' ) . '</p>';
  3286 
  3543 
  3287 	if ( $request && in_array( $request->action_name, _wp_privacy_action_request_types(), true ) ) {
  3544 	if ( $request && in_array( $request->action_name, _wp_privacy_action_request_types(), true ) ) {
  3337 
  3594 
  3338 	// Check for duplicates.
  3595 	// Check for duplicates.
  3339 	$requests_query = new WP_Query(
  3596 	$requests_query = new WP_Query(
  3340 		array(
  3597 		array(
  3341 			'post_type'     => 'user_request',
  3598 			'post_type'     => 'user_request',
  3342 			'post_name__in' => array( $action_name ),  // Action name stored in post_name column.
  3599 			'post_name__in' => array( $action_name ), // Action name stored in post_name column.
  3343 			'title'         => $email_address, // Email address stored in post_title column.
  3600 			'title'         => $email_address,        // Email address stored in post_title column.
  3344 			'post_status'   => array(
  3601 			'post_status'   => array(
  3345 				'request-pending',
  3602 				'request-pending',
  3346 				'request-confirmed',
  3603 				'request-confirmed',
  3347 			),
  3604 			),
  3348 			'fields'        => 'ids',
  3605 			'fields'        => 'ids',
  3385 			break;
  3642 			break;
  3386 		case 'remove_personal_data':
  3643 		case 'remove_personal_data':
  3387 			$description = __( 'Erase Personal Data' );
  3644 			$description = __( 'Erase Personal Data' );
  3388 			break;
  3645 			break;
  3389 		default:
  3646 		default:
  3390 			/* translators: %s: action name */
  3647 			/* translators: %s: Action name. */
  3391 			$description = sprintf( __( 'Confirm the "%s" action' ), $action_name );
  3648 			$description = sprintf( __( 'Confirm the "%s" action' ), $action_name );
  3392 			break;
  3649 			break;
  3393 	}
  3650 	}
  3394 
  3651 
  3395 	/**
  3652 	/**
  3413  * @param string $request_id ID of the request created via wp_create_user_request().
  3670  * @param string $request_id ID of the request created via wp_create_user_request().
  3414  * @return bool|WP_Error True on success, `WP_Error` on failure.
  3671  * @return bool|WP_Error True on success, `WP_Error` on failure.
  3415  */
  3672  */
  3416 function wp_send_user_request( $request_id ) {
  3673 function wp_send_user_request( $request_id ) {
  3417 	$request_id = absint( $request_id );
  3674 	$request_id = absint( $request_id );
  3418 	$request    = wp_get_user_request_data( $request_id );
  3675 	$request    = wp_get_user_request( $request_id );
  3419 
  3676 
  3420 	if ( ! $request ) {
  3677 	if ( ! $request ) {
  3421 		return new WP_Error( 'invalid_request', __( 'Invalid user request.' ) );
  3678 		return new WP_Error( 'invalid_request', __( 'Invalid user request.' ) );
  3422 	}
  3679 	}
  3423 
  3680 
  3495 	$content = str_replace( '###CONFIRM_URL###', esc_url_raw( $email_data['confirm_url'] ), $content );
  3752 	$content = str_replace( '###CONFIRM_URL###', esc_url_raw( $email_data['confirm_url'] ), $content );
  3496 	$content = str_replace( '###EMAIL###', $email_data['email'], $content );
  3753 	$content = str_replace( '###EMAIL###', $email_data['email'], $content );
  3497 	$content = str_replace( '###SITENAME###', $email_data['sitename'], $content );
  3754 	$content = str_replace( '###SITENAME###', $email_data['sitename'], $content );
  3498 	$content = str_replace( '###SITEURL###', esc_url_raw( $email_data['siteurl'] ), $content );
  3755 	$content = str_replace( '###SITEURL###', esc_url_raw( $email_data['siteurl'] ), $content );
  3499 
  3756 
  3500 	/* translators: Confirm privacy data request notification email subject. 1: Site title, 2: Name of the action */
  3757 	/* translators: Confirm privacy data request notification email subject. 1: Site title, 2: Name of the action. */
  3501 	$subject = sprintf( __( '[%1$s] Confirm Action: %2$s' ), $email_data['sitename'], $email_data['description'] );
  3758 	$subject = sprintf( __( '[%1$s] Confirm Action: %2$s' ), $email_data['sitename'], $email_data['description'] );
  3502 
  3759 
  3503 	/**
  3760 	/**
  3504 	 * Filters the subject of the email sent when an account action is attempted.
  3761 	 * Filters the subject of the email sent when an account action is attempted.
  3505 	 *
  3762 	 *
  3518 	 *     @type string          $siteurl     The site URL sending the mail.
  3775 	 *     @type string          $siteurl     The site URL sending the mail.
  3519 	 * }
  3776 	 * }
  3520 	 */
  3777 	 */
  3521 	$subject = apply_filters( 'user_request_action_email_subject', $subject, $email_data['sitename'], $email_data );
  3778 	$subject = apply_filters( 'user_request_action_email_subject', $subject, $email_data['sitename'], $email_data );
  3522 
  3779 
  3523 	$email_sent = wp_mail( $email_data['email'], $subject, $content );
  3780 	$headers = '';
       
  3781 
       
  3782 	/**
       
  3783 	 * Filters the headers of the email sent when an account action is attempted.
       
  3784 	 *
       
  3785 	 * @since 5.4.0
       
  3786 	 *
       
  3787 	 * @param string|array $headers    The email headers.
       
  3788 	 * @param string       $subject    The email subject.
       
  3789 	 * @param string       $content    The email content.
       
  3790 	 * @param int          $request_id The request ID.
       
  3791 	 * @param array        $email_data {
       
  3792 	 *     Data relating to the account action email.
       
  3793 	 *
       
  3794 	 *     @type WP_User_Request $request     User request object.
       
  3795 	 *     @type string          $email       The email address this is being sent to.
       
  3796 	 *     @type string          $description Description of the action being performed so the user knows what the email is for.
       
  3797 	 *     @type string          $confirm_url The link to click on to confirm the account action.
       
  3798 	 *     @type string          $sitename    The site name sending the mail.
       
  3799 	 *     @type string          $siteurl     The site URL sending the mail.
       
  3800 	 * }
       
  3801 	 */
       
  3802 	$headers = apply_filters( 'user_request_action_email_headers', $headers, $subject, $content, $request_id, $email_data );
       
  3803 
       
  3804 	$email_sent = wp_mail( $email_data['email'], $subject, $content, $headers );
  3524 
  3805 
  3525 	if ( $switched_locale ) {
  3806 	if ( $switched_locale ) {
  3526 		restore_previous_locale();
  3807 		restore_previous_locale();
  3527 	}
  3808 	}
  3528 
  3809 
  3569  *
  3850  *
  3570  * @since 4.9.6
  3851  * @since 4.9.6
  3571  *
  3852  *
  3572  * @param string $request_id ID of the request being confirmed.
  3853  * @param string $request_id ID of the request being confirmed.
  3573  * @param string $key        Provided key to validate.
  3854  * @param string $key        Provided key to validate.
  3574  * @return bool|WP_Error WP_Error on failure, true on success.
  3855  * @return bool|WP_Error True on success, WP_Error on failure.
  3575  */
  3856  */
  3576 function wp_validate_user_request_key( $request_id, $key ) {
  3857 function wp_validate_user_request_key( $request_id, $key ) {
  3577 	global $wp_hasher;
  3858 	global $wp_hasher;
  3578 
  3859 
  3579 	$request_id = absint( $request_id );
  3860 	$request_id = absint( $request_id );
  3580 	$request    = wp_get_user_request_data( $request_id );
  3861 	$request    = wp_get_user_request( $request_id );
  3581 
  3862 
  3582 	if ( ! $request ) {
  3863 	if ( ! $request ) {
  3583 		return new WP_Error( 'invalid_request', __( 'Invalid request.' ) );
  3864 		return new WP_Error( 'invalid_request', __( 'Invalid request.' ) );
  3584 	}
  3865 	}
  3585 
  3866 
  3627 
  3908 
  3628 	return true;
  3909 	return true;
  3629 }
  3910 }
  3630 
  3911 
  3631 /**
  3912 /**
  3632  * Return data about a user request.
  3913  * Return the user request object for the specified request ID.
  3633  *
  3914  *
  3634  * @since 4.9.6
  3915  * @since 4.9.6
  3635  *
  3916  *
  3636  * @param int $request_id Request ID to get data about.
  3917  * @param int $request_id The ID of the user request.
  3637  * @return WP_User_Request|false
  3918  * @return WP_User_Request|false
  3638  */
  3919  */
  3639 function wp_get_user_request_data( $request_id ) {
  3920 function wp_get_user_request( $request_id ) {
  3640 	$request_id = absint( $request_id );
  3921 	$request_id = absint( $request_id );
  3641 	$post       = get_post( $request_id );
  3922 	$post       = get_post( $request_id );
  3642 
  3923 
  3643 	if ( ! $post || 'user_request' !== $post->post_type ) {
  3924 	if ( ! $post || 'user_request' !== $post->post_type ) {
  3644 		return false;
  3925 		return false;
  3645 	}
  3926 	}
  3646 
  3927 
  3647 	return new WP_User_Request( $post );
  3928 	return new WP_User_Request( $post );
  3648 }
  3929 }
  3649 
       
  3650 /**
       
  3651  * WP_User_Request class.
       
  3652  *
       
  3653  * Represents user request data loaded from a WP_Post object.
       
  3654  *
       
  3655  * @since 4.9.6
       
  3656  */
       
  3657 final class WP_User_Request {
       
  3658 	/**
       
  3659 	 * Request ID.
       
  3660 	 *
       
  3661 	 * @var int
       
  3662 	 */
       
  3663 	public $ID = 0;
       
  3664 
       
  3665 	/**
       
  3666 	 * User ID.
       
  3667 	 *
       
  3668 	 * @var int
       
  3669 	 */
       
  3670 	public $user_id = 0;
       
  3671 
       
  3672 	/**
       
  3673 	 * User email.
       
  3674 	 *
       
  3675 	 * @var int
       
  3676 	 */
       
  3677 	public $email = '';
       
  3678 
       
  3679 	/**
       
  3680 	 * Action name.
       
  3681 	 *
       
  3682 	 * @var string
       
  3683 	 */
       
  3684 	public $action_name = '';
       
  3685 
       
  3686 	/**
       
  3687 	 * Current status.
       
  3688 	 *
       
  3689 	 * @var string
       
  3690 	 */
       
  3691 	public $status = '';
       
  3692 
       
  3693 	/**
       
  3694 	 * Timestamp this request was created.
       
  3695 	 *
       
  3696 	 * @var int|null
       
  3697 	 */
       
  3698 	public $created_timestamp = null;
       
  3699 
       
  3700 	/**
       
  3701 	 * Timestamp this request was last modified.
       
  3702 	 *
       
  3703 	 * @var int|null
       
  3704 	 */
       
  3705 	public $modified_timestamp = null;
       
  3706 
       
  3707 	/**
       
  3708 	 * Timestamp this request was confirmed.
       
  3709 	 *
       
  3710 	 * @var int
       
  3711 	 */
       
  3712 	public $confirmed_timestamp = null;
       
  3713 
       
  3714 	/**
       
  3715 	 * Timestamp this request was completed.
       
  3716 	 *
       
  3717 	 * @var int
       
  3718 	 */
       
  3719 	public $completed_timestamp = null;
       
  3720 
       
  3721 	/**
       
  3722 	 * Misc data assigned to this request.
       
  3723 	 *
       
  3724 	 * @var array
       
  3725 	 */
       
  3726 	public $request_data = array();
       
  3727 
       
  3728 	/**
       
  3729 	 * Key used to confirm this request.
       
  3730 	 *
       
  3731 	 * @var string
       
  3732 	 */
       
  3733 	public $confirm_key = '';
       
  3734 
       
  3735 	/**
       
  3736 	 * Constructor.
       
  3737 	 *
       
  3738 	 * @since 4.9.6
       
  3739 	 *
       
  3740 	 * @param WP_Post|object $post Post object.
       
  3741 	 */
       
  3742 	public function __construct( $post ) {
       
  3743 		$this->ID                  = $post->ID;
       
  3744 		$this->user_id             = $post->post_author;
       
  3745 		$this->email               = $post->post_title;
       
  3746 		$this->action_name         = $post->post_name;
       
  3747 		$this->status              = $post->post_status;
       
  3748 		$this->created_timestamp   = strtotime( $post->post_date_gmt );
       
  3749 		$this->modified_timestamp  = strtotime( $post->post_modified_gmt );
       
  3750 		$this->confirmed_timestamp = (int) get_post_meta( $post->ID, '_wp_user_request_confirmed_timestamp', true );
       
  3751 		$this->completed_timestamp = (int) get_post_meta( $post->ID, '_wp_user_request_completed_timestamp', true );
       
  3752 		$this->request_data        = json_decode( $post->post_content, true );
       
  3753 		$this->confirm_key         = $post->post_password;
       
  3754 	}
       
  3755 }