wp/wp-includes/pluggable.php
changeset 21 48c4eec2b7e6
parent 19 3d72ae0968f4
child 22 8c2e4d02f4ef
equal deleted inserted replaced
20:7b1b88e27a20 21:48c4eec2b7e6
    28 		global $current_user;
    28 		global $current_user;
    29 
    29 
    30 		// If `$id` matches the current user, there is nothing to do.
    30 		// If `$id` matches the current user, there is nothing to do.
    31 		if ( isset( $current_user )
    31 		if ( isset( $current_user )
    32 		&& ( $current_user instanceof WP_User )
    32 		&& ( $current_user instanceof WP_User )
    33 		&& ( $id == $current_user->ID )
    33 		&& ( $id === $current_user->ID )
    34 		&& ( null !== $id )
    34 		&& ( null !== $id )
    35 		) {
    35 		) {
    36 			return $current_user;
    36 			return $current_user;
    37 		}
    37 		}
    38 
    38 
    51 	}
    51 	}
    52 endif;
    52 endif;
    53 
    53 
    54 if ( ! function_exists( 'wp_get_current_user' ) ) :
    54 if ( ! function_exists( 'wp_get_current_user' ) ) :
    55 	/**
    55 	/**
    56 	 * Retrieve the current user object.
    56 	 * Retrieves the current user object.
    57 	 *
    57 	 *
    58 	 * Will set the current user, if the current user is not set. The current user
    58 	 * Will set the current user, if the current user is not set. The current user
    59 	 * will be set to the logged-in person. If no user is logged-in, then it will
    59 	 * will be set to the logged-in person. If no user is logged-in, then it will
    60 	 * set the current user to 0, which is invalid and won't have any permissions.
    60 	 * set the current user to 0, which is invalid and won't have any permissions.
    61 	 *
    61 	 *
    71 	}
    71 	}
    72 endif;
    72 endif;
    73 
    73 
    74 if ( ! function_exists( 'get_userdata' ) ) :
    74 if ( ! function_exists( 'get_userdata' ) ) :
    75 	/**
    75 	/**
    76 	 * Retrieve user info by user ID.
    76 	 * Retrieves user info by user ID.
    77 	 *
    77 	 *
    78 	 * @since 0.71
    78 	 * @since 0.71
    79 	 *
    79 	 *
    80 	 * @param int $user_id User ID
    80 	 * @param int $user_id User ID
    81 	 * @return WP_User|false WP_User object on success, false on failure.
    81 	 * @return WP_User|false WP_User object on success, false on failure.
    85 	}
    85 	}
    86 endif;
    86 endif;
    87 
    87 
    88 if ( ! function_exists( 'get_user_by' ) ) :
    88 if ( ! function_exists( 'get_user_by' ) ) :
    89 	/**
    89 	/**
    90 	 * Retrieve user info by a given field
    90 	 * Retrieves user info by a given field.
    91 	 *
    91 	 *
    92 	 * @since 2.8.0
    92 	 * @since 2.8.0
    93 	 * @since 4.4.0 Added 'ID' as an alias of 'id' for the `$field` parameter.
    93 	 * @since 4.4.0 Added 'ID' as an alias of 'id' for the `$field` parameter.
    94 	 * @since 5.8.0 Returns the global `$current_user` if it's the user being fetched.
       
    95 	 *
    94 	 *
    96 	 * @global WP_User $current_user The current user object which holds the user data.
    95 	 * @global WP_User $current_user The current user object which holds the user data.
    97 	 *
    96 	 *
    98 	 * @param string     $field The field to retrieve the user with. id | ID | slug | email | login.
    97 	 * @param string     $field The field to retrieve the user with. id | ID | slug | email | login.
    99 	 * @param int|string $value A value for $field. A user ID, slug, email address, or login name.
    98 	 * @param int|string $value A value for $field. A user ID, slug, email address, or login name.
   100 	 * @return WP_User|false WP_User object on success, false on failure.
    99 	 * @return WP_User|false WP_User object on success, false on failure.
   101 	 */
   100 	 */
   102 	function get_user_by( $field, $value ) {
   101 	function get_user_by( $field, $value ) {
   103 		global $current_user;
       
   104 
       
   105 		$userdata = WP_User::get_data_by( $field, $value );
   102 		$userdata = WP_User::get_data_by( $field, $value );
   106 
   103 
   107 		if ( ! $userdata ) {
   104 		if ( ! $userdata ) {
   108 			return false;
   105 			return false;
   109 		}
   106 		}
   110 
   107 
   111 		if ( $current_user instanceof WP_User && $current_user->ID === (int) $userdata->ID ) {
   108 		$user = new WP_User();
   112 			return $current_user;
       
   113 		}
       
   114 
       
   115 		$user = new WP_User;
       
   116 		$user->init( $userdata );
   109 		$user->init( $userdata );
   117 
   110 
   118 		return $user;
   111 		return $user;
   119 	}
   112 	}
   120 endif;
   113 endif;
   121 
   114 
   122 if ( ! function_exists( 'cache_users' ) ) :
   115 if ( ! function_exists( 'cache_users' ) ) :
   123 	/**
   116 	/**
   124 	 * Retrieve info for user lists to prevent multiple queries by get_userdata()
   117 	 * Retrieves info for user lists to prevent multiple queries by get_userdata().
   125 	 *
   118 	 *
   126 	 * @since 3.0.0
   119 	 * @since 3.0.0
   127 	 *
   120 	 *
   128 	 * @global wpdb $wpdb WordPress database abstraction object.
   121 	 * @global wpdb $wpdb WordPress database abstraction object.
   129 	 *
   122 	 *
   130 	 * @param int[] $user_ids User ID numbers list
   123 	 * @param int[] $user_ids User ID numbers list
   131 	 */
   124 	 */
   132 	function cache_users( $user_ids ) {
   125 	function cache_users( $user_ids ) {
   133 		global $wpdb;
   126 		global $wpdb;
   134 
   127 
       
   128 		update_meta_cache( 'user', $user_ids );
       
   129 
   135 		$clean = _get_non_cached_ids( $user_ids, 'users' );
   130 		$clean = _get_non_cached_ids( $user_ids, 'users' );
   136 
   131 
   137 		if ( empty( $clean ) ) {
   132 		if ( empty( $clean ) ) {
   138 			return;
   133 			return;
   139 		}
   134 		}
   140 
   135 
   141 		$list = implode( ',', $clean );
   136 		$list = implode( ',', $clean );
   142 
   137 
   143 		$users = $wpdb->get_results( "SELECT * FROM $wpdb->users WHERE ID IN ($list)" );
   138 		$users = $wpdb->get_results( "SELECT * FROM $wpdb->users WHERE ID IN ($list)" );
   144 
   139 
   145 		$ids = array();
       
   146 		foreach ( $users as $user ) {
   140 		foreach ( $users as $user ) {
   147 			update_user_caches( $user );
   141 			update_user_caches( $user );
   148 			$ids[] = $user->ID;
   142 		}
   149 		}
       
   150 		update_meta_cache( 'user', $ids );
       
   151 	}
   143 	}
   152 endif;
   144 endif;
   153 
   145 
   154 if ( ! function_exists( 'wp_mail' ) ) :
   146 if ( ! function_exists( 'wp_mail' ) ) :
   155 	/**
   147 	/**
   273 
   265 
   274 		if ( empty( $headers ) ) {
   266 		if ( empty( $headers ) ) {
   275 			$headers = array();
   267 			$headers = array();
   276 		} else {
   268 		} else {
   277 			if ( ! is_array( $headers ) ) {
   269 			if ( ! is_array( $headers ) ) {
   278 				// Explode the headers out, so this function can take
   270 				/*
   279 				// both string headers and an array of headers.
   271 				 * Explode the headers out, so this function can take
       
   272 				 * both string headers and an array of headers.
       
   273 				 */
   280 				$tempheaders = explode( "\n", str_replace( "\r\n", "\n", $headers ) );
   274 				$tempheaders = explode( "\n", str_replace( "\r\n", "\n", $headers ) );
   281 			} else {
   275 			} else {
   282 				$tempheaders = $headers;
   276 				$tempheaders = $headers;
   283 			}
   277 			}
   284 			$headers = array();
   278 			$headers = array();
   285 
   279 
   286 			// If it's actually got contents.
   280 			// If it's actually got contents.
   287 			if ( ! empty( $tempheaders ) ) {
   281 			if ( ! empty( $tempheaders ) ) {
   288 				// Iterate through the raw headers.
   282 				// Iterate through the raw headers.
   289 				foreach ( (array) $tempheaders as $header ) {
   283 				foreach ( (array) $tempheaders as $header ) {
   290 					if ( strpos( $header, ':' ) === false ) {
   284 					if ( ! str_contains( $header, ':' ) ) {
   291 						if ( false !== stripos( $header, 'boundary=' ) ) {
   285 						if ( false !== stripos( $header, 'boundary=' ) ) {
   292 							$parts    = preg_split( '/boundary=/i', trim( $header ) );
   286 							$parts    = preg_split( '/boundary=/i', trim( $header ) );
   293 							$boundary = trim( str_replace( array( "'", '"' ), '', $parts[1] ) );
   287 							$boundary = trim( str_replace( array( "'", '"' ), '', $parts[1] ) );
   294 						}
   288 						}
   295 						continue;
   289 						continue;
   306 						case 'from':
   300 						case 'from':
   307 							$bracket_pos = strpos( $content, '<' );
   301 							$bracket_pos = strpos( $content, '<' );
   308 							if ( false !== $bracket_pos ) {
   302 							if ( false !== $bracket_pos ) {
   309 								// Text before the bracketed email is the "From" name.
   303 								// Text before the bracketed email is the "From" name.
   310 								if ( $bracket_pos > 0 ) {
   304 								if ( $bracket_pos > 0 ) {
   311 									$from_name = substr( $content, 0, $bracket_pos - 1 );
   305 									$from_name = substr( $content, 0, $bracket_pos );
   312 									$from_name = str_replace( '"', '', $from_name );
   306 									$from_name = str_replace( '"', '', $from_name );
   313 									$from_name = trim( $from_name );
   307 									$from_name = trim( $from_name );
   314 								}
   308 								}
   315 
   309 
   316 								$from_email = substr( $content, $bracket_pos + 1 );
   310 								$from_email = substr( $content, $bracket_pos + 1 );
   321 							} elseif ( '' !== trim( $content ) ) {
   315 							} elseif ( '' !== trim( $content ) ) {
   322 								$from_email = trim( $content );
   316 								$from_email = trim( $content );
   323 							}
   317 							}
   324 							break;
   318 							break;
   325 						case 'content-type':
   319 						case 'content-type':
   326 							if ( strpos( $content, ';' ) !== false ) {
   320 							if ( str_contains( $content, ';' ) ) {
   327 								list( $type, $charset_content ) = explode( ';', $content );
   321 								list( $type, $charset_content ) = explode( ';', $content );
   328 								$content_type                   = trim( $type );
   322 								$content_type                   = trim( $type );
   329 								if ( false !== stripos( $charset_content, 'charset=' ) ) {
   323 								if ( false !== stripos( $charset_content, 'charset=' ) ) {
   330 									$charset = trim( str_replace( array( 'charset=', '"' ), '', $charset_content ) );
   324 									$charset = trim( str_replace( array( 'charset=', '"' ), '', $charset_content ) );
   331 								} elseif ( false !== stripos( $charset_content, 'boundary=' ) ) {
   325 								} elseif ( false !== stripos( $charset_content, 'boundary=' ) ) {
   359 		// Empty out the values that may be set.
   353 		// Empty out the values that may be set.
   360 		$phpmailer->clearAllRecipients();
   354 		$phpmailer->clearAllRecipients();
   361 		$phpmailer->clearAttachments();
   355 		$phpmailer->clearAttachments();
   362 		$phpmailer->clearCustomHeaders();
   356 		$phpmailer->clearCustomHeaders();
   363 		$phpmailer->clearReplyTos();
   357 		$phpmailer->clearReplyTos();
       
   358 		$phpmailer->Body    = '';
       
   359 		$phpmailer->AltBody = '';
   364 
   360 
   365 		// Set "From" name and email.
   361 		// Set "From" name and email.
   366 
   362 
   367 		// If we don't have a name from the input headers.
   363 		// If we don't have a name from the input headers.
   368 		if ( ! isset( $from_name ) ) {
   364 		if ( ! isset( $from_name ) ) {
   380 			// Get the site domain and get rid of www.
   376 			// Get the site domain and get rid of www.
   381 			$sitename   = wp_parse_url( network_home_url(), PHP_URL_HOST );
   377 			$sitename   = wp_parse_url( network_home_url(), PHP_URL_HOST );
   382 			$from_email = 'wordpress@';
   378 			$from_email = 'wordpress@';
   383 
   379 
   384 			if ( null !== $sitename ) {
   380 			if ( null !== $sitename ) {
   385 				if ( 'www.' === substr( $sitename, 0, 4 ) ) {
   381 				if ( str_starts_with( $sitename, 'www.' ) ) {
   386 					$sitename = substr( $sitename, 4 );
   382 					$sitename = substr( $sitename, 4 );
   387 				}
   383 				}
   388 
   384 
   389 				$from_email .= $sitename;
   385 				$from_email .= $sitename;
   390 			}
   386 			}
   436 				try {
   432 				try {
   437 					// Break $recipient into name and address parts if in the format "Foo <bar@baz.com>".
   433 					// Break $recipient into name and address parts if in the format "Foo <bar@baz.com>".
   438 					$recipient_name = '';
   434 					$recipient_name = '';
   439 
   435 
   440 					if ( preg_match( '/(.*)<(.+)>/', $address, $matches ) ) {
   436 					if ( preg_match( '/(.*)<(.+)>/', $address, $matches ) ) {
   441 						if ( count( $matches ) == 3 ) {
   437 						if ( count( $matches ) === 3 ) {
   442 							$recipient_name = $matches[1];
   438 							$recipient_name = $matches[1];
   443 							$address        = $matches[2];
   439 							$address        = $matches[2];
   444 						}
   440 						}
   445 					}
   441 					}
   446 
   442 
   467 		// Set to use PHP's mail().
   463 		// Set to use PHP's mail().
   468 		$phpmailer->isMail();
   464 		$phpmailer->isMail();
   469 
   465 
   470 		// Set Content-Type and charset.
   466 		// Set Content-Type and charset.
   471 
   467 
   472 		// If we don't have a content-type from the input headers.
   468 		// If we don't have a Content-Type from the input headers.
   473 		if ( ! isset( $content_type ) ) {
   469 		if ( ! isset( $content_type ) ) {
   474 			$content_type = 'text/plain';
   470 			$content_type = 'text/plain';
   475 		}
   471 		}
   476 
   472 
   477 		/**
   473 		/**
   521 				$phpmailer->addCustomHeader( sprintf( 'Content-Type: %s; boundary="%s"', $content_type, $boundary ) );
   517 				$phpmailer->addCustomHeader( sprintf( 'Content-Type: %s; boundary="%s"', $content_type, $boundary ) );
   522 			}
   518 			}
   523 		}
   519 		}
   524 
   520 
   525 		if ( ! empty( $attachments ) ) {
   521 		if ( ! empty( $attachments ) ) {
   526 			foreach ( $attachments as $attachment ) {
   522 			foreach ( $attachments as $filename => $attachment ) {
       
   523 				$filename = is_string( $filename ) ? $filename : '';
       
   524 
   527 				try {
   525 				try {
   528 					$phpmailer->addAttachment( $attachment );
   526 					$phpmailer->addAttachment( $attachment, $filename );
   529 				} catch ( PHPMailer\PHPMailer\Exception $e ) {
   527 				} catch ( PHPMailer\PHPMailer\Exception $e ) {
   530 					continue;
   528 					continue;
   531 				}
   529 				}
   532 			}
   530 			}
   533 		}
   531 		}
   587 	}
   585 	}
   588 endif;
   586 endif;
   589 
   587 
   590 if ( ! function_exists( 'wp_authenticate' ) ) :
   588 if ( ! function_exists( 'wp_authenticate' ) ) :
   591 	/**
   589 	/**
   592 	 * Authenticate a user, confirming the login credentials are valid.
   590 	 * Authenticates a user, confirming the login credentials are valid.
   593 	 *
   591 	 *
   594 	 * @since 2.5.0
   592 	 * @since 2.5.0
   595 	 * @since 4.5.0 `$username` now accepts an email address.
   593 	 * @since 4.5.0 `$username` now accepts an email address.
   596 	 *
   594 	 *
   597 	 * @param string $username User's username or email address.
   595 	 * @param string $username User's username or email address.
   613 		 * @since 4.5.0 `$username` now accepts an email address.
   611 		 * @since 4.5.0 `$username` now accepts an email address.
   614 		 *
   612 		 *
   615 		 * @param null|WP_User|WP_Error $user     WP_User if the user is authenticated.
   613 		 * @param null|WP_User|WP_Error $user     WP_User if the user is authenticated.
   616 		 *                                        WP_Error or null otherwise.
   614 		 *                                        WP_Error or null otherwise.
   617 		 * @param string                $username Username or email address.
   615 		 * @param string                $username Username or email address.
   618 		 * @param string                $password User password
   616 		 * @param string                $password User password.
   619 		 */
   617 		 */
   620 		$user = apply_filters( 'authenticate', null, $username, $password );
   618 		$user = apply_filters( 'authenticate', null, $username, $password );
   621 
   619 
   622 		if ( null == $user ) {
   620 		if ( null === $user || false === $user ) {
   623 			// TODO: What should the error message be? (Or would these even happen?)
   621 			/*
   624 			// Only needed if all authentication handlers fail to return anything.
   622 			 * TODO: What should the error message be? (Or would these even happen?)
   625 			$user = new WP_Error( 'authentication_failed', __( '<strong>Error</strong>: Invalid username, email address or incorrect password.' ) );
   623 			 * Only needed if all authentication handlers fail to return anything.
       
   624 			 */
       
   625 			$user = new WP_Error( 'authentication_failed', __( '<strong>Error:</strong> Invalid username, email address or incorrect password.' ) );
   626 		}
   626 		}
   627 
   627 
   628 		$ignore_codes = array( 'empty_username', 'empty_password' );
   628 		$ignore_codes = array( 'empty_username', 'empty_password' );
   629 
   629 
   630 		if ( is_wp_error( $user ) && ! in_array( $user->get_error_code(), $ignore_codes, true ) ) {
   630 		if ( is_wp_error( $user ) && ! in_array( $user->get_error_code(), $ignore_codes, true ) ) {
   647 	}
   647 	}
   648 endif;
   648 endif;
   649 
   649 
   650 if ( ! function_exists( 'wp_logout' ) ) :
   650 if ( ! function_exists( 'wp_logout' ) ) :
   651 	/**
   651 	/**
   652 	 * Log the current user out.
   652 	 * Logs the current user out.
   653 	 *
   653 	 *
   654 	 * @since 2.5.0
   654 	 * @since 2.5.0
   655 	 */
   655 	 */
   656 	function wp_logout() {
   656 	function wp_logout() {
   657 		$user_id = get_current_user_id();
   657 		$user_id = get_current_user_id();
   894 if ( ! function_exists( 'wp_parse_auth_cookie' ) ) :
   894 if ( ! function_exists( 'wp_parse_auth_cookie' ) ) :
   895 	/**
   895 	/**
   896 	 * Parses a cookie into its components.
   896 	 * Parses a cookie into its components.
   897 	 *
   897 	 *
   898 	 * @since 2.7.0
   898 	 * @since 2.7.0
       
   899 	 * @since 4.0.0 The `$token` element was added to the return value.
   899 	 *
   900 	 *
   900 	 * @param string $cookie Authentication cookie.
   901 	 * @param string $cookie Authentication cookie.
   901 	 * @param string $scheme Optional. The cookie scheme to use: 'auth', 'secure_auth', or 'logged_in'.
   902 	 * @param string $scheme Optional. The cookie scheme to use: 'auth', 'secure_auth', or 'logged_in'.
   902 	 * @return string[]|false {
   903 	 * @return string[]|false {
   903 	 *     Authentication cookie components. None of the components should be assumed
   904 	 *     Authentication cookie components. None of the components should be assumed
  1071 
  1072 
  1072 		/**
  1073 		/**
  1073 		 * Allows preventing auth cookies from actually being sent to the client.
  1074 		 * Allows preventing auth cookies from actually being sent to the client.
  1074 		 *
  1075 		 *
  1075 		 * @since 4.7.4
  1076 		 * @since 4.7.4
  1076 		 *
  1077 		 * @since 6.2.0 The `$expire`, `$expiration`, `$user_id`, `$scheme`, and `$token` parameters were added.
  1077 		 * @param bool $send Whether to send auth cookies to the client.
  1078 		 *
  1078 		 */
  1079 		 * @param bool   $send       Whether to send auth cookies to the client. Default true.
  1079 		if ( ! apply_filters( 'send_auth_cookies', true ) ) {
  1080 		 * @param int    $expire     The time the login grace period expires as a UNIX timestamp.
       
  1081 		 *                           Default is 12 hours past the cookie's expiration time. Zero when clearing cookies.
       
  1082 		 * @param int    $expiration The time when the logged-in authentication cookie expires as a UNIX timestamp.
       
  1083 		 *                           Default is 14 days from now. Zero when clearing cookies.
       
  1084 		 * @param int    $user_id    User ID. Zero when clearing cookies.
       
  1085 		 * @param string $scheme     Authentication scheme. Values include 'auth' or 'secure_auth'.
       
  1086 		 *                           Empty string when clearing cookies.
       
  1087 		 * @param string $token      User's session token to use for this cookie. Empty string when clearing cookies.
       
  1088 		 */
       
  1089 		if ( ! apply_filters( 'send_auth_cookies', true, $expire, $expiration, $user_id, $scheme, $token ) ) {
  1080 			return;
  1090 			return;
  1081 		}
  1091 		}
  1082 
  1092 
  1083 		setcookie( $auth_cookie_name, $auth_cookie, $expire, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN, $secure, true );
  1093 		setcookie( $auth_cookie_name, $auth_cookie, $expire, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN, $secure, true );
  1084 		setcookie( $auth_cookie_name, $auth_cookie, $expire, ADMIN_COOKIE_PATH, COOKIE_DOMAIN, $secure, true );
  1094 		setcookie( $auth_cookie_name, $auth_cookie, $expire, ADMIN_COOKIE_PATH, COOKIE_DOMAIN, $secure, true );
  1085 		setcookie( LOGGED_IN_COOKIE, $logged_in_cookie, $expire, COOKIEPATH, COOKIE_DOMAIN, $secure_logged_in_cookie, true );
  1095 		setcookie( LOGGED_IN_COOKIE, $logged_in_cookie, $expire, COOKIEPATH, COOKIE_DOMAIN, $secure_logged_in_cookie, true );
  1086 		if ( COOKIEPATH != SITECOOKIEPATH ) {
  1096 		if ( COOKIEPATH !== SITECOOKIEPATH ) {
  1087 			setcookie( LOGGED_IN_COOKIE, $logged_in_cookie, $expire, SITECOOKIEPATH, COOKIE_DOMAIN, $secure_logged_in_cookie, true );
  1097 			setcookie( LOGGED_IN_COOKIE, $logged_in_cookie, $expire, SITECOOKIEPATH, COOKIE_DOMAIN, $secure_logged_in_cookie, true );
  1088 		}
  1098 		}
  1089 	}
  1099 	}
  1090 endif;
  1100 endif;
  1091 
  1101 
  1102 		 * @since 2.7.0
  1112 		 * @since 2.7.0
  1103 		 */
  1113 		 */
  1104 		do_action( 'clear_auth_cookie' );
  1114 		do_action( 'clear_auth_cookie' );
  1105 
  1115 
  1106 		/** This filter is documented in wp-includes/pluggable.php */
  1116 		/** This filter is documented in wp-includes/pluggable.php */
  1107 		if ( ! apply_filters( 'send_auth_cookies', true ) ) {
  1117 		if ( ! apply_filters( 'send_auth_cookies', true, 0, 0, 0, '', '' ) ) {
  1108 			return;
  1118 			return;
  1109 		}
  1119 		}
  1110 
  1120 
  1111 		// Auth cookies.
  1121 		// Auth cookies.
  1112 		setcookie( AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, ADMIN_COOKIE_PATH, COOKIE_DOMAIN );
  1122 		setcookie( AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, ADMIN_COOKIE_PATH, COOKIE_DOMAIN );
  1178 		 * @param bool $secure Whether to use a secure authentication redirect. Default false.
  1188 		 * @param bool $secure Whether to use a secure authentication redirect. Default false.
  1179 		 */
  1189 		 */
  1180 		$secure = apply_filters( 'secure_auth_redirect', $secure );
  1190 		$secure = apply_filters( 'secure_auth_redirect', $secure );
  1181 
  1191 
  1182 		// If https is required and request is http, redirect.
  1192 		// If https is required and request is http, redirect.
  1183 		if ( $secure && ! is_ssl() && false !== strpos( $_SERVER['REQUEST_URI'], 'wp-admin' ) ) {
  1193 		if ( $secure && ! is_ssl() && str_contains( $_SERVER['REQUEST_URI'], 'wp-admin' ) ) {
  1184 			if ( 0 === strpos( $_SERVER['REQUEST_URI'], 'http' ) ) {
  1194 			if ( str_starts_with( $_SERVER['REQUEST_URI'], 'http' ) ) {
  1185 				wp_redirect( set_url_scheme( $_SERVER['REQUEST_URI'], 'https' ) );
  1195 				wp_redirect( set_url_scheme( $_SERVER['REQUEST_URI'], 'https' ) );
  1186 				exit;
  1196 				exit;
  1187 			} else {
  1197 			} else {
  1188 				wp_redirect( 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
  1198 				wp_redirect( 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
  1189 				exit;
  1199 				exit;
  1209 			 * @param int $user_id User ID.
  1219 			 * @param int $user_id User ID.
  1210 			 */
  1220 			 */
  1211 			do_action( 'auth_redirect', $user_id );
  1221 			do_action( 'auth_redirect', $user_id );
  1212 
  1222 
  1213 			// If the user wants ssl but the session is not ssl, redirect.
  1223 			// If the user wants ssl but the session is not ssl, redirect.
  1214 			if ( ! $secure && get_user_option( 'use_ssl', $user_id ) && false !== strpos( $_SERVER['REQUEST_URI'], 'wp-admin' ) ) {
  1224 			if ( ! $secure && get_user_option( 'use_ssl', $user_id ) && str_contains( $_SERVER['REQUEST_URI'], 'wp-admin' ) ) {
  1215 				if ( 0 === strpos( $_SERVER['REQUEST_URI'], 'http' ) ) {
  1225 				if ( str_starts_with( $_SERVER['REQUEST_URI'], 'http' ) ) {
  1216 					wp_redirect( set_url_scheme( $_SERVER['REQUEST_URI'], 'https' ) );
  1226 					wp_redirect( set_url_scheme( $_SERVER['REQUEST_URI'], 'https' ) );
  1217 					exit;
  1227 					exit;
  1218 				} else {
  1228 				} else {
  1219 					wp_redirect( 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
  1229 					wp_redirect( 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
  1220 					exit;
  1230 					exit;
  1225 		}
  1235 		}
  1226 
  1236 
  1227 		// The cookie is no good, so force login.
  1237 		// The cookie is no good, so force login.
  1228 		nocache_headers();
  1238 		nocache_headers();
  1229 
  1239 
  1230 		$redirect = ( strpos( $_SERVER['REQUEST_URI'], '/options.php' ) && wp_get_referer() ) ? wp_get_referer() : set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
  1240 		if ( str_contains( $_SERVER['REQUEST_URI'], '/options.php' ) && wp_get_referer() ) {
       
  1241 			$redirect = wp_get_referer();
       
  1242 		} else {
       
  1243 			$redirect = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
       
  1244 		}
  1231 
  1245 
  1232 		$login_url = wp_login_url( $redirect, true );
  1246 		$login_url = wp_login_url( $redirect, true );
  1233 
  1247 
  1234 		wp_redirect( $login_url );
  1248 		wp_redirect( $login_url );
  1235 		exit;
  1249 		exit;
  1239 if ( ! function_exists( 'check_admin_referer' ) ) :
  1253 if ( ! function_exists( 'check_admin_referer' ) ) :
  1240 	/**
  1254 	/**
  1241 	 * Ensures intent by verifying that a user was referred from another admin page with the correct security nonce.
  1255 	 * Ensures intent by verifying that a user was referred from another admin page with the correct security nonce.
  1242 	 *
  1256 	 *
  1243 	 * This function ensures the user intends to perform a given action, which helps protect against clickjacking style
  1257 	 * This function ensures the user intends to perform a given action, which helps protect against clickjacking style
  1244 	 * attacks. It verifies intent, not authorisation, therefore it does not verify the user's capabilities. This should
  1258 	 * attacks. It verifies intent, not authorization, therefore it does not verify the user's capabilities. This should
  1245 	 * be performed with `current_user_can()` or similar.
  1259 	 * be performed with `current_user_can()` or similar.
  1246 	 *
  1260 	 *
  1247 	 * If the nonce value is invalid, the function will exit with an "Are You Sure?" style message.
  1261 	 * If the nonce value is invalid, the function will exit with an "Are You Sure?" style message.
  1248 	 *
  1262 	 *
  1249 	 * @since 1.2.0
  1263 	 * @since 1.2.0
  1273 		 * @param false|int $result False if the nonce is invalid, 1 if the nonce is valid and generated between
  1287 		 * @param false|int $result False if the nonce is invalid, 1 if the nonce is valid and generated between
  1274 		 *                          0-12 hours ago, 2 if the nonce is valid and generated between 12-24 hours ago.
  1288 		 *                          0-12 hours ago, 2 if the nonce is valid and generated between 12-24 hours ago.
  1275 		 */
  1289 		 */
  1276 		do_action( 'check_admin_referer', $action, $result );
  1290 		do_action( 'check_admin_referer', $action, $result );
  1277 
  1291 
  1278 		if ( ! $result && ! ( -1 === $action && strpos( $referer, $adminurl ) === 0 ) ) {
  1292 		if ( ! $result && ! ( -1 === $action && str_starts_with( $referer, $adminurl ) ) ) {
  1279 			wp_nonce_ays( $action );
  1293 			wp_nonce_ays( $action );
  1280 			die();
  1294 			die();
  1281 		}
  1295 		}
  1282 
  1296 
  1283 		return $result;
  1297 		return $result;
  1292 	 *
  1306 	 *
  1293 	 * @param int|string   $action    Action nonce.
  1307 	 * @param int|string   $action    Action nonce.
  1294 	 * @param false|string $query_arg Optional. Key to check for the nonce in `$_REQUEST` (since 2.5). If false,
  1308 	 * @param false|string $query_arg Optional. Key to check for the nonce in `$_REQUEST` (since 2.5). If false,
  1295 	 *                                `$_REQUEST` values will be evaluated for '_ajax_nonce', and '_wpnonce'
  1309 	 *                                `$_REQUEST` values will be evaluated for '_ajax_nonce', and '_wpnonce'
  1296 	 *                                (in that order). Default false.
  1310 	 *                                (in that order). Default false.
  1297 	 * @param bool         $die       Optional. Whether to die early when the nonce cannot be verified.
  1311 	 * @param bool         $stop      Optional. Whether to stop early when the nonce cannot be verified.
  1298 	 *                                Default true.
  1312 	 *                                Default true.
  1299 	 * @return int|false 1 if the nonce is valid and generated between 0-12 hours ago,
  1313 	 * @return int|false 1 if the nonce is valid and generated between 0-12 hours ago,
  1300 	 *                   2 if the nonce is valid and generated between 12-24 hours ago.
  1314 	 *                   2 if the nonce is valid and generated between 12-24 hours ago.
  1301 	 *                   False if the nonce is invalid.
  1315 	 *                   False if the nonce is invalid.
  1302 	 */
  1316 	 */
  1303 	function check_ajax_referer( $action = -1, $query_arg = false, $die = true ) {
  1317 	function check_ajax_referer( $action = -1, $query_arg = false, $stop = true ) {
  1304 		if ( -1 == $action ) {
  1318 		if ( -1 === $action ) {
  1305 			_doing_it_wrong( __FUNCTION__, __( 'You should specify an action to be verified by using the first parameter.' ), '4.7.0' );
  1319 			_doing_it_wrong( __FUNCTION__, __( 'You should specify an action to be verified by using the first parameter.' ), '4.7.0' );
  1306 		}
  1320 		}
  1307 
  1321 
  1308 		$nonce = '';
  1322 		$nonce = '';
  1309 
  1323 
  1326 		 * @param false|int $result False if the nonce is invalid, 1 if the nonce is valid and generated between
  1340 		 * @param false|int $result False if the nonce is invalid, 1 if the nonce is valid and generated between
  1327 		 *                          0-12 hours ago, 2 if the nonce is valid and generated between 12-24 hours ago.
  1341 		 *                          0-12 hours ago, 2 if the nonce is valid and generated between 12-24 hours ago.
  1328 		 */
  1342 		 */
  1329 		do_action( 'check_ajax_referer', $action, $result );
  1343 		do_action( 'check_ajax_referer', $action, $result );
  1330 
  1344 
  1331 		if ( $die && false === $result ) {
  1345 		if ( $stop && false === $result ) {
  1332 			if ( wp_doing_ajax() ) {
  1346 			if ( wp_doing_ajax() ) {
  1333 				wp_die( -1, 403 );
  1347 				wp_die( -1, 403 );
  1334 			} else {
  1348 			} else {
  1335 				die( '-1' );
  1349 				die( '-1' );
  1336 			}
  1350 			}
  1349 	 *
  1363 	 *
  1350 	 *     wp_redirect( $url );
  1364 	 *     wp_redirect( $url );
  1351 	 *     exit;
  1365 	 *     exit;
  1352 	 *
  1366 	 *
  1353 	 * Exiting can also be selectively manipulated by using wp_redirect() as a conditional
  1367 	 * Exiting can also be selectively manipulated by using wp_redirect() as a conditional
  1354 	 * in conjunction with the {@see 'wp_redirect'} and {@see 'wp_redirect_location'} filters:
  1368 	 * in conjunction with the {@see 'wp_redirect'} and {@see 'wp_redirect_status'} filters:
  1355 	 *
  1369 	 *
  1356 	 *     if ( wp_redirect( $url ) ) {
  1370 	 *     if ( wp_redirect( $url ) ) {
  1357 	 *         exit;
  1371 	 *         exit;
  1358 	 *     }
  1372 	 *     }
  1359 	 *
  1373 	 *
  1361 	 * @since 5.1.0 The `$x_redirect_by` parameter was added.
  1375 	 * @since 5.1.0 The `$x_redirect_by` parameter was added.
  1362 	 * @since 5.4.0 On invalid status codes, wp_die() is called.
  1376 	 * @since 5.4.0 On invalid status codes, wp_die() is called.
  1363 	 *
  1377 	 *
  1364 	 * @global bool $is_IIS
  1378 	 * @global bool $is_IIS
  1365 	 *
  1379 	 *
  1366 	 * @param string $location      The path or URL to redirect to.
  1380 	 * @param string       $location      The path or URL to redirect to.
  1367 	 * @param int    $status        Optional. HTTP response status code to use. Default '302' (Moved Temporarily).
  1381 	 * @param int          $status        Optional. HTTP response status code to use. Default '302' (Moved Temporarily).
  1368 	 * @param string $x_redirect_by Optional. The application doing the redirect. Default 'WordPress'.
  1382 	 * @param string|false $x_redirect_by Optional. The application doing the redirect or false to omit. Default 'WordPress'.
  1369 	 * @return bool False if the redirect was cancelled, true otherwise.
  1383 	 * @return bool False if the redirect was canceled, true otherwise.
  1370 	 */
  1384 	 */
  1371 	function wp_redirect( $location, $status = 302, $x_redirect_by = 'WordPress' ) {
  1385 	function wp_redirect( $location, $status = 302, $x_redirect_by = 'WordPress' ) {
  1372 		global $is_IIS;
  1386 		global $is_IIS;
  1373 
  1387 
  1374 		/**
  1388 		/**
  1410 		 *
  1424 		 *
  1411 		 * Allows applications to identify themselves when they're doing a redirect.
  1425 		 * Allows applications to identify themselves when they're doing a redirect.
  1412 		 *
  1426 		 *
  1413 		 * @since 5.1.0
  1427 		 * @since 5.1.0
  1414 		 *
  1428 		 *
  1415 		 * @param string $x_redirect_by The application doing the redirect.
  1429 		 * @param string|false $x_redirect_by The application doing the redirect or false to omit the header.
  1416 		 * @param int    $status        Status code to use.
  1430 		 * @param int          $status        Status code to use.
  1417 		 * @param string $location      The path to redirect to.
  1431 		 * @param string       $location      The path to redirect to.
  1418 		 */
  1432 		 */
  1419 		$x_redirect_by = apply_filters( 'x_redirect_by', $x_redirect_by, $status, $location );
  1433 		$x_redirect_by = apply_filters( 'x_redirect_by', $x_redirect_by, $status, $location );
  1420 		if ( is_string( $x_redirect_by ) ) {
  1434 		if ( is_string( $x_redirect_by ) ) {
  1421 			header( "X-Redirect-By: $x_redirect_by" );
  1435 			header( "X-Redirect-By: $x_redirect_by" );
  1422 		}
  1436 		}
  1460 		$strip = array( '%0d', '%0a', '%0D', '%0A' );
  1474 		$strip = array( '%0d', '%0a', '%0D', '%0A' );
  1461 		return _deep_replace( $strip, $location );
  1475 		return _deep_replace( $strip, $location );
  1462 	}
  1476 	}
  1463 
  1477 
  1464 	/**
  1478 	/**
  1465 	 * URL encode UTF-8 characters in a URL.
  1479 	 * URL encodes UTF-8 characters in a URL.
  1466 	 *
  1480 	 *
  1467 	 * @ignore
  1481 	 * @ignore
  1468 	 * @since 4.2.0
  1482 	 * @since 4.2.0
  1469 	 * @access private
  1483 	 * @access private
  1470 	 *
  1484 	 *
  1495 	 *
  1509 	 *
  1496 	 *     wp_safe_redirect( $url );
  1510 	 *     wp_safe_redirect( $url );
  1497 	 *     exit;
  1511 	 *     exit;
  1498 	 *
  1512 	 *
  1499 	 * Exiting can also be selectively manipulated by using wp_safe_redirect() as a conditional
  1513 	 * Exiting can also be selectively manipulated by using wp_safe_redirect() as a conditional
  1500 	 * in conjunction with the {@see 'wp_redirect'} and {@see 'wp_redirect_location'} filters:
  1514 	 * in conjunction with the {@see 'wp_redirect'} and {@see 'wp_redirect_status'} filters:
  1501 	 *
  1515 	 *
  1502 	 *     if ( wp_safe_redirect( $url ) ) {
  1516 	 *     if ( wp_safe_redirect( $url ) ) {
  1503 	 *         exit;
  1517 	 *         exit;
  1504 	 *     }
  1518 	 *     }
  1505 	 *
  1519 	 *
  1506 	 * @since 2.3.0
  1520 	 * @since 2.3.0
  1507 	 * @since 5.1.0 The return value from wp_redirect() is now passed on, and the `$x_redirect_by` parameter was added.
  1521 	 * @since 5.1.0 The return value from wp_redirect() is now passed on, and the `$x_redirect_by` parameter was added.
  1508 	 *
  1522 	 *
  1509 	 * @param string $location      The path or URL to redirect to.
  1523 	 * @param string       $location      The path or URL to redirect to.
  1510 	 * @param int    $status        Optional. HTTP response status code to use. Default '302' (Moved Temporarily).
  1524 	 * @param int          $status        Optional. HTTP response status code to use. Default '302' (Moved Temporarily).
  1511 	 * @param string $x_redirect_by Optional. The application doing the redirect. Default 'WordPress'.
  1525 	 * @param string|false $x_redirect_by Optional. The application doing the redirect or false to omit. Default 'WordPress'.
  1512 	 * @return bool False if the redirect was cancelled, true otherwise.
  1526 	 * @return bool False if the redirect was canceled, true otherwise.
  1513 	 */
  1527 	 */
  1514 	function wp_safe_redirect( $location, $status = 302, $x_redirect_by = 'WordPress' ) {
  1528 	function wp_safe_redirect( $location, $status = 302, $x_redirect_by = 'WordPress' ) {
  1515 
  1529 
  1516 		// Need to look at the URL the way it will end up in wp_redirect().
  1530 		// Need to look at the URL the way it will end up in wp_redirect().
  1517 		$location = wp_sanitize_redirect( $location );
  1531 		$location = wp_sanitize_redirect( $location );
  1522 		 * @since 4.3.0
  1536 		 * @since 4.3.0
  1523 		 *
  1537 		 *
  1524 		 * @param string $fallback_url The fallback URL to use by default.
  1538 		 * @param string $fallback_url The fallback URL to use by default.
  1525 		 * @param int    $status       The HTTP response status code to use.
  1539 		 * @param int    $status       The HTTP response status code to use.
  1526 		 */
  1540 		 */
  1527 		$location = wp_validate_redirect( $location, apply_filters( 'wp_safe_redirect_fallback', admin_url(), $status ) );
  1541 		$fallback_url = apply_filters( 'wp_safe_redirect_fallback', admin_url(), $status );
       
  1542 
       
  1543 		$location = wp_validate_redirect( $location, $fallback_url );
  1528 
  1544 
  1529 		return wp_redirect( $location, $status, $x_redirect_by );
  1545 		return wp_redirect( $location, $status, $x_redirect_by );
  1530 	}
  1546 	}
  1531 endif;
  1547 endif;
  1532 
  1548 
  1536 	 *
  1552 	 *
  1537 	 * Checks whether the $location is using an allowed host, if it has an absolute
  1553 	 * Checks whether the $location is using an allowed host, if it has an absolute
  1538 	 * path. A plugin can therefore set or remove allowed host(s) to or from the
  1554 	 * path. A plugin can therefore set or remove allowed host(s) to or from the
  1539 	 * list.
  1555 	 * list.
  1540 	 *
  1556 	 *
  1541 	 * If the host is not allowed, then the redirect is to $default supplied
  1557 	 * If the host is not allowed, then the redirect is to $fallback_url supplied.
  1542 	 *
  1558 	 *
  1543 	 * @since 2.8.1
  1559 	 * @since 2.8.1
  1544 	 *
  1560 	 *
  1545 	 * @param string $location The redirect to validate
  1561 	 * @param string $location     The redirect to validate.
  1546 	 * @param string $default  The value to return if $location is not allowed
  1562 	 * @param string $fallback_url The value to return if $location is not allowed.
  1547 	 * @return string redirect-sanitized URL
  1563 	 * @return string Redirect-sanitized URL.
  1548 	 */
  1564 	 */
  1549 	function wp_validate_redirect( $location, $default = '' ) {
  1565 	function wp_validate_redirect( $location, $fallback_url = '' ) {
  1550 		$location = wp_sanitize_redirect( trim( $location, " \t\n\r\0\x08\x0B" ) );
  1566 		$location = wp_sanitize_redirect( trim( $location, " \t\n\r\0\x08\x0B" ) );
  1551 		// Browsers will assume 'http' is your protocol, and will obey a redirect to a URL starting with '//'.
  1567 		// Browsers will assume 'http' is your protocol, and will obey a redirect to a URL starting with '//'.
  1552 		if ( '//' === substr( $location, 0, 2 ) ) {
  1568 		if ( str_starts_with( $location, '//' ) ) {
  1553 			$location = 'http:' . $location;
  1569 			$location = 'http:' . $location;
  1554 		}
  1570 		}
  1555 
  1571 
  1556 		// In PHP 5 parse_url() may fail if the URL query part contains 'http://'.
  1572 		/*
  1557 		// See https://bugs.php.net/bug.php?id=38143
  1573 		 * In PHP 5 parse_url() may fail if the URL query part contains 'http://'.
       
  1574 		 * See https://bugs.php.net/bug.php?id=38143
       
  1575 		 */
  1558 		$cut  = strpos( $location, '?' );
  1576 		$cut  = strpos( $location, '?' );
  1559 		$test = $cut ? substr( $location, 0, $cut ) : $location;
  1577 		$test = $cut ? substr( $location, 0, $cut ) : $location;
  1560 
  1578 
  1561 		$lp = parse_url( $test );
  1579 		$lp = parse_url( $test );
  1562 
  1580 
  1563 		// Give up if malformed URL.
  1581 		// Give up if malformed URL.
  1564 		if ( false === $lp ) {
  1582 		if ( false === $lp ) {
  1565 			return $default;
  1583 			return $fallback_url;
  1566 		}
  1584 		}
  1567 
  1585 
  1568 		// Allow only 'http' and 'https' schemes. No 'data:', etc.
  1586 		// Allow only 'http' and 'https' schemes. No 'data:', etc.
  1569 		if ( isset( $lp['scheme'] ) && ! ( 'http' === $lp['scheme'] || 'https' === $lp['scheme'] ) ) {
  1587 		if ( isset( $lp['scheme'] ) && ! ( 'http' === $lp['scheme'] || 'https' === $lp['scheme'] ) ) {
  1570 			return $default;
  1588 			return $fallback_url;
  1571 		}
  1589 		}
  1572 
  1590 
  1573 		if ( ! isset( $lp['host'] ) && ! empty( $lp['path'] ) && '/' !== $lp['path'][0] ) {
  1591 		if ( ! isset( $lp['host'] ) && ! empty( $lp['path'] ) && '/' !== $lp['path'][0] ) {
  1574 			$path = '';
  1592 			$path = '';
  1575 			if ( ! empty( $_SERVER['REQUEST_URI'] ) ) {
  1593 			if ( ! empty( $_SERVER['REQUEST_URI'] ) ) {
  1577 				$path = wp_normalize_path( $path );
  1595 				$path = wp_normalize_path( $path );
  1578 			}
  1596 			}
  1579 			$location = '/' . ltrim( $path . '/', '/' ) . $location;
  1597 			$location = '/' . ltrim( $path . '/', '/' ) . $location;
  1580 		}
  1598 		}
  1581 
  1599 
  1582 		// Reject if certain components are set but host is not.
  1600 		/*
  1583 		// This catches URLs like https:host.com for which parse_url() does not set the host field.
  1601 		 * Reject if certain components are set but host is not.
       
  1602 		 * This catches URLs like https:host.com for which parse_url() does not set the host field.
       
  1603 		 */
  1584 		if ( ! isset( $lp['host'] ) && ( isset( $lp['scheme'] ) || isset( $lp['user'] ) || isset( $lp['pass'] ) || isset( $lp['port'] ) ) ) {
  1604 		if ( ! isset( $lp['host'] ) && ( isset( $lp['scheme'] ) || isset( $lp['user'] ) || isset( $lp['pass'] ) || isset( $lp['port'] ) ) ) {
  1585 			return $default;
  1605 			return $fallback_url;
  1586 		}
  1606 		}
  1587 
  1607 
  1588 		// Reject malformed components parse_url() can return on odd inputs.
  1608 		// Reject malformed components parse_url() can return on odd inputs.
  1589 		foreach ( array( 'user', 'pass', 'host' ) as $component ) {
  1609 		foreach ( array( 'user', 'pass', 'host' ) as $component ) {
  1590 			if ( isset( $lp[ $component ] ) && strpbrk( $lp[ $component ], ':/?#@' ) ) {
  1610 			if ( isset( $lp[ $component ] ) && strpbrk( $lp[ $component ], ':/?#@' ) ) {
  1591 				return $default;
  1611 				return $fallback_url;
  1592 			}
  1612 			}
  1593 		}
  1613 		}
  1594 
  1614 
  1595 		$wpp = parse_url( home_url() );
  1615 		$wpp = parse_url( home_url() );
  1596 
  1616 
  1603 		 * @param string   $host  The host name of the redirect destination; empty string if not set.
  1623 		 * @param string   $host  The host name of the redirect destination; empty string if not set.
  1604 		 */
  1624 		 */
  1605 		$allowed_hosts = (array) apply_filters( 'allowed_redirect_hosts', array( $wpp['host'] ), isset( $lp['host'] ) ? $lp['host'] : '' );
  1625 		$allowed_hosts = (array) apply_filters( 'allowed_redirect_hosts', array( $wpp['host'] ), isset( $lp['host'] ) ? $lp['host'] : '' );
  1606 
  1626 
  1607 		if ( isset( $lp['host'] ) && ( ! in_array( $lp['host'], $allowed_hosts, true ) && strtolower( $wpp['host'] ) !== $lp['host'] ) ) {
  1627 		if ( isset( $lp['host'] ) && ( ! in_array( $lp['host'], $allowed_hosts, true ) && strtolower( $wpp['host'] ) !== $lp['host'] ) ) {
  1608 			$location = $default;
  1628 			$location = $fallback_url;
  1609 		}
  1629 		}
  1610 
  1630 
  1611 		return $location;
  1631 		return $location;
  1612 	}
  1632 	}
  1613 endif;
  1633 endif;
  1614 
  1634 
  1615 if ( ! function_exists( 'wp_notify_postauthor' ) ) :
  1635 if ( ! function_exists( 'wp_notify_postauthor' ) ) :
  1616 	/**
  1636 	/**
  1617 	 * Notify an author (and/or others) of a comment/trackback/pingback on a post.
  1637 	 * Notifies an author (and/or others) of a comment/trackback/pingback on a post.
  1618 	 *
  1638 	 *
  1619 	 * @since 1.0.0
  1639 	 * @since 1.0.0
  1620 	 *
  1640 	 *
  1621 	 * @param int|WP_Comment $comment_id Comment ID or WP_Comment object.
  1641 	 * @param int|WP_Comment $comment_id Comment ID or WP_Comment object.
  1622 	 * @param string         $deprecated Not used
  1642 	 * @param string         $deprecated Not used.
  1623 	 * @return bool True on completion. False if no email addresses were specified.
  1643 	 * @return bool True on completion. False if no email addresses were specified.
  1624 	 */
  1644 	 */
  1625 	function wp_notify_postauthor( $comment_id, $deprecated = null ) {
  1645 	function wp_notify_postauthor( $comment_id, $deprecated = null ) {
  1626 		if ( null !== $deprecated ) {
  1646 		if ( null !== $deprecated ) {
  1627 			_deprecated_argument( __FUNCTION__, '3.8.0' );
  1647 			_deprecated_argument( __FUNCTION__, '3.8.0' );
  1676 		 * @param string $comment_id The comment ID as a numeric string.
  1696 		 * @param string $comment_id The comment ID as a numeric string.
  1677 		 */
  1697 		 */
  1678 		$notify_author = apply_filters( 'comment_notification_notify_author', false, $comment->comment_ID );
  1698 		$notify_author = apply_filters( 'comment_notification_notify_author', false, $comment->comment_ID );
  1679 
  1699 
  1680 		// The comment was left by the author.
  1700 		// The comment was left by the author.
  1681 		if ( $author && ! $notify_author && $comment->user_id == $post->post_author ) {
  1701 		if ( $author && ! $notify_author && (int) $comment->user_id === (int) $post->post_author ) {
  1682 			unset( $emails[ $author->user_email ] );
  1702 			unset( $emails[ $author->user_email ] );
  1683 		}
  1703 		}
  1684 
  1704 
  1685 		// The author moderated a comment on their own post.
  1705 		// The author moderated a comment on their own post.
  1686 		if ( $author && ! $notify_author && get_current_user_id() == $post->post_author ) {
  1706 		if ( $author && ! $notify_author && get_current_user_id() === (int) $post->post_author ) {
  1687 			unset( $emails[ $author->user_email ] );
  1707 			unset( $emails[ $author->user_email ] );
  1688 		}
  1708 		}
  1689 
  1709 
  1690 		// The post author is no longer a member of the blog.
  1710 		// The post author is no longer a member of the blog.
  1691 		if ( $author && ! $notify_author && ! user_can( $post->post_author, 'read_post', $post->ID ) ) {
  1711 		if ( $author && ! $notify_author && ! user_can( $post->post_author, 'read_post', $post->ID ) ) {
  1704 		$comment_author_domain = '';
  1724 		$comment_author_domain = '';
  1705 		if ( WP_Http::is_ip_address( $comment->comment_author_IP ) ) {
  1725 		if ( WP_Http::is_ip_address( $comment->comment_author_IP ) ) {
  1706 			$comment_author_domain = gethostbyaddr( $comment->comment_author_IP );
  1726 			$comment_author_domain = gethostbyaddr( $comment->comment_author_IP );
  1707 		}
  1727 		}
  1708 
  1728 
  1709 		// The blogname option is escaped with esc_html() on the way into the database in sanitize_option().
  1729 		/*
  1710 		// We want to reverse this for the plain text arena of emails.
  1730 		 * The blogname option is escaped with esc_html() on the way into the database in sanitize_option().
       
  1731 		 * We want to reverse this for the plain text arena of emails.
       
  1732 		 */
  1711 		$blogname        = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
  1733 		$blogname        = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
  1712 		$comment_content = wp_specialchars_decode( $comment->comment_content );
  1734 		$comment_content = wp_specialchars_decode( $comment->comment_content );
  1713 
  1735 
  1714 		switch ( $comment->comment_type ) {
  1736 		switch ( $comment->comment_type ) {
  1715 			case 'trackback':
  1737 			case 'trackback':
  1865 		 * Filters whether to send the site moderator email notifications, overriding the site setting.
  1887 		 * Filters whether to send the site moderator email notifications, overriding the site setting.
  1866 		 *
  1888 		 *
  1867 		 * @since 4.4.0
  1889 		 * @since 4.4.0
  1868 		 *
  1890 		 *
  1869 		 * @param bool $maybe_notify Whether to notify blog moderator.
  1891 		 * @param bool $maybe_notify Whether to notify blog moderator.
  1870 		 * @param int  $comment_ID   The id of the comment for the notification.
  1892 		 * @param int  $comment_id   The ID of the comment for the notification.
  1871 		 */
  1893 		 */
  1872 		$maybe_notify = apply_filters( 'notify_moderator', $maybe_notify, $comment_id );
  1894 		$maybe_notify = apply_filters( 'notify_moderator', $maybe_notify, $comment_id );
  1873 
  1895 
  1874 		if ( ! $maybe_notify ) {
  1896 		if ( ! $maybe_notify ) {
  1875 			return true;
  1897 			return true;
  1893 			$comment_author_domain = gethostbyaddr( $comment->comment_author_IP );
  1915 			$comment_author_domain = gethostbyaddr( $comment->comment_author_IP );
  1894 		}
  1916 		}
  1895 
  1917 
  1896 		$comments_waiting = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_approved = '0'" );
  1918 		$comments_waiting = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_approved = '0'" );
  1897 
  1919 
  1898 		// The blogname option is escaped with esc_html() on the way into the database in sanitize_option().
  1920 		/*
  1899 		// We want to reverse this for the plain text arena of emails.
  1921 		 * The blogname option is escaped with esc_html() on the way into the database in sanitize_option().
       
  1922 		 * We want to reverse this for the plain text arena of emails.
       
  1923 		 */
  1900 		$blogname        = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
  1924 		$blogname        = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
  1901 		$comment_content = wp_specialchars_decode( $comment->comment_content );
  1925 		$comment_content = wp_specialchars_decode( $comment->comment_content );
  1902 
  1926 
  1903 		switch ( $comment->comment_type ) {
  1927 		switch ( $comment->comment_type ) {
  1904 			case 'trackback':
  1928 			case 'trackback':
  2025 	}
  2049 	}
  2026 endif;
  2050 endif;
  2027 
  2051 
  2028 if ( ! function_exists( 'wp_password_change_notification' ) ) :
  2052 if ( ! function_exists( 'wp_password_change_notification' ) ) :
  2029 	/**
  2053 	/**
  2030 	 * Notify the blog admin of a user changing password, normally via email.
  2054 	 * Notifies the blog admin of a user changing password, normally via email.
  2031 	 *
  2055 	 *
  2032 	 * @since 2.7.0
  2056 	 * @since 2.7.0
  2033 	 *
  2057 	 *
  2034 	 * @param WP_User $user User object.
  2058 	 * @param WP_User $user User object.
  2035 	 */
  2059 	 */
  2036 	function wp_password_change_notification( $user ) {
  2060 	function wp_password_change_notification( $user ) {
  2037 		// Send a copy of password change notification to the admin,
  2061 		/*
  2038 		// but check to see if it's the admin whose password we're changing, and skip this.
  2062 		 * Send a copy of password change notification to the admin,
       
  2063 		 * but check to see if it's the admin whose password we're changing, and skip this.
       
  2064 		 */
  2039 		if ( 0 !== strcasecmp( $user->user_email, get_option( 'admin_email' ) ) ) {
  2065 		if ( 0 !== strcasecmp( $user->user_email, get_option( 'admin_email' ) ) ) {
  2040 			/* translators: %s: User name. */
  2066 			/* translators: %s: User name. */
  2041 			$message = sprintf( __( 'Password changed for user: %s' ), $user->user_login ) . "\r\n";
  2067 			$message = sprintf( __( 'Password changed for user: %s' ), $user->user_login ) . "\r\n";
  2042 			// The blogname option is escaped with esc_html() on the way into the database in sanitize_option().
  2068 			/*
  2043 			// We want to reverse this for the plain text arena of emails.
  2069 			 * The blogname option is escaped with esc_html() on the way into the database in sanitize_option().
       
  2070 			 * We want to reverse this for the plain text arena of emails.
       
  2071 			 */
  2044 			$blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
  2072 			$blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
  2045 
  2073 
  2046 			$wp_password_change_notification_email = array(
  2074 			$wp_password_change_notification_email = array(
  2047 				'to'      => get_option( 'admin_email' ),
  2075 				'to'      => get_option( 'admin_email' ),
  2048 				/* translators: Password change notification email subject. %s: Site title. */
  2076 				/* translators: Password change notification email subject. %s: Site title. */
  2079 	}
  2107 	}
  2080 endif;
  2108 endif;
  2081 
  2109 
  2082 if ( ! function_exists( 'wp_new_user_notification' ) ) :
  2110 if ( ! function_exists( 'wp_new_user_notification' ) ) :
  2083 	/**
  2111 	/**
  2084 	 * Email login credentials to a newly-registered user.
  2112 	 * Emails login credentials to a newly-registered user.
  2085 	 *
  2113 	 *
  2086 	 * A new user registration notification is also sent to admin email.
  2114 	 * A new user registration notification is also sent to admin email.
  2087 	 *
  2115 	 *
  2088 	 * @since 2.0.0
  2116 	 * @since 2.0.0
  2089 	 * @since 4.3.0 The `$plaintext_pass` parameter was changed to `$notify`.
  2117 	 * @since 4.3.0 The `$plaintext_pass` parameter was changed to `$notify`.
  2105 			return;
  2133 			return;
  2106 		}
  2134 		}
  2107 
  2135 
  2108 		$user = get_userdata( $user_id );
  2136 		$user = get_userdata( $user_id );
  2109 
  2137 
  2110 		// The blogname option is escaped with esc_html() on the way into the database in sanitize_option().
  2138 		/*
  2111 		// We want to reverse this for the plain text arena of emails.
  2139 		 * The blogname option is escaped with esc_html() on the way into the database in sanitize_option().
       
  2140 		 * We want to reverse this for the plain text arena of emails.
       
  2141 		 */
  2112 		$blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
  2142 		$blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
  2113 
  2143 
  2114 		if ( 'user' !== $notify ) {
  2144 		/**
       
  2145 		 * Filters whether the admin is notified of a new user registration.
       
  2146 		 *
       
  2147 		 * @since 6.1.0
       
  2148 		 *
       
  2149 		 * @param bool    $send Whether to send the email. Default true.
       
  2150 		 * @param WP_User $user User object for new user.
       
  2151 		 */
       
  2152 		$send_notification_to_admin = apply_filters( 'wp_send_new_user_notification_to_admin', true, $user );
       
  2153 
       
  2154 		if ( 'user' !== $notify && true === $send_notification_to_admin ) {
  2115 			$switched_locale = switch_to_locale( get_locale() );
  2155 			$switched_locale = switch_to_locale( get_locale() );
  2116 
  2156 
  2117 			/* translators: %s: Site title. */
  2157 			/* translators: %s: Site title. */
  2118 			$message = sprintf( __( 'New user registration on your site %s:' ), $blogname ) . "\r\n\r\n";
  2158 			$message = sprintf( __( 'New user registration on your site %s:' ), $blogname ) . "\r\n\r\n";
  2119 			/* translators: %s: User login. */
  2159 			/* translators: %s: User login. */
  2157 			if ( $switched_locale ) {
  2197 			if ( $switched_locale ) {
  2158 				restore_previous_locale();
  2198 				restore_previous_locale();
  2159 			}
  2199 			}
  2160 		}
  2200 		}
  2161 
  2201 
       
  2202 		/**
       
  2203 		 * Filters whether the user is notified of their new user registration.
       
  2204 		 *
       
  2205 		 * @since 6.1.0
       
  2206 		 *
       
  2207 		 * @param bool    $send Whether to send the email. Default true.
       
  2208 		 * @param WP_User $user User object for new user.
       
  2209 		 */
       
  2210 		$send_notification_to_user = apply_filters( 'wp_send_new_user_notification_to_user', true, $user );
       
  2211 
  2162 		// `$deprecated` was pre-4.3 `$plaintext_pass`. An empty `$plaintext_pass` didn't sent a user notification.
  2212 		// `$deprecated` was pre-4.3 `$plaintext_pass`. An empty `$plaintext_pass` didn't sent a user notification.
  2163 		if ( 'admin' === $notify || ( empty( $deprecated ) && empty( $notify ) ) ) {
  2213 		if ( 'admin' === $notify || true !== $send_notification_to_user || ( empty( $deprecated ) && empty( $notify ) ) ) {
  2164 			return;
  2214 			return;
  2165 		}
  2215 		}
  2166 
  2216 
  2167 		$key = get_password_reset_key( $user );
  2217 		$key = get_password_reset_key( $user );
  2168 		if ( is_wp_error( $key ) ) {
  2218 		if ( is_wp_error( $key ) ) {
  2169 			return;
  2219 			return;
  2170 		}
  2220 		}
  2171 
  2221 
  2172 		$switched_locale = switch_to_locale( get_user_locale( $user ) );
  2222 		$switched_locale = switch_to_user_locale( $user_id );
  2173 
  2223 
  2174 		/* translators: %s: User login. */
  2224 		/* translators: %s: User login. */
  2175 		$message  = sprintf( __( 'Username: %s' ), $user->user_login ) . "\r\n\r\n";
  2225 		$message  = sprintf( __( 'Username: %s' ), $user->user_login ) . "\r\n\r\n";
  2176 		$message .= __( 'To set your password, visit the following address:' ) . "\r\n\r\n";
  2226 		$message .= __( 'To set your password, visit the following address:' ) . "\r\n\r\n";
  2177 		$message .= network_site_url( "wp-login.php?action=rp&key=$key&login=" . rawurlencode( $user->user_login ), 'login' ) . "\r\n\r\n";
  2227 		$message .= network_site_url( "wp-login.php?action=rp&key=$key&login=" . rawurlencode( $user->user_login ), 'login' ) . "\r\n\r\n";
  2223 	 *
  2273 	 *
  2224 	 * A nonce has a lifespan of two ticks. Nonces in their second tick may be
  2274 	 * A nonce has a lifespan of two ticks. Nonces in their second tick may be
  2225 	 * updated, e.g. by autosave.
  2275 	 * updated, e.g. by autosave.
  2226 	 *
  2276 	 *
  2227 	 * @since 2.5.0
  2277 	 * @since 2.5.0
  2228 	 *
  2278 	 * @since 6.1.0 Added `$action` argument.
       
  2279 	 *
       
  2280 	 * @param string|int $action Optional. The nonce action. Default -1.
  2229 	 * @return float Float value rounded up to the next highest integer.
  2281 	 * @return float Float value rounded up to the next highest integer.
  2230 	 */
  2282 	 */
  2231 	function wp_nonce_tick() {
  2283 	function wp_nonce_tick( $action = -1 ) {
  2232 		/**
  2284 		/**
  2233 		 * Filters the lifespan of nonces in seconds.
  2285 		 * Filters the lifespan of nonces in seconds.
  2234 		 *
  2286 		 *
  2235 		 * @since 2.5.0
  2287 		 * @since 2.5.0
  2236 		 *
  2288 		 * @since 6.1.0 Added `$action` argument to allow for more targeted filters.
  2237 		 * @param int $lifespan Lifespan of nonces in seconds. Default 86,400 seconds, or one day.
  2289 		 *
  2238 		 */
  2290 		 * @param int        $lifespan Lifespan of nonces in seconds. Default 86,400 seconds, or one day.
  2239 		$nonce_life = apply_filters( 'nonce_life', DAY_IN_SECONDS );
  2291 		 * @param string|int $action   The nonce action, or -1 if none was provided.
       
  2292 		 */
       
  2293 		$nonce_life = apply_filters( 'nonce_life', DAY_IN_SECONDS, $action );
  2240 
  2294 
  2241 		return ceil( time() / ( $nonce_life / 2 ) );
  2295 		return ceil( time() / ( $nonce_life / 2 ) );
  2242 	}
  2296 	}
  2243 endif;
  2297 endif;
  2244 
  2298 
  2264 			/**
  2318 			/**
  2265 			 * Filters whether the user who generated the nonce is logged out.
  2319 			 * Filters whether the user who generated the nonce is logged out.
  2266 			 *
  2320 			 *
  2267 			 * @since 3.5.0
  2321 			 * @since 3.5.0
  2268 			 *
  2322 			 *
  2269 			 * @param int    $uid    ID of the nonce-owning user.
  2323 			 * @param int        $uid    ID of the nonce-owning user.
  2270 			 * @param string $action The nonce action.
  2324 			 * @param string|int $action The nonce action, or -1 if none was provided.
  2271 			 */
  2325 			 */
  2272 			$uid = apply_filters( 'nonce_user_logged_out', $uid, $action );
  2326 			$uid = apply_filters( 'nonce_user_logged_out', $uid, $action );
  2273 		}
  2327 		}
  2274 
  2328 
  2275 		if ( empty( $nonce ) ) {
  2329 		if ( empty( $nonce ) ) {
  2276 			return false;
  2330 			return false;
  2277 		}
  2331 		}
  2278 
  2332 
  2279 		$token = wp_get_session_token();
  2333 		$token = wp_get_session_token();
  2280 		$i     = wp_nonce_tick();
  2334 		$i     = wp_nonce_tick( $action );
  2281 
  2335 
  2282 		// Nonce generated 0-12 hours ago.
  2336 		// Nonce generated 0-12 hours ago.
  2283 		$expected = substr( wp_hash( $i . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), -12, 10 );
  2337 		$expected = substr( wp_hash( $i . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), -12, 10 );
  2284 		if ( hash_equals( $expected, $nonce ) ) {
  2338 		if ( hash_equals( $expected, $nonce ) ) {
  2285 			return 1;
  2339 			return 1;
  2312 	/**
  2366 	/**
  2313 	 * Creates a cryptographic token tied to a specific action, user, user session,
  2367 	 * Creates a cryptographic token tied to a specific action, user, user session,
  2314 	 * and window of time.
  2368 	 * and window of time.
  2315 	 *
  2369 	 *
  2316 	 * @since 2.0.3
  2370 	 * @since 2.0.3
  2317 	 * @since 4.0.0 Session tokens were integrated with nonce creation
  2371 	 * @since 4.0.0 Session tokens were integrated with nonce creation.
  2318 	 *
  2372 	 *
  2319 	 * @param string|int $action Scalar value to add context to the nonce.
  2373 	 * @param string|int $action Scalar value to add context to the nonce.
  2320 	 * @return string The token.
  2374 	 * @return string The token.
  2321 	 */
  2375 	 */
  2322 	function wp_create_nonce( $action = -1 ) {
  2376 	function wp_create_nonce( $action = -1 ) {
  2326 			/** This filter is documented in wp-includes/pluggable.php */
  2380 			/** This filter is documented in wp-includes/pluggable.php */
  2327 			$uid = apply_filters( 'nonce_user_logged_out', $uid, $action );
  2381 			$uid = apply_filters( 'nonce_user_logged_out', $uid, $action );
  2328 		}
  2382 		}
  2329 
  2383 
  2330 		$token = wp_get_session_token();
  2384 		$token = wp_get_session_token();
  2331 		$i     = wp_nonce_tick();
  2385 		$i     = wp_nonce_tick( $action );
  2332 
  2386 
  2333 		return substr( wp_hash( $i . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), -12, 10 );
  2387 		return substr( wp_hash( $i . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), -12, 10 );
  2334 	}
  2388 	}
  2335 endif;
  2389 endif;
  2336 
  2390 
  2362 	 *
  2416 	 *
  2363 	 * @since 2.5.0
  2417 	 * @since 2.5.0
  2364 	 *
  2418 	 *
  2365 	 * @link https://api.wordpress.org/secret-key/1.1/salt/ Create secrets for wp-config.php
  2419 	 * @link https://api.wordpress.org/secret-key/1.1/salt/ Create secrets for wp-config.php
  2366 	 *
  2420 	 *
  2367 	 * @param string $scheme Authentication scheme (auth, secure_auth, logged_in, nonce)
  2421 	 * @param string $scheme Authentication scheme (auth, secure_auth, logged_in, nonce).
  2368 	 * @return string Salt value
  2422 	 * @return string Salt value
  2369 	 */
  2423 	 */
  2370 	function wp_salt( $scheme = 'auth' ) {
  2424 	function wp_salt( $scheme = 'auth' ) {
  2371 		static $cached_salts = array();
  2425 		static $cached_salts = array();
  2372 		if ( isset( $cached_salts[ $scheme ] ) ) {
  2426 		if ( isset( $cached_salts[ $scheme ] ) ) {
  2382 			return apply_filters( 'salt', $cached_salts[ $scheme ], $scheme );
  2436 			return apply_filters( 'salt', $cached_salts[ $scheme ], $scheme );
  2383 		}
  2437 		}
  2384 
  2438 
  2385 		static $duplicated_keys;
  2439 		static $duplicated_keys;
  2386 		if ( null === $duplicated_keys ) {
  2440 		if ( null === $duplicated_keys ) {
  2387 			$duplicated_keys = array( 'put your unique phrase here' => true );
  2441 			$duplicated_keys = array(
       
  2442 				'put your unique phrase here' => true,
       
  2443 			);
       
  2444 
       
  2445 			/*
       
  2446 			 * translators: This string should only be translated if wp-config-sample.php is localized.
       
  2447 			 * You can check the localized release package or
       
  2448 			 * https://i18n.svn.wordpress.org/<locale code>/branches/<wp version>/dist/wp-config-sample.php
       
  2449 			 */
       
  2450 			$duplicated_keys[ __( 'put your unique phrase here' ) ] = true;
       
  2451 
  2388 			foreach ( array( 'AUTH', 'SECURE_AUTH', 'LOGGED_IN', 'NONCE', 'SECRET' ) as $first ) {
  2452 			foreach ( array( 'AUTH', 'SECURE_AUTH', 'LOGGED_IN', 'NONCE', 'SECRET' ) as $first ) {
  2389 				foreach ( array( 'KEY', 'SALT' ) as $second ) {
  2453 				foreach ( array( 'KEY', 'SALT' ) as $second ) {
  2390 					if ( ! defined( "{$first}_{$second}" ) ) {
  2454 					if ( ! defined( "{$first}_{$second}" ) ) {
  2391 						continue;
  2455 						continue;
  2392 					}
  2456 					}
  2438 	}
  2502 	}
  2439 endif;
  2503 endif;
  2440 
  2504 
  2441 if ( ! function_exists( 'wp_hash' ) ) :
  2505 if ( ! function_exists( 'wp_hash' ) ) :
  2442 	/**
  2506 	/**
  2443 	 * Get hash of given string.
  2507 	 * Gets hash of given string.
  2444 	 *
  2508 	 *
  2445 	 * @since 2.0.3
  2509 	 * @since 2.0.3
  2446 	 *
  2510 	 *
  2447 	 * @param string $data   Plain text to hash
  2511 	 * @param string $data   Plain text to hash.
  2448 	 * @param string $scheme Authentication scheme (auth, secure_auth, logged_in, nonce)
  2512 	 * @param string $scheme Authentication scheme (auth, secure_auth, logged_in, nonce).
  2449 	 * @return string Hash of $data
  2513 	 * @return string Hash of $data.
  2450 	 */
  2514 	 */
  2451 	function wp_hash( $data, $scheme = 'auth' ) {
  2515 	function wp_hash( $data, $scheme = 'auth' ) {
  2452 		$salt = wp_salt( $scheme );
  2516 		$salt = wp_salt( $scheme );
  2453 
  2517 
  2454 		return hash_hmac( 'md5', $data, $salt );
  2518 		return hash_hmac( 'md5', $data, $salt );
  2455 	}
  2519 	}
  2456 endif;
  2520 endif;
  2457 
  2521 
  2458 if ( ! function_exists( 'wp_hash_password' ) ) :
  2522 if ( ! function_exists( 'wp_hash_password' ) ) :
  2459 	/**
  2523 	/**
  2460 	 * Create a hash (encrypt) of a plain text password.
  2524 	 * Creates a hash (encrypt) of a plain text password.
  2461 	 *
  2525 	 *
  2462 	 * For integration with other applications, this function can be overwritten to
  2526 	 * For integration with other applications, this function can be overwritten to
  2463 	 * instead use the other package password checking algorithm.
  2527 	 * instead use the other package password checking algorithm.
  2464 	 *
  2528 	 *
  2465 	 * @since 2.5.0
  2529 	 * @since 2.5.0
  2466 	 *
  2530 	 *
  2467 	 * @global PasswordHash $wp_hasher PHPass object
  2531 	 * @global PasswordHash $wp_hasher PHPass object.
  2468 	 *
  2532 	 *
  2469 	 * @param string $password Plain text user password to hash
  2533 	 * @param string $password Plain text user password to hash.
  2470 	 * @return string The hash string of the password
  2534 	 * @return string The hash string of the password.
  2471 	 */
  2535 	 */
  2472 	function wp_hash_password( $password ) {
  2536 	function wp_hash_password( $password ) {
  2473 		global $wp_hasher;
  2537 		global $wp_hasher;
  2474 
  2538 
  2475 		if ( empty( $wp_hasher ) ) {
  2539 		if ( empty( $wp_hasher ) ) {
  2495 	 * instead use the other package password checking algorithm.
  2559 	 * instead use the other package password checking algorithm.
  2496 	 *
  2560 	 *
  2497 	 * @since 2.5.0
  2561 	 * @since 2.5.0
  2498 	 *
  2562 	 *
  2499 	 * @global PasswordHash $wp_hasher PHPass object used for checking the password
  2563 	 * @global PasswordHash $wp_hasher PHPass object used for checking the password
  2500 	 *                                 against the $hash + $password
  2564 	 *                                 against the $hash + $password.
  2501 	 * @uses PasswordHash::CheckPassword
  2565 	 * @uses PasswordHash::CheckPassword
  2502 	 *
  2566 	 *
  2503 	 * @param string     $password Plaintext user's password
  2567 	 * @param string     $password Plaintext user's password.
  2504 	 * @param string     $hash     Hash of the user's password to check against.
  2568 	 * @param string     $hash     Hash of the user's password to check against.
  2505 	 * @param string|int $user_id  Optional. User ID.
  2569 	 * @param string|int $user_id  Optional. User ID.
  2506 	 * @return bool False, if the $password does not match the hashed password
  2570 	 * @return bool False, if the $password does not match the hashed password.
  2507 	 */
  2571 	 */
  2508 	function wp_check_password( $password, $hash, $user_id = '' ) {
  2572 	function wp_check_password( $password, $hash, $user_id = '' ) {
  2509 		global $wp_hasher;
  2573 		global $wp_hasher;
  2510 
  2574 
  2511 		// If the hash is still md5...
  2575 		// If the hash is still md5...
  2528 			 * @param string|int $user_id  User ID. Can be empty.
  2592 			 * @param string|int $user_id  User ID. Can be empty.
  2529 			 */
  2593 			 */
  2530 			return apply_filters( 'check_password', $check, $password, $hash, $user_id );
  2594 			return apply_filters( 'check_password', $check, $password, $hash, $user_id );
  2531 		}
  2595 		}
  2532 
  2596 
  2533 		// If the stored hash is longer than an MD5,
  2597 		/*
  2534 		// presume the new style phpass portable hash.
  2598 		 * If the stored hash is longer than an MD5,
       
  2599 		 * presume the new style phpass portable hash.
       
  2600 		 */
  2535 		if ( empty( $wp_hasher ) ) {
  2601 		if ( empty( $wp_hasher ) ) {
  2536 			require_once ABSPATH . WPINC . '/class-phpass.php';
  2602 			require_once ABSPATH . WPINC . '/class-phpass.php';
  2537 			// By default, use the portable hash from phpass.
  2603 			// By default, use the portable hash from phpass.
  2538 			$wp_hasher = new PasswordHash( 8, true );
  2604 			$wp_hasher = new PasswordHash( 8, true );
  2539 		}
  2605 		}
  2547 
  2613 
  2548 if ( ! function_exists( 'wp_generate_password' ) ) :
  2614 if ( ! function_exists( 'wp_generate_password' ) ) :
  2549 	/**
  2615 	/**
  2550 	 * Generates a random password drawn from the defined set of characters.
  2616 	 * Generates a random password drawn from the defined set of characters.
  2551 	 *
  2617 	 *
  2552 	 * Uses wp_rand() is used to create passwords with far less predictability
  2618 	 * Uses wp_rand() to create passwords with far less predictability
  2553 	 * than similar native PHP functions like `rand()` or `mt_rand()`.
  2619 	 * than similar native PHP functions like `rand()` or `mt_rand()`.
  2554 	 *
  2620 	 *
  2555 	 * @since 2.5.0
  2621 	 * @since 2.5.0
  2556 	 *
  2622 	 *
  2557 	 * @param int  $length              Optional. The length of password to generate. Default 12.
  2623 	 * @param int  $length              Optional. The length of password to generate. Default 12.
  2590 	}
  2656 	}
  2591 endif;
  2657 endif;
  2592 
  2658 
  2593 if ( ! function_exists( 'wp_rand' ) ) :
  2659 if ( ! function_exists( 'wp_rand' ) ) :
  2594 	/**
  2660 	/**
  2595 	 * Generates a random number.
  2661 	 * Generates a random non-negative number.
  2596 	 *
  2662 	 *
  2597 	 * @since 2.6.2
  2663 	 * @since 2.6.2
  2598 	 * @since 4.4.0 Uses PHP7 random_int() or the random_compat library if available.
  2664 	 * @since 4.4.0 Uses PHP7 random_int() or the random_compat library if available.
       
  2665 	 * @since 6.1.0 Returns zero instead of a random number if both `$min` and `$max` are zero.
  2599 	 *
  2666 	 *
  2600 	 * @global string $rnd_value
  2667 	 * @global string $rnd_value
  2601 	 *
  2668 	 *
  2602 	 * @param int $min Lower limit for the generated number
  2669 	 * @param int $min Optional. Lower limit for the generated number.
  2603 	 * @param int $max Upper limit for the generated number
  2670 	 *                 Accepts positive integers or zero. Defaults to 0.
  2604 	 * @return int A random number between min and max
  2671 	 * @param int $max Optional. Upper limit for the generated number.
  2605 	 */
  2672 	 *                 Accepts positive integers. Defaults to 4294967295.
  2606 	function wp_rand( $min = 0, $max = 0 ) {
  2673 	 * @return int A random non-negative number between min and max.
       
  2674 	 */
       
  2675 	function wp_rand( $min = null, $max = null ) {
  2607 		global $rnd_value;
  2676 		global $rnd_value;
  2608 
  2677 
  2609 		// Some misconfigured 32-bit environments (Entropy PHP, for example)
  2678 		/*
  2610 		// truncate integers larger than PHP_INT_MAX to PHP_INT_MAX rather than overflowing them to floats.
  2679 		 * Some misconfigured 32-bit environments (Entropy PHP, for example)
       
  2680 		 * truncate integers larger than PHP_INT_MAX to PHP_INT_MAX rather than overflowing them to floats.
       
  2681 		 */
  2611 		$max_random_number = 3000000000 === 2147483647 ? (float) '4294967295' : 4294967295; // 4294967295 = 0xffffffff
  2682 		$max_random_number = 3000000000 === 2147483647 ? (float) '4294967295' : 4294967295; // 4294967295 = 0xffffffff
       
  2683 
       
  2684 		if ( null === $min ) {
       
  2685 			$min = 0;
       
  2686 		}
       
  2687 
       
  2688 		if ( null === $max ) {
       
  2689 			$max = $max_random_number;
       
  2690 		}
  2612 
  2691 
  2613 		// We only handle ints, floats are truncated to their integer value.
  2692 		// We only handle ints, floats are truncated to their integer value.
  2614 		$min = (int) $min;
  2693 		$min = (int) $min;
  2615 		$max = (int) $max;
  2694 		$max = (int) $max;
  2616 
  2695 
  2617 		// Use PHP's CSPRNG, or a compatible method.
  2696 		// Use PHP's CSPRNG, or a compatible method.
  2618 		static $use_random_int_functionality = true;
  2697 		static $use_random_int_functionality = true;
  2619 		if ( $use_random_int_functionality ) {
  2698 		if ( $use_random_int_functionality ) {
  2620 			try {
  2699 			try {
  2621 				$_max = ( 0 != $max ) ? $max : $max_random_number;
       
  2622 				// wp_rand() can accept arguments in either order, PHP cannot.
  2700 				// wp_rand() can accept arguments in either order, PHP cannot.
  2623 				$_max = max( $min, $_max );
  2701 				$_max = max( $min, $max );
  2624 				$_min = min( $min, $_max );
  2702 				$_min = min( $min, $max );
  2625 				$val  = random_int( $_min, $_max );
  2703 				$val  = random_int( $_min, $_max );
  2626 				if ( false !== $val ) {
  2704 				if ( false !== $val ) {
  2627 					return absint( $val );
  2705 					return absint( $val );
  2628 				} else {
  2706 				} else {
  2629 					$use_random_int_functionality = false;
  2707 					$use_random_int_functionality = false;
  2633 			} catch ( Exception $e ) {
  2711 			} catch ( Exception $e ) {
  2634 				$use_random_int_functionality = false;
  2712 				$use_random_int_functionality = false;
  2635 			}
  2713 			}
  2636 		}
  2714 		}
  2637 
  2715 
  2638 		// Reset $rnd_value after 14 uses.
  2716 		/*
  2639 		// 32 (md5) + 40 (sha1) + 40 (sha1) / 8 = 14 random numbers from $rnd_value.
  2717 		 * Reset $rnd_value after 14 uses.
       
  2718 		 * 32 (md5) + 40 (sha1) + 40 (sha1) / 8 = 14 random numbers from $rnd_value.
       
  2719 		 */
  2640 		if ( strlen( $rnd_value ) < 8 ) {
  2720 		if ( strlen( $rnd_value ) < 8 ) {
  2641 			if ( defined( 'WP_SETUP_CONFIG' ) ) {
  2721 			if ( defined( 'WP_SETUP_CONFIG' ) ) {
  2642 				static $seed = '';
  2722 				static $seed = '';
  2643 			} else {
  2723 			} else {
  2644 				$seed = get_transient( 'random_seed' );
  2724 				$seed = get_transient( 'random_seed' );
  2659 		$rnd_value = substr( $rnd_value, 8 );
  2739 		$rnd_value = substr( $rnd_value, 8 );
  2660 
  2740 
  2661 		$value = abs( hexdec( $value ) );
  2741 		$value = abs( hexdec( $value ) );
  2662 
  2742 
  2663 		// Reduce the value to be within the min - max range.
  2743 		// Reduce the value to be within the min - max range.
  2664 		if ( 0 != $max ) {
  2744 		$value = $min + ( $max - $min + 1 ) * $value / ( $max_random_number + 1 );
  2665 			$value = $min + ( $max - $min + 1 ) * $value / ( $max_random_number + 1 );
       
  2666 		}
       
  2667 
  2745 
  2668 		return abs( (int) $value );
  2746 		return abs( (int) $value );
  2669 	}
  2747 	}
  2670 endif;
  2748 endif;
  2671 
  2749 
  2682 	 *
  2760 	 *
  2683 	 * @since 2.5.0
  2761 	 * @since 2.5.0
  2684 	 *
  2762 	 *
  2685 	 * @global wpdb $wpdb WordPress database abstraction object.
  2763 	 * @global wpdb $wpdb WordPress database abstraction object.
  2686 	 *
  2764 	 *
  2687 	 * @param string $password The plaintext new user password
  2765 	 * @param string $password The plaintext new user password.
  2688 	 * @param int    $user_id  User ID
  2766 	 * @param int    $user_id  User ID.
  2689 	 */
  2767 	 */
  2690 	function wp_set_password( $password, $user_id ) {
  2768 	function wp_set_password( $password, $user_id ) {
  2691 		global $wpdb;
  2769 		global $wpdb;
  2692 
  2770 
  2693 		$hash = wp_hash_password( $password );
  2771 		$hash = wp_hash_password( $password );
  2699 			),
  2777 			),
  2700 			array( 'ID' => $user_id )
  2778 			array( 'ID' => $user_id )
  2701 		);
  2779 		);
  2702 
  2780 
  2703 		clean_user_cache( $user_id );
  2781 		clean_user_cache( $user_id );
       
  2782 
       
  2783 		/**
       
  2784 		 * Fires after the user password is set.
       
  2785 		 *
       
  2786 		 * @since 6.2.0
       
  2787 		 *
       
  2788 		 * @param string $password The plaintext password just set.
       
  2789 		 * @param int    $user_id  The ID of the user whose password was just set.
       
  2790 		 */
       
  2791 		do_action( 'wp_set_password', $password, $user_id );
  2704 	}
  2792 	}
  2705 endif;
  2793 endif;
  2706 
  2794 
  2707 if ( ! function_exists( 'get_avatar' ) ) :
  2795 if ( ! function_exists( 'get_avatar' ) ) :
  2708 	/**
  2796 	/**
  2709 	 * Retrieve the avatar `<img>` tag for a user, email address, MD5 hash, comment, or post.
  2797 	 * Retrieves the avatar `<img>` tag for a user, email address, MD5 hash, comment, or post.
  2710 	 *
  2798 	 *
  2711 	 * @since 2.5.0
  2799 	 * @since 2.5.0
  2712 	 * @since 4.2.0 Optional `$args` parameter added.
  2800 	 * @since 4.2.0 Added the optional `$args` parameter.
  2713 	 *
  2801 	 * @since 5.5.0 Added the `loading` argument.
  2714 	 * @param mixed  $id_or_email The Gravatar to retrieve. Accepts a user_id, gravatar md5 hash,
  2802 	 * @since 6.1.0 Added the `decoding` argument.
  2715 	 *                            user email, WP_User object, WP_Post object, or WP_Comment object.
  2803 	 * @since 6.3.0 Added the `fetchpriority` argument.
  2716 	 * @param int    $size        Optional. Height and width of the avatar image file in pixels. Default 96.
  2804 	 *
  2717 	 * @param string $default     Optional. URL for the default image or a default type. Accepts '404'
  2805 	 * @param mixed  $id_or_email   The avatar to retrieve. Accepts a user ID, Gravatar MD5 hash,
  2718 	 *                            (return a 404 instead of a default image), 'retro' (8bit), 'monsterid'
  2806 	 *                              user email, WP_User object, WP_Post object, or WP_Comment object.
  2719 	 *                            (monster), 'wavatar' (cartoon face), 'indenticon' (the "quilt"),
  2807 	 * @param int    $size          Optional. Height and width of the avatar in pixels. Default 96.
  2720 	 *                            'mystery', 'mm', or 'mysteryman' (The Oyster Man), 'blank' (transparent GIF),
  2808 	 * @param string $default_value URL for the default image or a default type. Accepts:
  2721 	 *                            or 'gravatar_default' (the Gravatar logo). Default is the value of the
  2809 	 *                              - '404' (return a 404 instead of a default image)
  2722 	 *                            'avatar_default' option, with a fallback of 'mystery'.
  2810 	 *                              - 'retro' (a 8-bit arcade-style pixelated face)
  2723 	 * @param string $alt         Optional. Alternative text to use in img tag. Default empty.
  2811 	 *                              - 'robohash' (a robot)
       
  2812 	 *                              - 'monsterid' (a monster)
       
  2813 	 *                              - 'wavatar' (a cartoon face)
       
  2814 	 *                              - 'identicon' (the "quilt", a geometric pattern)
       
  2815 	 *                              - 'mystery', 'mm', or 'mysteryman' (The Oyster Man)
       
  2816 	 *                              - 'blank' (transparent GIF)
       
  2817 	 *                              - 'gravatar_default' (the Gravatar logo)
       
  2818 	 *                              Default is the value of the 'avatar_default' option,
       
  2819 	 *                              with a fallback of 'mystery'.
       
  2820 	 * @param string $alt           Optional. Alternative text to use in the avatar image tag.
       
  2821 	 *                              Default empty.
  2724 	 * @param array  $args {
  2822 	 * @param array  $args {
  2725 	 *     Optional. Extra arguments to retrieve the avatar.
  2823 	 *     Optional. Extra arguments to retrieve the avatar.
  2726 	 *
  2824 	 *
  2727 	 *     @type int          $height        Display height of the avatar in pixels. Defaults to $size.
  2825 	 *     @type int          $height        Display height of the avatar in pixels. Defaults to $size.
  2728 	 *     @type int          $width         Display width of the avatar in pixels. Defaults to $size.
  2826 	 *     @type int          $width         Display width of the avatar in pixels. Defaults to $size.
  2729 	 *     @type bool         $force_default Whether to always show the default image, never the Gravatar. Default false.
  2827 	 *     @type bool         $force_default Whether to always show the default image, never the Gravatar.
  2730 	 *     @type string       $rating        What rating to display avatars up to. Accepts 'G', 'PG', 'R', 'X', and are
  2828 	 *                                       Default false.
  2731 	 *                                       judged in that order. Default is the value of the 'avatar_rating' option.
  2829 	 *     @type string       $rating        What rating to display avatars up to. Accepts:
       
  2830 	 *                                       - 'G' (suitable for all audiences)
       
  2831 	 *                                       - 'PG' (possibly offensive, usually for audiences 13 and above)
       
  2832 	 *                                       - 'R' (intended for adult audiences above 17)
       
  2833 	 *                                       - 'X' (even more mature than above)
       
  2834 	 *                                       Default is the value of the 'avatar_rating' option.
  2732 	 *     @type string       $scheme        URL scheme to use. See set_url_scheme() for accepted values.
  2835 	 *     @type string       $scheme        URL scheme to use. See set_url_scheme() for accepted values.
  2733 	 *                                       Default null.
  2836 	 *                                       Default null.
  2734 	 *     @type array|string $class         Array or string of additional classes to add to the img element.
  2837 	 *     @type array|string $class         Array or string of additional classes to add to the img element.
  2735 	 *                                       Default null.
  2838 	 *                                       Default null.
  2736 	 *     @type bool         $force_display Whether to always show the avatar - ignores the show_avatars option.
  2839 	 *     @type bool         $force_display Whether to always show the avatar - ignores the show_avatars option.
  2737 	 *                                       Default false.
  2840 	 *                                       Default false.
  2738 	 *     @type string       $loading       Value for the `loading` attribute.
  2841 	 *     @type string       $loading       Value for the `loading` attribute.
  2739 	 *                                       Default null.
  2842 	 *                                       Default null.
  2740 	 *     @type string       $extra_attr    HTML attributes to insert in the IMG element. Is not sanitized. Default empty.
  2843 	 *     @type string       $fetchpriority Value for the `fetchpriority` attribute.
       
  2844 	 *                                       Default null.
       
  2845 	 *     @type string       $decoding      Value for the `decoding` attribute.
       
  2846 	 *                                       Default null.
       
  2847 	 *     @type string       $extra_attr    HTML attributes to insert in the IMG element. Is not sanitized.
       
  2848 	 *                                       Default empty.
  2741 	 * }
  2849 	 * }
  2742 	 * @return string|false `<img>` tag for the user's avatar. False on failure.
  2850 	 * @return string|false `<img>` tag for the user's avatar. False on failure.
  2743 	 */
  2851 	 */
  2744 	function get_avatar( $id_or_email, $size = 96, $default = '', $alt = '', $args = null ) {
  2852 	function get_avatar( $id_or_email, $size = 96, $default_value = '', $alt = '', $args = null ) {
  2745 		$defaults = array(
  2853 		$defaults = array(
  2746 			// get_avatar_data() args.
  2854 			// get_avatar_data() args.
  2747 			'size'          => 96,
  2855 			'size'          => 96,
  2748 			'height'        => null,
  2856 			'height'        => null,
  2749 			'width'         => null,
  2857 			'width'         => null,
  2753 			'scheme'        => null,
  2861 			'scheme'        => null,
  2754 			'alt'           => '',
  2862 			'alt'           => '',
  2755 			'class'         => null,
  2863 			'class'         => null,
  2756 			'force_display' => false,
  2864 			'force_display' => false,
  2757 			'loading'       => null,
  2865 			'loading'       => null,
       
  2866 			'fetchpriority' => null,
       
  2867 			'decoding'      => null,
  2758 			'extra_attr'    => '',
  2868 			'extra_attr'    => '',
  2759 		);
  2869 		);
  2760 
  2870 
  2761 		if ( wp_lazy_loading_enabled( 'img', 'get_avatar' ) ) {
       
  2762 			$defaults['loading'] = wp_get_loading_attr_default( 'get_avatar' );
       
  2763 		}
       
  2764 
       
  2765 		if ( empty( $args ) ) {
  2871 		if ( empty( $args ) ) {
  2766 			$args = array();
  2872 			$args = array();
  2767 		}
  2873 		}
  2768 
  2874 
  2769 		$args['size']    = (int) $size;
  2875 		$args['size']    = (int) $size;
  2770 		$args['default'] = $default;
  2876 		$args['default'] = $default_value;
  2771 		$args['alt']     = $alt;
  2877 		$args['alt']     = $alt;
  2772 
  2878 
  2773 		$args = wp_parse_args( $args, $defaults );
  2879 		$args = wp_parse_args( $args, $defaults );
  2774 
  2880 
  2775 		if ( empty( $args['height'] ) ) {
  2881 		if ( empty( $args['height'] ) ) {
  2777 		}
  2883 		}
  2778 		if ( empty( $args['width'] ) ) {
  2884 		if ( empty( $args['width'] ) ) {
  2779 			$args['width'] = $args['size'];
  2885 			$args['width'] = $args['size'];
  2780 		}
  2886 		}
  2781 
  2887 
       
  2888 		// Update args with loading optimized attributes.
       
  2889 		$loading_optimization_attr = wp_get_loading_optimization_attributes( 'img', $args, 'get_avatar' );
       
  2890 
       
  2891 		$args = array_merge( $args, $loading_optimization_attr );
       
  2892 
  2782 		if ( is_object( $id_or_email ) && isset( $id_or_email->comment_ID ) ) {
  2893 		if ( is_object( $id_or_email ) && isset( $id_or_email->comment_ID ) ) {
  2783 			$id_or_email = get_comment( $id_or_email );
  2894 			$id_or_email = get_comment( $id_or_email );
  2784 		}
  2895 		}
  2785 
  2896 
  2786 		/**
  2897 		/**
  2790 		 * the value through the {@see 'get_avatar'} filter and returning early.
  2901 		 * the value through the {@see 'get_avatar'} filter and returning early.
  2791 		 *
  2902 		 *
  2792 		 * @since 4.2.0
  2903 		 * @since 4.2.0
  2793 		 *
  2904 		 *
  2794 		 * @param string|null $avatar      HTML for the user's avatar. Default null.
  2905 		 * @param string|null $avatar      HTML for the user's avatar. Default null.
  2795 		 * @param mixed       $id_or_email The avatar to retrieve. Accepts a user_id, Gravatar MD5 hash,
  2906 		 * @param mixed       $id_or_email The avatar to retrieve. Accepts a user ID, Gravatar MD5 hash,
  2796 		 *                                 user email, WP_User object, WP_Post object, or WP_Comment object.
  2907 		 *                                 user email, WP_User object, WP_Post object, or WP_Comment object.
  2797 		 * @param array       $args        Arguments passed to get_avatar_url(), after processing.
  2908 		 * @param array       $args        Arguments passed to get_avatar_url(), after processing.
  2798 		 */
  2909 		 */
  2799 		$avatar = apply_filters( 'pre_get_avatar', null, $id_or_email, $args );
  2910 		$avatar = apply_filters( 'pre_get_avatar', null, $id_or_email, $args );
  2800 
  2911 
  2829 			} else {
  2940 			} else {
  2830 				$class[] = $args['class'];
  2941 				$class[] = $args['class'];
  2831 			}
  2942 			}
  2832 		}
  2943 		}
  2833 
  2944 
  2834 		// Add `loading` attribute.
  2945 		// Add `loading`, `fetchpriority`, and `decoding` attributes.
  2835 		$extra_attr = $args['extra_attr'];
  2946 		$extra_attr = $args['extra_attr'];
  2836 		$loading    = $args['loading'];
  2947 
  2837 
  2948 		if ( in_array( $args['loading'], array( 'lazy', 'eager' ), true )
  2838 		if ( in_array( $loading, array( 'lazy', 'eager' ), true ) && ! preg_match( '/\bloading\s*=/', $extra_attr ) ) {
  2949 			&& ! preg_match( '/\bloading\s*=/', $extra_attr )
       
  2950 		) {
  2839 			if ( ! empty( $extra_attr ) ) {
  2951 			if ( ! empty( $extra_attr ) ) {
  2840 				$extra_attr .= ' ';
  2952 				$extra_attr .= ' ';
  2841 			}
  2953 			}
  2842 
  2954 
  2843 			$extra_attr .= "loading='{$loading}'";
  2955 			$extra_attr .= "loading='{$args['loading']}'";
       
  2956 		}
       
  2957 
       
  2958 		if ( in_array( $args['fetchpriority'], array( 'high', 'low', 'auto' ), true )
       
  2959 			&& ! preg_match( '/\bfetchpriority\s*=/', $extra_attr )
       
  2960 		) {
       
  2961 			if ( ! empty( $extra_attr ) ) {
       
  2962 				$extra_attr .= ' ';
       
  2963 			}
       
  2964 
       
  2965 			$extra_attr .= "fetchpriority='{$args['fetchpriority']}'";
       
  2966 		}
       
  2967 
       
  2968 		if ( in_array( $args['decoding'], array( 'async', 'sync', 'auto' ), true )
       
  2969 			&& ! preg_match( '/\bdecoding\s*=/', $extra_attr )
       
  2970 		) {
       
  2971 			if ( ! empty( $extra_attr ) ) {
       
  2972 				$extra_attr .= ' ';
       
  2973 			}
       
  2974 
       
  2975 			$extra_attr .= "decoding='{$args['decoding']}'";
  2844 		}
  2976 		}
  2845 
  2977 
  2846 		$avatar = sprintf(
  2978 		$avatar = sprintf(
  2847 			"<img alt='%s' src='%s' srcset='%s' class='%s' height='%d' width='%d' %s/>",
  2979 			"<img alt='%s' src='%s' srcset='%s' class='%s' height='%d' width='%d' %s/>",
  2848 			esc_attr( $args['alt'] ),
  2980 			esc_attr( $args['alt'] ),
  2856 
  2988 
  2857 		/**
  2989 		/**
  2858 		 * Filters the HTML for a user's avatar.
  2990 		 * Filters the HTML for a user's avatar.
  2859 		 *
  2991 		 *
  2860 		 * @since 2.5.0
  2992 		 * @since 2.5.0
  2861 		 * @since 4.2.0 The `$args` parameter was added.
  2993 		 * @since 4.2.0 Added the `$args` parameter.
  2862 		 *
  2994 		 *
  2863 		 * @param string $avatar      HTML for the user's avatar.
  2995 		 * @param string $avatar        HTML for the user's avatar.
  2864 		 * @param mixed  $id_or_email The avatar to retrieve. Accepts a user_id, Gravatar MD5 hash,
  2996 		 * @param mixed  $id_or_email   The avatar to retrieve. Accepts a user ID, Gravatar MD5 hash,
  2865 		 *                            user email, WP_User object, WP_Post object, or WP_Comment object.
  2997 		 *                              user email, WP_User object, WP_Post object, or WP_Comment object.
  2866 		 * @param int    $size        Square avatar width and height in pixels to retrieve.
  2998 		 * @param int    $size          Height and width of the avatar in pixels.
  2867 		 * @param string $default     URL for the default image or a default type. Accepts '404', 'retro', 'monsterid',
  2999 		 * @param string $default_value URL for the default image or a default type. Accepts:
  2868 		 *                            'wavatar', 'indenticon', 'mystery', 'mm', 'mysteryman', 'blank', or 'gravatar_default'.
  3000 		 *                              - '404' (return a 404 instead of a default image)
  2869 		 * @param string $alt         Alternative text to use in the avatar image tag.
  3001 		 *                              - 'retro' (a 8-bit arcade-style pixelated face)
  2870 		 * @param array  $args        Arguments passed to get_avatar_data(), after processing.
  3002 		 *                              - 'robohash' (a robot)
       
  3003 		 *                              - 'monsterid' (a monster)
       
  3004 		 *                              - 'wavatar' (a cartoon face)
       
  3005 		 *                              - 'identicon' (the "quilt", a geometric pattern)
       
  3006 		 *                              - 'mystery', 'mm', or 'mysteryman' (The Oyster Man)
       
  3007 		 *                              - 'blank' (transparent GIF)
       
  3008 		 *                              - 'gravatar_default' (the Gravatar logo)
       
  3009 		 * @param string $alt           Alternative text to use in the avatar image tag.
       
  3010 		 * @param array  $args          Arguments passed to get_avatar_data(), after processing.
  2871 		 */
  3011 		 */
  2872 		return apply_filters( 'get_avatar', $avatar, $id_or_email, $args['size'], $args['default'], $args['alt'], $args );
  3012 		return apply_filters( 'get_avatar', $avatar, $id_or_email, $args['size'], $args['default'], $args['alt'], $args );
  2873 	}
  3013 	}
  2874 endif;
  3014 endif;
  2875 
  3015 
  2885 	 *
  3025 	 *
  2886 	 * @see wp_parse_args() Used to change defaults to user defined settings.
  3026 	 * @see wp_parse_args() Used to change defaults to user defined settings.
  2887 	 * @uses Text_Diff
  3027 	 * @uses Text_Diff
  2888 	 * @uses WP_Text_Diff_Renderer_Table
  3028 	 * @uses WP_Text_Diff_Renderer_Table
  2889 	 *
  3029 	 *
  2890 	 * @param string       $left_string  "old" (left) version of string
  3030 	 * @param string       $left_string  "old" (left) version of string.
  2891 	 * @param string       $right_string "new" (right) version of string
  3031 	 * @param string       $right_string "new" (right) version of string.
  2892 	 * @param string|array $args {
  3032 	 * @param string|array $args {
  2893 	 *     Associative array of options to pass to WP_Text_Diff_Renderer_Table().
  3033 	 *     Associative array of options to pass to WP_Text_Diff_Renderer_Table().
  2894 	 *
  3034 	 *
  2895 	 *     @type string $title           Titles the diff in a manner compatible
  3035 	 *     @type string $title           Titles the diff in a manner compatible
  2896 	 *                                   with the output. Default empty.
  3036 	 *                                   with the output. Default empty.