* @since 4.6.0 The `$notify` parameter accepts 'user' for sending notification only to the user created.
* @param int $user_id User ID.
* @param null $deprecated Not used (argument deprecated).
* @param string $notify Optional. Type of notification that should happen. Accepts 'admin' or an empty
* string (admin only), 'user', or 'both' (admin and user). Default empty.
function wp_new_user_notification( $user_id, $deprecated = null, $notify = '' ) {
if ( null !== $deprecated ) {
_deprecated_argument( __FUNCTION__, '4.3.1' );
// Accepts only 'user', 'admin' , 'both' or default '' as $notify.
if ( ! in_array( $notify, array( 'user', 'admin', 'both', '' ), true ) ) {
$user = get_userdata( $user_id );
// The blogname option is escaped with esc_html() on the way into the database in sanitize_option().
// We want to reverse this for the plain text arena of emails.
$blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
if ( 'user' !== $notify ) {
$switched_locale = switch_to_locale( get_locale() );
/* translators: %s: Site title. */
$message = sprintf( __( 'New user registration on your site %s:' ), $blogname ) . "\r\n\r\n";
/* translators: %s: User login. */
$message .= sprintf( __( 'Username: %s' ), $user->user_login ) . "\r\n\r\n";
/* translators: %s: User email address. */
$message .= sprintf( __( 'Email: %s' ), $user->user_email ) . "\r\n";
$wp_new_user_notification_email_admin = array(
'to' => get_option( 'admin_email' ),
/* translators: New user registration notification email subject. %s: Site title. */
'subject' => __( '[%s] New User Registration' ),
* Filters the contents of the new user notification email sent to the site admin.
* @param array $wp_new_user_notification_email_admin {
* Used to build wp_mail().
* @type string $to The intended recipient - site admin email address.
* @type string $subject The subject of the email.
* @type string $message The body of the email.
* @type string $headers The headers of the email.
* @param WP_User $user User object for new user.
* @param string $blogname The site title.
$wp_new_user_notification_email_admin = apply_filters( 'wp_new_user_notification_email_admin', $wp_new_user_notification_email_admin, $user, $blogname );
$wp_new_user_notification_email_admin['to'],
wp_specialchars_decode( sprintf( $wp_new_user_notification_email_admin['subject'], $blogname ) ),
$wp_new_user_notification_email_admin['message'],
$wp_new_user_notification_email_admin['headers']
if ( $switched_locale ) {
restore_previous_locale();
// `$deprecated` was pre-4.3 `$plaintext_pass`. An empty `$plaintext_pass` didn't sent a user notification.
if ( 'admin' === $notify || ( empty( $deprecated ) && empty( $notify ) ) ) {
$key = get_password_reset_key( $user );
if ( is_wp_error( $key ) ) {
$switched_locale = switch_to_locale( get_user_locale( $user ) );
/* translators: %s: User login. */
$message = sprintf( __( 'Username: %s' ), $user->user_login ) . "\r\n\r\n";
$message .= __( 'To set your password, visit the following address:' ) . "\r\n\r\n";
$message .= network_site_url( "wp-login.php?action=rp&key=$key&login=" . rawurlencode( $user->user_login ), 'login' ) . "\r\n\r\n";
$message .= wp_login_url() . "\r\n";
$wp_new_user_notification_email = array(
'to' => $user->user_email,
/* translators: Login details notification email subject. %s: Site title. */
'subject' => __( '[%s] Login Details' ),
* Filters the contents of the new user notification email sent to the new user.
* @param array $wp_new_user_notification_email {
* Used to build wp_mail().
* @type string $to The intended recipient - New user email address.
* @type string $subject The subject of the email.
* @type string $message The body of the email.
* @type string $headers The headers of the email.
* @param WP_User $user User object for new user.
* @param string $blogname The site title.
$wp_new_user_notification_email = apply_filters( 'wp_new_user_notification_email', $wp_new_user_notification_email, $user, $blogname );
$wp_new_user_notification_email['to'],
wp_specialchars_decode( sprintf( $wp_new_user_notification_email['subject'], $blogname ) ),
$wp_new_user_notification_email['message'],
$wp_new_user_notification_email['headers']
if ( $switched_locale ) {
restore_previous_locale();
if ( ! function_exists( 'wp_nonce_tick' ) ) :
* Returns the time-dependent variable for nonce creation.
* A nonce has a lifespan of two ticks. Nonces in their second tick may be
* updated, e.g. by autosave.
* @return float Float value rounded up to the next highest integer.
function wp_nonce_tick() {
* Filters the lifespan of nonces in seconds.
* @param int $lifespan Lifespan of nonces in seconds. Default 86,400 seconds, or one day.
$nonce_life = apply_filters( 'nonce_life', DAY_IN_SECONDS );
return ceil( time() / ( $nonce_life / 2 ) );
if ( ! function_exists( 'wp_verify_nonce' ) ) :
* Verifies that a correct security nonce was used with time limit.
* A nonce is valid for 24 hours (by default).
* @param string $nonce Nonce value that was used for verification, usually via a form field.
* @param string|int $action Should give context to what is taking place and be the same when nonce was created.
* @return int|false 1 if the nonce is valid and generated between 0-12 hours ago,
* 2 if the nonce is valid and generated between 12-24 hours ago.
* False if the nonce is invalid.
function wp_verify_nonce( $nonce, $action = -1 ) {
$nonce = (string) $nonce;
$user = wp_get_current_user();
* Filters whether the user who generated the nonce is logged out.
* @param int $uid ID of the nonce-owning user.
* @param string $action The nonce action.
$uid = apply_filters( 'nonce_user_logged_out', $uid, $action );
$token = wp_get_session_token();
// Nonce generated 0-12 hours ago.
$expected = substr( wp_hash( $i . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), -12, 10 );
if ( hash_equals( $expected, $nonce ) ) {
// Nonce generated 12-24 hours ago.
$expected = substr( wp_hash( ( $i - 1 ) . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), -12, 10 );
if ( hash_equals( $expected, $nonce ) ) {
* Fires when nonce verification fails.
* @param string $nonce The invalid nonce.
* @param string|int $action The nonce action.
* @param WP_User $user The current user object.
* @param string $token The user's session token.
do_action( 'wp_verify_nonce_failed', $nonce, $action, $user, $token );
if ( ! function_exists( 'wp_create_nonce' ) ) :
* Creates a cryptographic token tied to a specific action, user, user session,
* @since 4.0.0 Session tokens were integrated with nonce creation
* @param string|int $action Scalar value to add context to the nonce.
* @return string The token.
function wp_create_nonce( $action = -1 ) {
$user = wp_get_current_user();
/** This filter is documented in wp-includes/pluggable.php */
$uid = apply_filters( 'nonce_user_logged_out', $uid, $action );
$token = wp_get_session_token();
return substr( wp_hash( $i . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), -12, 10 );
if ( ! function_exists( 'wp_salt' ) ) :
* Returns a salt to add to hashes.
* Salts are created using secret keys. Secret keys are located in two places:
* in the database and in the wp-config.php file. The secret key in the database
* is randomly generated and will be appended to the secret keys in wp-config.php.
* The secret keys in wp-config.php should be updated to strong, random keys to maximize
* security. Below is an example of how the secret key constants are defined.
* Do not paste this example directly into wp-config.php. Instead, have a
* {@link https://api.wordpress.org/secret-key/1.1/salt/ secret key created} just
* define('AUTH_KEY', ' Xakm<o xQy rw4EMsLKM-?!T+,PFF})H4lzcW57AF0U@N@< >M%G4Yt>f`z]MON');
* define('SECURE_AUTH_KEY', 'LzJ}op]mr|6+![P}Ak:uNdJCJZd>(Hx.-Mh#Tz)pCIU#uGEnfFz|f ;;eU%/U^O~');
* define('LOGGED_IN_KEY', '|i|Ux`9<p-h$aFf(qnT:sDO:D1P^wZ$$/Ra@miTJi9G;ddp_<q}6H1)o|a +&JCM');
* define('NONCE_KEY', '%:R{[P|,s.KuMltH5}cI;/k<Gx~j!f0I)m_sIyu+&NJZ)-iO>z7X>QYR0Z_XnZ@|');
* define('AUTH_SALT', 'eZyT)-Naw]F8CwA*VaW#q*|.)g@o}||wf~@C-YSt}(dh_r6EbI#A,y|nU2{B#JBW');
* define('SECURE_AUTH_SALT', '!=oLUTXh,QW=H `}`L|9/^4-3 STz},T(w}W<I`.JjPi)<Bmf1v,HpGe}T1:Xt7n');
* define('LOGGED_IN_SALT', '+XSqHc;@Q*K_b|Z?NC[3H!!EONbh.n<+=uKR:>*c(u`g~EJBf#8u#R{mUEZrozmm');
* define('NONCE_SALT', 'h`GXHhD>SLWVfg1(1(N{;.V!MoE(SfbA_ksP@&`+AycHcAV$+?@3q+rxV{%^VyKT');
* Salting passwords helps against tools which has stored hashed values of
* common dictionary strings. The added values makes it harder to crack.
* @link https://api.wordpress.org/secret-key/1.1/salt/ Create secrets for wp-config.php
* @param string $scheme Authentication scheme (auth, secure_auth, logged_in, nonce)
* @return string Salt value
function wp_salt( $scheme = 'auth' ) {
static $cached_salts = array();
if ( isset( $cached_salts[ $scheme ] ) ) {
* Filters the WordPress salt.
* @param string $cached_salt Cached salt for the given scheme.
* @param string $scheme Authentication scheme. Values include 'auth',
* 'secure_auth', 'logged_in', and 'nonce'.
return apply_filters( 'salt', $cached_salts[ $scheme ], $scheme );
if ( null === $duplicated_keys ) {
$duplicated_keys = array( 'put your unique phrase here' => true );
foreach ( array( 'AUTH', 'SECURE_AUTH', 'LOGGED_IN', 'NONCE', 'SECRET' ) as $first ) {
foreach ( array( 'KEY', 'SALT' ) as $second ) {
if ( ! defined( "{$first}_{$second}" ) ) {
$value = constant( "{$first}_{$second}" );
$duplicated_keys[ $value ] = isset( $duplicated_keys[ $value ] );
if ( defined( 'SECRET_KEY' ) && SECRET_KEY && empty( $duplicated_keys[ SECRET_KEY ] ) ) {
$values['key'] = SECRET_KEY;
if ( 'auth' === $scheme && defined( 'SECRET_SALT' ) && SECRET_SALT && empty( $duplicated_keys[ SECRET_SALT ] ) ) {
$values['salt'] = SECRET_SALT;
if ( in_array( $scheme, array( 'auth', 'secure_auth', 'logged_in', 'nonce' ), true ) ) {
foreach ( array( 'key', 'salt' ) as $type ) {
$const = strtoupper( "{$scheme}_{$type}" );
if ( defined( $const ) && constant( $const ) && empty( $duplicated_keys[ constant( $const ) ] ) ) {
$values[ $type ] = constant( $const );
} elseif ( ! $values[ $type ] ) {
$values[ $type ] = get_site_option( "{$scheme}_{$type}" );
if ( ! $values[ $type ] ) {
$values[ $type ] = wp_generate_password( 64, true, true );
update_site_option( "{$scheme}_{$type}", $values[ $type ] );
if ( ! $values['key'] ) {
$values['key'] = get_site_option( 'secret_key' );
if ( ! $values['key'] ) {
$values['key'] = wp_generate_password( 64, true, true );
update_site_option( 'secret_key', $values['key'] );
$values['salt'] = hash_hmac( 'md5', $scheme, $values['key'] );
$cached_salts[ $scheme ] = $values['key'] . $values['salt'];
/** This filter is documented in wp-includes/pluggable.php */
return apply_filters( 'salt', $cached_salts[ $scheme ], $scheme );
if ( ! function_exists( 'wp_hash' ) ) :
* Get hash of given string.
* @param string $data Plain text to hash
* @param string $scheme Authentication scheme (auth, secure_auth, logged_in, nonce)
* @return string Hash of $data
function wp_hash( $data, $scheme = 'auth' ) {
$salt = wp_salt( $scheme );
return hash_hmac( 'md5', $data, $salt );
if ( ! function_exists( 'wp_hash_password' ) ) :
* Create a hash (encrypt) of a plain text password.
* For integration with other applications, this function can be overwritten to
* instead use the other package password checking algorithm.
* @global PasswordHash $wp_hasher PHPass object
* @param string $password Plain text user password to hash
* @return string The hash string of the password
function wp_hash_password( $password ) {
if ( empty( $wp_hasher ) ) {
require_once ABSPATH . WPINC . '/class-phpass.php';
// By default, use the portable hash from phpass.
$wp_hasher = new PasswordHash( 8, true );
return $wp_hasher->HashPassword( trim( $password ) );
if ( ! function_exists( 'wp_check_password' ) ) :
* Checks the plaintext password against the encrypted Password.
* Maintains compatibility between old version and the new cookie authentication
* protocol using PHPass library. The $hash parameter is the encrypted password
* and the function compares the plain text password when encrypted similarly
* against the already encrypted password to see if they match.
* For integration with other applications, this function can be overwritten to
* instead use the other package password checking algorithm.
* @global PasswordHash $wp_hasher PHPass object used for checking the password
* against the $hash + $password
* @uses PasswordHash::CheckPassword
* @param string $password Plaintext user's password
* @param string $hash Hash of the user's password to check against.
* @param string|int $user_id Optional. User ID.
* @return bool False, if the $password does not match the hashed password
function wp_check_password( $password, $hash, $user_id = '' ) {
// If the hash is still md5...
if ( strlen( $hash ) <= 32 ) {
$check = hash_equals( $hash, md5( $password ) );
if ( $check && $user_id ) {
// Rehash using new hash.
wp_set_password( $password, $user_id );
$hash = wp_hash_password( $password );
* Filters whether the plaintext password matches the encrypted password.
* @param bool $check Whether the passwords match.
* @param string $password The plaintext password.
* @param string $hash The hashed password.
* @param string|int $user_id User ID. Can be empty.
return apply_filters( 'check_password', $check, $password, $hash, $user_id );
// If the stored hash is longer than an MD5,
// presume the new style phpass portable hash.
if ( empty( $wp_hasher ) ) {
require_once ABSPATH . WPINC . '/class-phpass.php';
// By default, use the portable hash from phpass.
$wp_hasher = new PasswordHash( 8, true );
$check = $wp_hasher->CheckPassword( $password, $hash );
/** This filter is documented in wp-includes/pluggable.php */
return apply_filters( 'check_password', $check, $password, $hash, $user_id );
if ( ! function_exists( 'wp_generate_password' ) ) :
* Generates a random password drawn from the defined set of characters.
* Uses wp_rand() is used to create passwords with far less predictability
* than similar native PHP functions like `rand()` or `mt_rand()`.
* @param int $length Optional. The length of password to generate. Default 12.
* @param bool $special_chars Optional. Whether to include standard special characters.
* @param bool $extra_special_chars Optional. Whether to include other special characters.
* Used when generating secret keys and salts. Default false.
* @return string The random password.
function wp_generate_password( $length = 12, $special_chars = true, $extra_special_chars = false ) {
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
if ( $extra_special_chars ) {
$chars .= '-_ []{}<>~`+=,.;:/?|';
for ( $i = 0; $i < $length; $i++ ) {
$password .= substr( $chars, wp_rand( 0, strlen( $chars ) - 1 ), 1 );
* Filters the randomly-generated password.
* @since 5.3.0 Added the `$length`, `$special_chars`, and `$extra_special_chars` parameters.
* @param string $password The generated password.
* @param int $length The length of password to generate.
* @param bool $special_chars Whether to include standard special characters.
* @param bool $extra_special_chars Whether to include other special characters.
return apply_filters( 'random_password', $password, $length, $special_chars, $extra_special_chars );