wp_update_user( array|object|WP_User $userdata ): int|WP_Error

Updates a user in the database.

Description

It is possible to update a user’s password by specifying the ‘user_pass’ value in the $userdata parameter array.

If current user’s password is being updated, then the cookies will be cleared.

See also

Parameters

$userdataarray|object|WP_Userrequired
An array of user data or a user object of type stdClass or WP_User.

Return

int|WP_Error The updated user’s ID or a WP_Error object if the user could not be updated.

Source

function wp_update_user( $userdata ) {
	if ( $userdata instanceof stdClass ) {
		$userdata = get_object_vars( $userdata );
	} elseif ( $userdata instanceof WP_User ) {
		$userdata = $userdata->to_array();
	}

	$userdata_raw = $userdata;

	$user_id = isset( $userdata['ID'] ) ? (int) $userdata['ID'] : 0;
	if ( ! $user_id ) {
		return new WP_Error( 'invalid_user_id', __( 'Invalid user ID.' ) );
	}

	// First, get all of the original fields.
	$user_obj = get_userdata( $user_id );
	if ( ! $user_obj ) {
		return new WP_Error( 'invalid_user_id', __( 'Invalid user ID.' ) );
	}

	$user = $user_obj->to_array();

	// Add additional custom fields.
	foreach ( _get_additional_user_keys( $user_obj ) as $key ) {
		$user[ $key ] = get_user_meta( $user_id, $key, true );
	}

	// Escape data pulled from DB.
	$user = add_magic_quotes( $user );

	if ( ! empty( $userdata['user_pass'] ) && $userdata['user_pass'] !== $user_obj->user_pass ) {
		// If password is changing, hash it now.
		$plaintext_pass        = $userdata['user_pass'];
		$userdata['user_pass'] = wp_hash_password( $userdata['user_pass'] );

		/**
		 * Filters whether to send the password change email.
		 *
		 * @since 4.3.0
		 *
		 * @see wp_insert_user() For `$user` and `$userdata` fields.
		 *
		 * @param bool  $send     Whether to send the email.
		 * @param array $user     The original user array.
		 * @param array $userdata The updated user array.
		 */
		$send_password_change_email = apply_filters( 'send_password_change_email', true, $user, $userdata );
	}

	if ( isset( $userdata['user_email'] ) && $user['user_email'] !== $userdata['user_email'] ) {
		/**
		 * Filters whether to send the email change email.
		 *
		 * @since 4.3.0
		 *
		 * @see wp_insert_user() For `$user` and `$userdata` fields.
		 *
		 * @param bool  $send     Whether to send the email.
		 * @param array $user     The original user array.
		 * @param array $userdata The updated user array.
		 */
		$send_email_change_email = apply_filters( 'send_email_change_email', true, $user, $userdata );
	}

	clean_user_cache( $user_obj );

	// Merge old and new fields with new fields overwriting old ones.
	$userdata = array_merge( $user, $userdata );
	$user_id  = wp_insert_user( $userdata );

	if ( is_wp_error( $user_id ) ) {
		return $user_id;
	}

	$blog_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );

	$switched_locale = false;
	if ( ! empty( $send_password_change_email ) || ! empty( $send_email_change_email ) ) {
		$switched_locale = switch_to_user_locale( $user_id );
	}

	if ( ! empty( $send_password_change_email ) ) {
		/* translators: Do not translate USERNAME, ADMIN_EMAIL, EMAIL, SITENAME, SITEURL: those are placeholders. */
		$pass_change_text = __(
			'Hi ###USERNAME###,

This notice confirms that your password was changed on ###SITENAME###.

If you did not change your password, please contact the Site Administrator at
###ADMIN_EMAIL###

This email has been sent to ###EMAIL###

Regards,
All at ###SITENAME###
###SITEURL###'
		);

		$pass_change_email = array(
			'to'      => $user['user_email'],
			/* translators: Password change notification email subject. %s: Site title. */
			'subject' => __( '[%s] Password Changed' ),
			'message' => $pass_change_text,
			'headers' => '',
		);

		/**
		 * Filters the contents of the email sent when the user's password is changed.
		 *
		 * @since 4.3.0
		 *
		 * @param array $pass_change_email {
		 *     Used to build wp_mail().
		 *
		 *     @type string $to      The intended recipients. Add emails in a comma separated string.
		 *     @type string $subject The subject of the email.
		 *     @type string $message The content of the email.
		 *         The following strings have a special meaning and will get replaced dynamically:
		 *         - ###USERNAME###    The current user's username.
		 *         - ###ADMIN_EMAIL### The admin email in case this was unexpected.
		 *         - ###EMAIL###       The user's email address.
		 *         - ###SITENAME###    The name of the site.
		 *         - ###SITEURL###     The URL to the site.
		 *     @type string $headers Headers. Add headers in a newline (\r\n) separated string.
		 * }
		 * @param array $user     The original user array.
		 * @param array $userdata The updated user array.
		 */
		$pass_change_email = apply_filters( 'password_change_email', $pass_change_email, $user, $userdata );

		$pass_change_email['message'] = str_replace( '###USERNAME###', $user['user_login'], $pass_change_email['message'] );
		$pass_change_email['message'] = str_replace( '###ADMIN_EMAIL###', get_option( 'admin_email' ), $pass_change_email['message'] );
		$pass_change_email['message'] = str_replace( '###EMAIL###', $user['user_email'], $pass_change_email['message'] );
		$pass_change_email['message'] = str_replace( '###SITENAME###', $blog_name, $pass_change_email['message'] );
		$pass_change_email['message'] = str_replace( '###SITEURL###', home_url(), $pass_change_email['message'] );

		wp_mail( $pass_change_email['to'], sprintf( $pass_change_email['subject'], $blog_name ), $pass_change_email['message'], $pass_change_email['headers'] );
	}

	if ( ! empty( $send_email_change_email ) ) {
		/* translators: Do not translate USERNAME, ADMIN_EMAIL, NEW_EMAIL, EMAIL, SITENAME, SITEURL: those are placeholders. */
		$email_change_text = __(
			'Hi ###USERNAME###,

This notice confirms that your email address on ###SITENAME### was changed to ###NEW_EMAIL###.

If you did not change your email, please contact the Site Administrator at
###ADMIN_EMAIL###

This email has been sent to ###EMAIL###

Regards,
All at ###SITENAME###
###SITEURL###'
		);

		$email_change_email = array(
			'to'      => $user['user_email'],
			/* translators: Email change notification email subject. %s: Site title. */
			'subject' => __( '[%s] Email Changed' ),
			'message' => $email_change_text,
			'headers' => '',
		);

		/**
		 * Filters the contents of the email sent when the user's email is changed.
		 *
		 * @since 4.3.0
		 *
		 * @param array $email_change_email {
		 *     Used to build wp_mail().
		 *
		 *     @type string $to      The intended recipients.
		 *     @type string $subject The subject of the email.
		 *     @type string $message The content of the email.
		 *         The following strings have a special meaning and will get replaced dynamically:
		 *         - ###USERNAME###    The current user's username.
		 *         - ###ADMIN_EMAIL### The admin email in case this was unexpected.
		 *         - ###NEW_EMAIL###   The new email address.
		 *         - ###EMAIL###       The old email address.
		 *         - ###SITENAME###    The name of the site.
		 *         - ###SITEURL###     The URL to the site.
		 *     @type string $headers Headers.
		 * }
		 * @param array $user     The original user array.
		 * @param array $userdata The updated user array.
		 */
		$email_change_email = apply_filters( 'email_change_email', $email_change_email, $user, $userdata );

		$email_change_email['message'] = str_replace( '###USERNAME###', $user['user_login'], $email_change_email['message'] );
		$email_change_email['message'] = str_replace( '###ADMIN_EMAIL###', get_option( 'admin_email' ), $email_change_email['message'] );
		$email_change_email['message'] = str_replace( '###NEW_EMAIL###', $userdata['user_email'], $email_change_email['message'] );
		$email_change_email['message'] = str_replace( '###EMAIL###', $user['user_email'], $email_change_email['message'] );
		$email_change_email['message'] = str_replace( '###SITENAME###', $blog_name, $email_change_email['message'] );
		$email_change_email['message'] = str_replace( '###SITEURL###', home_url(), $email_change_email['message'] );

		wp_mail( $email_change_email['to'], sprintf( $email_change_email['subject'], $blog_name ), $email_change_email['message'], $email_change_email['headers'] );
	}

	if ( $switched_locale ) {
		restore_previous_locale();
	}

	// Update the cookies if the password changed.
	$current_user = wp_get_current_user();
	if ( $current_user->ID === $user_id ) {
		if ( isset( $plaintext_pass ) ) {
			wp_clear_auth_cookie();

			/*
			 * Here we calculate the expiration length of the current auth cookie and compare it to the default expiration.
			 * If it's greater than this, then we know the user checked 'Remember Me' when they logged in.
			 */
			$logged_in_cookie = wp_parse_auth_cookie( '', 'logged_in' );
			/** This filter is documented in wp-includes/pluggable.php */
			$default_cookie_life = apply_filters( 'auth_cookie_expiration', ( 2 * DAY_IN_SECONDS ), $user_id, false );

			$remember = false;

			if ( false !== $logged_in_cookie && ( $logged_in_cookie['expiration'] - time() ) > $default_cookie_life ) {
				$remember = true;
			}

			wp_set_auth_cookie( $user_id, $remember );
		}
	}

	/**
	 * Fires after the user has been updated and emails have been sent.
	 *
	 * @since 6.3.0
	 *
	 * @param int   $user_id      The ID of the user that was just updated.
	 * @param array $userdata     The array of user data that was updated.
	 * @param array $userdata_raw The unedited array of user data that was updated.
	 */
	do_action( 'wp_update_user', $user_id, $userdata, $userdata_raw );

	return $user_id;
}

Hooks

apply_filters( ‘auth_cookie_expiration’, int $length, int $user_id, bool $remember )

Filters the duration of the authentication cookie expiration period.

apply_filters( ’email_change_email’, array $email_change_email, array $user, array $userdata )

Filters the contents of the email sent when the user’s email is changed.

apply_filters( ‘password_change_email’, array $pass_change_email, array $user, array $userdata )

Filters the contents of the email sent when the user’s password is changed.

apply_filters( ‘send_email_change_email’, bool $send, array $user, array $userdata )

Filters whether to send the email change email.

apply_filters( ‘send_password_change_email’, bool $send, array $user, array $userdata )

Filters whether to send the password change email.

do_action( ‘wp_update_user’, int $user_id, array $userdata, array $userdata_raw )

Fires after the user has been updated and emails have been sent.

Changelog

VersionDescription
2.0.0Introduced.

User Contributed Notes

  1. Skip to note 5 content

    Example showing how to update a user’s website profile field:

    <?php
    $user_id = 6;
    $website = 'http://example.com';
    
    $user_data = wp_update_user( array( 'ID' => $user_id, 'user_url' => $website ) );
    
    if ( is_wp_error( $user_data ) ) {
    	// There was an error; possibly this user doesn't exist.
    	echo 'Error.';
    } else {
    	// Success!
    	echo 'User profile updated.';
    }
    ?>
  2. Skip to note 6 content

    “If current user’s password is being updated, then the cookies will be cleared.” AND AN EMAIL WILL BE SEND !!!
    It sent an email to 50 users !!! Be more explicit !

  3. Skip to note 8 content

    An example showing how to update a user_meta field (for example, ‘wpdocs_free_offers_left’) with a WP_User object.

    $user = wp_get_current_user();
    
    $free_offers = $user->free_offers_left;
    update_user_meta( $user->ID, 'wpdocs_free_offers_left', $free_offers-- );
    
    $update = wp_update_user( $user );
    
    if ( is_int( $update ) ) {
      // Success
      echo "Update done";
    } else { // is WP_error
      echo "Update failed";
    }

You must log in before being able to contribute a note or feedback.