wp/wp-includes/functions.php
changeset 21 48c4eec2b7e6
parent 19 3d72ae0968f4
child 22 8c2e4d02f4ef
equal deleted inserted replaced
20:7b1b88e27a20 21:48c4eec2b7e6
     6  */
     6  */
     7 
     7 
     8 require ABSPATH . WPINC . '/option.php';
     8 require ABSPATH . WPINC . '/option.php';
     9 
     9 
    10 /**
    10 /**
    11  * Convert given MySQL date string into a different format.
    11  * Converts given MySQL date string into a different format.
    12  *
    12  *
    13  *  - `$format` should be a PHP date format string.
    13  *  - `$format` should be a PHP date format string.
    14  *  - 'U' and 'G' formats will return an integer sum of timestamp with timezone offset.
    14  *  - 'U' and 'G' formats will return an integer sum of timestamp with timezone offset.
    15  *  - `$date` is expected to be local time in MySQL format (`Y-m-d H:i:s`).
    15  *  - `$date` is expected to be local time in MySQL format (`Y-m-d H:i:s`).
    16  *
    16  *
    30 function mysql2date( $format, $date, $translate = true ) {
    30 function mysql2date( $format, $date, $translate = true ) {
    31 	if ( empty( $date ) ) {
    31 	if ( empty( $date ) ) {
    32 		return false;
    32 		return false;
    33 	}
    33 	}
    34 
    34 
    35 	$datetime = date_create( $date, wp_timezone() );
    35 	$timezone = wp_timezone();
       
    36 	$datetime = date_create( $date, $timezone );
    36 
    37 
    37 	if ( false === $datetime ) {
    38 	if ( false === $datetime ) {
    38 		return false;
    39 		return false;
    39 	}
    40 	}
    40 
    41 
    42 	if ( 'G' === $format || 'U' === $format ) {
    43 	if ( 'G' === $format || 'U' === $format ) {
    43 		return $datetime->getTimestamp() + $datetime->getOffset();
    44 		return $datetime->getTimestamp() + $datetime->getOffset();
    44 	}
    45 	}
    45 
    46 
    46 	if ( $translate ) {
    47 	if ( $translate ) {
    47 		return wp_date( $format, $datetime->getTimestamp() );
    48 		return wp_date( $format, $datetime->getTimestamp(), $timezone );
    48 	}
    49 	}
    49 
    50 
    50 	return $datetime->format( $format );
    51 	return $datetime->format( $format );
    51 }
    52 }
    52 
    53 
   160  * the timestamp represents. Storing such timestamps or calculating them differently
   161  * the timestamp represents. Storing such timestamps or calculating them differently
   161  * will lead to invalid output.
   162  * will lead to invalid output.
   162  *
   163  *
   163  * @since 0.71
   164  * @since 0.71
   164  * @since 5.3.0 Converted into a wrapper for wp_date().
   165  * @since 5.3.0 Converted into a wrapper for wp_date().
   165  *
       
   166  * @global WP_Locale $wp_locale WordPress date and time locale object.
       
   167  *
   166  *
   168  * @param string   $format                Format to display the date.
   167  * @param string   $format                Format to display the date.
   169  * @param int|bool $timestamp_with_offset Optional. A sum of Unix timestamp and timezone offset
   168  * @param int|bool $timestamp_with_offset Optional. A sum of Unix timestamp and timezone offset
   170  *                                        in seconds. Default false.
   169  *                                        in seconds. Default false.
   171  * @param bool     $gmt                   Optional. Whether to use GMT timezone. Only applies
   170  * @param bool     $gmt                   Optional. Whether to use GMT timezone. Only applies
   262 		$new_format    = '';
   261 		$new_format    = '';
   263 		$format_length = strlen( $format );
   262 		$format_length = strlen( $format );
   264 		$month         = $wp_locale->get_month( $datetime->format( 'm' ) );
   263 		$month         = $wp_locale->get_month( $datetime->format( 'm' ) );
   265 		$weekday       = $wp_locale->get_weekday( $datetime->format( 'w' ) );
   264 		$weekday       = $wp_locale->get_weekday( $datetime->format( 'w' ) );
   266 
   265 
   267 		for ( $i = 0; $i < $format_length; $i ++ ) {
   266 		for ( $i = 0; $i < $format_length; $i++ ) {
   268 			switch ( $format[ $i ] ) {
   267 			switch ( $format[ $i ] ) {
   269 				case 'D':
   268 				case 'D':
   270 					$new_format .= addcslashes( $wp_locale->get_weekday_abbrev( $weekday ), '\\A..Za..z' );
   269 					$new_format .= addcslashes( $wp_locale->get_weekday_abbrev( $weekday ), '\\A..Za..z' );
   271 					break;
   270 					break;
   272 				case 'F':
   271 				case 'F':
   406 
   405 
   407 	return $date;
   406 	return $date;
   408 }
   407 }
   409 
   408 
   410 /**
   409 /**
   411  * Convert float number to format based on the locale.
   410  * Converts float number to format based on the locale.
   412  *
   411  *
   413  * @since 2.3.0
   412  * @since 2.3.0
   414  *
   413  *
   415  * @global WP_Locale $wp_locale WordPress date and time locale object.
   414  * @global WP_Locale $wp_locale WordPress date and time locale object.
   416  *
   415  *
   496 
   495 
   497 	return false;
   496 	return false;
   498 }
   497 }
   499 
   498 
   500 /**
   499 /**
   501  * Convert a duration to human readable format.
   500  * Converts a duration to human readable format.
   502  *
   501  *
   503  * @since 5.1.0
   502  * @since 5.1.0
   504  *
   503  *
   505  * @param string $duration Duration will be in string format (HH:ii:ss) OR (ii:ss),
   504  * @param string $duration Duration will be in string format (HH:ii:ss) OR (ii:ss),
   506  *                         with a possible prepended negative sign (-).
   505  *                         with a possible prepended negative sign (-).
   512 	}
   511 	}
   513 
   512 
   514 	$duration = trim( $duration );
   513 	$duration = trim( $duration );
   515 
   514 
   516 	// Remove prepended negative sign.
   515 	// Remove prepended negative sign.
   517 	if ( '-' === substr( $duration, 0, 1 ) ) {
   516 	if ( str_starts_with( $duration, '-' ) ) {
   518 		$duration = substr( $duration, 1 );
   517 		$duration = substr( $duration, 1 );
   519 	}
   518 	}
   520 
   519 
   521 	// Extract duration parts.
   520 	// Extract duration parts.
   522 	$duration_parts = array_reverse( explode( ':', $duration ) );
   521 	$duration_parts = array_reverse( explode( ':', $duration ) );
   566 
   565 
   567 	return implode( ', ', $human_readable_duration );
   566 	return implode( ', ', $human_readable_duration );
   568 }
   567 }
   569 
   568 
   570 /**
   569 /**
   571  * Get the week start and end from the datetime or date string from MySQL.
   570  * Gets the week start and end from the datetime or date string from MySQL.
   572  *
   571  *
   573  * @since 0.71
   572  * @since 0.71
   574  *
   573  *
   575  * @param string     $mysqlstring   Date or datetime field type from MySQL.
   574  * @param string     $mysqlstring   Date or datetime field type from MySQL.
   576  * @param int|string $start_of_week Optional. Start of the week as an integer. Default empty string.
   575  * @param int|string $start_of_week Optional. Start of the week as an integer. Default empty string.
   612 	$end = $start + WEEK_IN_SECONDS - 1;
   611 	$end = $start + WEEK_IN_SECONDS - 1;
   613 	return compact( 'start', 'end' );
   612 	return compact( 'start', 'end' );
   614 }
   613 }
   615 
   614 
   616 /**
   615 /**
   617  * Serialize data, if needed.
   616  * Serializes data, if needed.
   618  *
   617  *
   619  * @since 2.0.5
   618  * @since 2.0.5
   620  *
   619  *
   621  * @param string|array|object $data Data that might be serialized.
   620  * @param string|array|object $data Data that might be serialized.
   622  * @return mixed A scalar data.
   621  * @return mixed A scalar data.
   637 
   636 
   638 	return $data;
   637 	return $data;
   639 }
   638 }
   640 
   639 
   641 /**
   640 /**
   642  * Unserialize data only if it was serialized.
   641  * Unserializes data only if it was serialized.
   643  *
   642  *
   644  * @since 2.0.0
   643  * @since 2.0.0
   645  *
   644  *
   646  * @param string $data Data that might be unserialized.
   645  * @param string $data Data that might be unserialized.
   647  * @return mixed Unserialized data can be any type.
   646  * @return mixed Unserialized data can be any type.
   653 
   652 
   654 	return $data;
   653 	return $data;
   655 }
   654 }
   656 
   655 
   657 /**
   656 /**
   658  * Check value to find if it was serialized.
   657  * Checks value to find if it was serialized.
   659  *
   658  *
   660  * If $data is not an string, then returned value will always be false.
   659  * If $data is not a string, then returned value will always be false.
   661  * Serialized data is always a string.
   660  * Serialized data is always a string.
   662  *
   661  *
   663  * @since 2.0.5
   662  * @since 2.0.5
       
   663  * @since 6.1.0 Added Enum support.
   664  *
   664  *
   665  * @param string $data   Value to check to see if was serialized.
   665  * @param string $data   Value to check to see if was serialized.
   666  * @param bool   $strict Optional. Whether to be strict about the end of the string. Default true.
   666  * @param bool   $strict Optional. Whether to be strict about the end of the string. Default true.
   667  * @return bool False if not serialized and true if it was.
   667  * @return bool False if not serialized and true if it was.
   668  */
   668  */
   706 		case 's':
   706 		case 's':
   707 			if ( $strict ) {
   707 			if ( $strict ) {
   708 				if ( '"' !== substr( $data, -2, 1 ) ) {
   708 				if ( '"' !== substr( $data, -2, 1 ) ) {
   709 					return false;
   709 					return false;
   710 				}
   710 				}
   711 			} elseif ( false === strpos( $data, '"' ) ) {
   711 			} elseif ( ! str_contains( $data, '"' ) ) {
   712 				return false;
   712 				return false;
   713 			}
   713 			}
   714 			// Or else fall through.
   714 			// Or else fall through.
   715 		case 'a':
   715 		case 'a':
   716 		case 'O':
   716 		case 'O':
       
   717 		case 'E':
   717 			return (bool) preg_match( "/^{$token}:[0-9]+:/s", $data );
   718 			return (bool) preg_match( "/^{$token}:[0-9]+:/s", $data );
   718 		case 'b':
   719 		case 'b':
   719 		case 'i':
   720 		case 'i':
   720 		case 'd':
   721 		case 'd':
   721 			$end = $strict ? '$' : '';
   722 			$end = $strict ? '$' : '';
   723 	}
   724 	}
   724 	return false;
   725 	return false;
   725 }
   726 }
   726 
   727 
   727 /**
   728 /**
   728  * Check whether serialized data is of string type.
   729  * Checks whether serialized data is of string type.
   729  *
   730  *
   730  * @since 2.0.5
   731  * @since 2.0.5
   731  *
   732  *
   732  * @param string $data Serialized data.
   733  * @param string $data Serialized data.
   733  * @return bool False if not a serialized string, true if it is.
   734  * @return bool False if not a serialized string, true if it is.
   740 	$data = trim( $data );
   741 	$data = trim( $data );
   741 	if ( strlen( $data ) < 4 ) {
   742 	if ( strlen( $data ) < 4 ) {
   742 		return false;
   743 		return false;
   743 	} elseif ( ':' !== $data[1] ) {
   744 	} elseif ( ':' !== $data[1] ) {
   744 		return false;
   745 		return false;
   745 	} elseif ( ';' !== substr( $data, -1 ) ) {
   746 	} elseif ( ! str_ends_with( $data, ';' ) ) {
   746 		return false;
   747 		return false;
   747 	} elseif ( 's' !== $data[0] ) {
   748 	} elseif ( 's' !== $data[0] ) {
   748 		return false;
   749 		return false;
   749 	} elseif ( '"' !== substr( $data, -2, 1 ) ) {
   750 	} elseif ( '"' !== substr( $data, -2, 1 ) ) {
   750 		return false;
   751 		return false;
   752 		return true;
   753 		return true;
   753 	}
   754 	}
   754 }
   755 }
   755 
   756 
   756 /**
   757 /**
   757  * Retrieve post title from XMLRPC XML.
   758  * Retrieves post title from XMLRPC XML.
   758  *
   759  *
   759  * If the title element is not part of the XML, then the default post title from
   760  * If the title element is not part of the XML, then the default post title from
   760  * the $post_default_title will be used instead.
   761  * the $post_default_title will be used instead.
   761  *
   762  *
   762  * @since 0.71
   763  * @since 0.71
   775 	}
   776 	}
   776 	return $post_title;
   777 	return $post_title;
   777 }
   778 }
   778 
   779 
   779 /**
   780 /**
   780  * Retrieve the post category or categories from XMLRPC XML.
   781  * Retrieves the post category or categories from XMLRPC XML.
   781  *
   782  *
   782  * If the category element is not found, then the default post category will be
   783  * If the category element is not found, then the default post category will be
   783  * used. The return type then would be what $post_default_category. If the
   784  * used. The return type then would be what $post_default_category. If the
   784  * category is found, then it will always be an array.
   785  * category is found, then it will always be an array.
   785  *
   786  *
   815 	$content = trim( $content );
   816 	$content = trim( $content );
   816 	return $content;
   817 	return $content;
   817 }
   818 }
   818 
   819 
   819 /**
   820 /**
   820  * Use RegEx to extract URLs from arbitrary content.
   821  * Uses RegEx to extract URLs from arbitrary content.
   821  *
   822  *
   822  * @since 3.7.0
   823  * @since 3.7.0
   823  * @since 6.0.0 Fixes support for HTML entities (Trac 30580).
   824  * @since 6.0.0 Fixes support for HTML entities (Trac 30580).
   824  *
   825  *
   825  * @param string $content Content to extract URLs from.
   826  * @param string $content Content to extract URLs from.
   843 		$post_links
   844 		$post_links
   844 	);
   845 	);
   845 
   846 
   846 	$post_links = array_unique(
   847 	$post_links = array_unique(
   847 		array_map(
   848 		array_map(
   848 			static function( $link ) {
   849 			static function ( $link ) {
   849 				// Decode to replace valid entities, like &amp;.
   850 				// Decode to replace valid entities, like &amp;.
   850 				$link = html_entity_decode( $link );
   851 				$link = html_entity_decode( $link );
   851 				// Maintain backward compatibility by removing extraneous semi-colons (`;`).
   852 				// Maintain backward compatibility by removing extraneous semi-colons (`;`).
   852 				return str_replace( ';', '', $link );
   853 				return str_replace( ';', '', $link );
   853 			},
   854 			},
   857 
   858 
   858 	return array_values( $post_links );
   859 	return array_values( $post_links );
   859 }
   860 }
   860 
   861 
   861 /**
   862 /**
   862  * Check content for video and audio links to add as enclosures.
   863  * Checks content for video and audio links to add as enclosures.
   863  *
   864  *
   864  * Will not add enclosures that have already been added and will
   865  * Will not add enclosures that have already been added and will
   865  * remove enclosures that are no longer in the post. This is called as
   866  * remove enclosures that are no longer in the post. This is called as
   866  * pingbacks and trackbacks.
   867  * pingbacks and trackbacks.
   867  *
   868  *
   879  */
   880  */
   880 function do_enclose( $content, $post ) {
   881 function do_enclose( $content, $post ) {
   881 	global $wpdb;
   882 	global $wpdb;
   882 
   883 
   883 	// @todo Tidy this code and make the debug code optional.
   884 	// @todo Tidy this code and make the debug code optional.
   884 	include_once ABSPATH . WPINC . '/class-IXR.php';
   885 	require_once ABSPATH . WPINC . '/class-IXR.php';
   885 
   886 
   886 	$post = get_post( $post );
   887 	$post = get_post( $post );
   887 	if ( ! $post ) {
   888 	if ( ! $post ) {
   888 		return false;
   889 		return false;
   889 	}
   890 	}
   930 	 * to postmeta before checking the database for existing enclosures.
   931 	 * to postmeta before checking the database for existing enclosures.
   931 	 *
   932 	 *
   932 	 * @since 4.4.0
   933 	 * @since 4.4.0
   933 	 *
   934 	 *
   934 	 * @param string[] $post_links An array of enclosure links.
   935 	 * @param string[] $post_links An array of enclosure links.
   935 	 * @param int      $post_ID    Post ID.
   936 	 * @param int      $post_id    Post ID.
   936 	 */
   937 	 */
   937 	$post_links = apply_filters( 'enclosure_links', $post_links, $post->ID );
   938 	$post_links = apply_filters( 'enclosure_links', $post_links, $post->ID );
   938 
   939 
   939 	foreach ( (array) $post_links as $url ) {
   940 	foreach ( (array) $post_links as $url ) {
   940 		$url = strip_fragment_from_url( $url );
   941 		$url = strip_fragment_from_url( $url );
   941 
   942 
   942 		if ( '' !== $url && ! $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE %s", $post->ID, $wpdb->esc_like( $url ) . '%' ) ) ) {
   943 		if ( '' !== $url && ! $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE %s", $post->ID, $wpdb->esc_like( $url ) . '%' ) ) ) {
   943 
   944 
   944 			$headers = wp_get_http_headers( $url );
   945 			$headers = wp_get_http_headers( $url );
   945 			if ( $headers ) {
   946 			if ( $headers ) {
   946 				$len           = isset( $headers['content-length'] ) ? (int) $headers['content-length'] : 0;
   947 				$len           = isset( $headers['Content-Length'] ) ? (int) $headers['Content-Length'] : 0;
   947 				$type          = isset( $headers['content-type'] ) ? $headers['content-type'] : '';
   948 				$type          = isset( $headers['Content-Type'] ) ? $headers['Content-Type'] : '';
   948 				$allowed_types = array( 'video', 'audio' );
   949 				$allowed_types = array( 'video', 'audio' );
   949 
   950 
   950 				// Check to see if we can figure out the mime type from the extension.
   951 				// Check to see if we can figure out the mime type from the extension.
   951 				$url_parts = parse_url( $url );
   952 				$url_parts = parse_url( $url );
   952 				if ( false !== $url_parts && ! empty( $url_parts['path'] ) ) {
   953 				if ( false !== $url_parts && ! empty( $url_parts['path'] ) ) {
   968 		}
   969 		}
   969 	}
   970 	}
   970 }
   971 }
   971 
   972 
   972 /**
   973 /**
   973  * Retrieve HTTP Headers from URL.
   974  * Retrieves HTTP Headers from URL.
   974  *
   975  *
   975  * @since 1.5.1
   976  * @since 1.5.1
   976  *
   977  *
   977  * @param string $url        URL to retrieve HTTP headers from.
   978  * @param string $url        URL to retrieve HTTP headers from.
   978  * @param bool   $deprecated Not Used.
   979  * @param bool   $deprecated Not Used.
   979  * @return string|false Headers on success, false on failure.
   980  * @return \WpOrg\Requests\Utility\CaseInsensitiveDictionary|false Headers on success, false on failure.
   980  */
   981  */
   981 function wp_get_http_headers( $url, $deprecated = false ) {
   982 function wp_get_http_headers( $url, $deprecated = false ) {
   982 	if ( ! empty( $deprecated ) ) {
   983 	if ( ! empty( $deprecated ) ) {
   983 		_deprecated_argument( __FUNCTION__, '2.7.0' );
   984 		_deprecated_argument( __FUNCTION__, '2.7.0' );
   984 	}
   985 	}
  1016 		return 0;
  1017 		return 0;
  1017 	}
  1018 	}
  1018 }
  1019 }
  1019 
  1020 
  1020 /**
  1021 /**
  1021  * Build URL query based on an associative and, or indexed array.
  1022  * Builds URL query based on an associative and, or indexed array.
  1022  *
  1023  *
  1023  * This is a convenient function for easily building url queries. It sets the
  1024  * This is a convenient function for easily building url queries. It sets the
  1024  * separator to '&' and uses _http_build_query() function.
  1025  * separator to '&' and uses _http_build_query() function.
  1025  *
  1026  *
  1026  * @since 2.3.0
  1027  * @since 2.3.0
  1047  * @param array|object $data      An array or object of data. Converted to array.
  1048  * @param array|object $data      An array or object of data. Converted to array.
  1048  * @param string       $prefix    Optional. Numeric index. If set, start parameter numbering with it.
  1049  * @param string       $prefix    Optional. Numeric index. If set, start parameter numbering with it.
  1049  *                                Default null.
  1050  *                                Default null.
  1050  * @param string       $sep       Optional. Argument separator; defaults to 'arg_separator.output'.
  1051  * @param string       $sep       Optional. Argument separator; defaults to 'arg_separator.output'.
  1051  *                                Default null.
  1052  *                                Default null.
  1052  * @param string       $key       Optional. Used to prefix key name. Default empty.
  1053  * @param string       $key       Optional. Used to prefix key name. Default empty string.
  1053  * @param bool         $urlencode Optional. Whether to use urlencode() in the result. Default true.
  1054  * @param bool         $urlencode Optional. Whether to use urlencode() in the result. Default true.
  1054  * @return string The query string.
  1055  * @return string The query string.
  1055  */
  1056  */
  1056 function _http_build_query( $data, $prefix = null, $sep = null, $key = '', $urlencode = true ) {
  1057 function _http_build_query( $data, $prefix = null, $sep = null, $key = '', $urlencode = true ) {
  1057 	$ret = array();
  1058 	$ret = array();
  1058 
  1059 
  1059 	foreach ( (array) $data as $k => $v ) {
  1060 	foreach ( (array) $data as $k => $v ) {
  1060 		if ( $urlencode ) {
  1061 		if ( $urlencode ) {
  1061 			$k = urlencode( $k );
  1062 			$k = urlencode( $k );
  1062 		}
  1063 		}
  1063 		if ( is_int( $k ) && null != $prefix ) {
  1064 
       
  1065 		if ( is_int( $k ) && null !== $prefix ) {
  1064 			$k = $prefix . $k;
  1066 			$k = $prefix . $k;
  1065 		}
  1067 		}
       
  1068 
  1066 		if ( ! empty( $key ) ) {
  1069 		if ( ! empty( $key ) ) {
  1067 			$k = $key . '%5B' . $k . '%5D';
  1070 			$k = $key . '%5B' . $k . '%5D';
  1068 		}
  1071 		}
       
  1072 
  1069 		if ( null === $v ) {
  1073 		if ( null === $v ) {
  1070 			continue;
  1074 			continue;
  1071 		} elseif ( false === $v ) {
  1075 		} elseif ( false === $v ) {
  1072 			$v = '0';
  1076 			$v = '0';
  1073 		}
  1077 		}
  1155 		$uri      = substr( $uri, 8 );
  1159 		$uri      = substr( $uri, 8 );
  1156 	} else {
  1160 	} else {
  1157 		$protocol = '';
  1161 		$protocol = '';
  1158 	}
  1162 	}
  1159 
  1163 
  1160 	if ( strpos( $uri, '?' ) !== false ) {
  1164 	if ( str_contains( $uri, '?' ) ) {
  1161 		list( $base, $query ) = explode( '?', $uri, 2 );
  1165 		list( $base, $query ) = explode( '?', $uri, 2 );
  1162 		$base                .= '?';
  1166 		$base                .= '?';
  1163 	} elseif ( $protocol || strpos( $uri, '=' ) === false ) {
  1167 	} elseif ( $protocol || ! str_contains( $uri, '=' ) ) {
  1164 		$base  = $uri . '?';
  1168 		$base  = $uri . '?';
  1165 		$query = '';
  1169 		$query = '';
  1166 	} else {
  1170 	} else {
  1167 		$base  = '';
  1171 		$base  = '';
  1168 		$query = $uri;
  1172 		$query = $uri;
  1193 	return $ret;
  1197 	return $ret;
  1194 }
  1198 }
  1195 
  1199 
  1196 /**
  1200 /**
  1197  * Removes an item or items from a query string.
  1201  * Removes an item or items from a query string.
       
  1202  *
       
  1203  * Important: The return value of remove_query_arg() is not escaped by default. Output should be
       
  1204  * late-escaped with esc_url() or similar to help prevent vulnerability to cross-site scripting
       
  1205  * (XSS) attacks.
  1198  *
  1206  *
  1199  * @since 1.5.0
  1207  * @since 1.5.0
  1200  *
  1208  *
  1201  * @param string|string[] $key   Query key or keys to remove.
  1209  * @param string|string[] $key   Query key or keys to remove.
  1202  * @param false|string    $query Optional. When false uses the current URL. Default false.
  1210  * @param false|string    $query Optional. When false uses the current URL. Default false.
  1265  * Walks the array while sanitizing the contents.
  1273  * Walks the array while sanitizing the contents.
  1266  *
  1274  *
  1267  * @since 0.71
  1275  * @since 0.71
  1268  * @since 5.5.0 Non-string values are left untouched.
  1276  * @since 5.5.0 Non-string values are left untouched.
  1269  *
  1277  *
  1270  * @param array $array Array to walk while sanitizing contents.
  1278  * @param array $input_array Array to walk while sanitizing contents.
  1271  * @return array Sanitized $array.
  1279  * @return array Sanitized $input_array.
  1272  */
  1280  */
  1273 function add_magic_quotes( $array ) {
  1281 function add_magic_quotes( $input_array ) {
  1274 	foreach ( (array) $array as $k => $v ) {
  1282 	foreach ( (array) $input_array as $k => $v ) {
  1275 		if ( is_array( $v ) ) {
  1283 		if ( is_array( $v ) ) {
  1276 			$array[ $k ] = add_magic_quotes( $v );
  1284 			$input_array[ $k ] = add_magic_quotes( $v );
  1277 		} elseif ( is_string( $v ) ) {
  1285 		} elseif ( is_string( $v ) ) {
  1278 			$array[ $k ] = addslashes( $v );
  1286 			$input_array[ $k ] = addslashes( $v );
  1279 		} else {
  1287 		}
  1280 			continue;
  1288 	}
  1281 		}
  1289 
  1282 	}
  1290 	return $input_array;
  1283 
       
  1284 	return $array;
       
  1285 }
  1291 }
  1286 
  1292 
  1287 /**
  1293 /**
  1288  * HTTP request for URI to retrieve content.
  1294  * HTTP request for URI to retrieve content.
  1289  *
  1295  *
  1312 
  1318 
  1313 	return wp_remote_retrieve_body( $response );
  1319 	return wp_remote_retrieve_body( $response );
  1314 }
  1320 }
  1315 
  1321 
  1316 /**
  1322 /**
  1317  * Set up the WordPress query.
  1323  * Sets up the WordPress query.
  1318  *
  1324  *
  1319  * @since 2.0.0
  1325  * @since 2.0.0
  1320  *
  1326  *
  1321  * @global WP       $wp           Current WordPress environment instance.
  1327  * @global WP       $wp           Current WordPress environment instance.
  1322  * @global WP_Query $wp_query     WordPress Query object.
  1328  * @global WP_Query $wp_query     WordPress Query object.
  1333 		$wp_the_query = $wp_query;
  1339 		$wp_the_query = $wp_query;
  1334 	}
  1340 	}
  1335 }
  1341 }
  1336 
  1342 
  1337 /**
  1343 /**
  1338  * Retrieve the description for the HTTP status.
  1344  * Retrieves the description for the HTTP status.
  1339  *
  1345  *
  1340  * @since 2.3.0
  1346  * @since 2.3.0
  1341  * @since 3.9.0 Added status codes 418, 428, 429, 431, and 511.
  1347  * @since 3.9.0 Added status codes 418, 428, 429, 431, and 511.
  1342  * @since 4.5.0 Added status codes 308, 421, and 451.
  1348  * @since 4.5.0 Added status codes 308, 421, and 451.
  1343  * @since 5.1.0 Added status code 103.
  1349  * @since 5.1.0 Added status code 103.
       
  1350  * @since 6.6.0 Added status code 425.
  1344  *
  1351  *
  1345  * @global array $wp_header_to_desc
  1352  * @global array $wp_header_to_desc
  1346  *
  1353  *
  1347  * @param int $code HTTP status code.
  1354  * @param int $code HTTP status code.
  1348  * @return string Status description if found, an empty string otherwise.
  1355  * @return string Status description if found, an empty string otherwise.
  1400 			418 => 'I\'m a teapot',
  1407 			418 => 'I\'m a teapot',
  1401 			421 => 'Misdirected Request',
  1408 			421 => 'Misdirected Request',
  1402 			422 => 'Unprocessable Entity',
  1409 			422 => 'Unprocessable Entity',
  1403 			423 => 'Locked',
  1410 			423 => 'Locked',
  1404 			424 => 'Failed Dependency',
  1411 			424 => 'Failed Dependency',
       
  1412 			425 => 'Too Early',
  1405 			426 => 'Upgrade Required',
  1413 			426 => 'Upgrade Required',
  1406 			428 => 'Precondition Required',
  1414 			428 => 'Precondition Required',
  1407 			429 => 'Too Many Requests',
  1415 			429 => 'Too Many Requests',
  1408 			431 => 'Request Header Fields Too Large',
  1416 			431 => 'Request Header Fields Too Large',
  1409 			451 => 'Unavailable For Legal Reasons',
  1417 			451 => 'Unavailable For Legal Reasons',
  1427 		return '';
  1435 		return '';
  1428 	}
  1436 	}
  1429 }
  1437 }
  1430 
  1438 
  1431 /**
  1439 /**
  1432  * Set HTTP status header.
  1440  * Sets HTTP status header.
  1433  *
  1441  *
  1434  * @since 2.0.0
  1442  * @since 2.0.0
  1435  * @since 4.4.0 Added the `$description` parameter.
  1443  * @since 4.4.0 Added the `$description` parameter.
  1436  *
  1444  *
  1437  * @see get_status_header_desc()
  1445  * @see get_status_header_desc()
  1438  *
  1446  *
  1439  * @param int    $code        HTTP status code.
  1447  * @param int    $code        HTTP status code.
  1440  * @param string $description Optional. A custom description for the HTTP status.
  1448  * @param string $description Optional. A custom description for the HTTP status.
       
  1449  *                            Defaults to the result of get_status_header_desc() for the given code.
  1441  */
  1450  */
  1442 function status_header( $code, $description = '' ) {
  1451 function status_header( $code, $description = '' ) {
  1443 	if ( ! $description ) {
  1452 	if ( ! $description ) {
  1444 		$description = get_status_header_desc( $code );
  1453 		$description = get_status_header_desc( $code );
  1445 	}
  1454 	}
  1469 		header( $status_header, true, $code );
  1478 		header( $status_header, true, $code );
  1470 	}
  1479 	}
  1471 }
  1480 }
  1472 
  1481 
  1473 /**
  1482 /**
  1474  * Get the header information to prevent caching.
  1483  * Gets the HTTP header information to prevent caching.
  1475  *
  1484  *
  1476  * The several different headers cover the different ways cache prevention
  1485  * The several different headers cover the different ways cache prevention
  1477  * is handled by different browsers
  1486  * is handled by different browsers.
  1478  *
  1487  *
  1479  * @since 2.8.0
  1488  * @since 2.8.0
       
  1489  * @since 6.3.0 The `Cache-Control` header for logged in users now includes the
       
  1490  *              `no-store` and `private` directives.
  1480  *
  1491  *
  1481  * @return array The associative array of header names and field values.
  1492  * @return array The associative array of header names and field values.
  1482  */
  1493  */
  1483 function wp_get_nocache_headers() {
  1494 function wp_get_nocache_headers() {
       
  1495 	$cache_control = ( function_exists( 'is_user_logged_in' ) && is_user_logged_in() )
       
  1496 		? 'no-cache, must-revalidate, max-age=0, no-store, private'
       
  1497 		: 'no-cache, must-revalidate, max-age=0';
       
  1498 
  1484 	$headers = array(
  1499 	$headers = array(
  1485 		'Expires'       => 'Wed, 11 Jan 1984 05:00:00 GMT',
  1500 		'Expires'       => 'Wed, 11 Jan 1984 05:00:00 GMT',
  1486 		'Cache-Control' => 'no-cache, must-revalidate, max-age=0',
  1501 		'Cache-Control' => $cache_control,
  1487 	);
  1502 	);
  1488 
  1503 
  1489 	if ( function_exists( 'apply_filters' ) ) {
  1504 	if ( function_exists( 'apply_filters' ) ) {
  1490 		/**
  1505 		/**
  1491 		 * Filters the cache-controlling headers.
  1506 		 * Filters the cache-controlling HTTP headers that are used to prevent caching.
  1492 		 *
  1507 		 *
  1493 		 * @since 2.8.0
  1508 		 * @since 2.8.0
  1494 		 *
  1509 		 *
  1495 		 * @see wp_get_nocache_headers()
  1510 		 * @see wp_get_nocache_headers()
  1496 		 *
  1511 		 *
  1497 		 * @param array $headers {
  1512 		 * @param array $headers Header names and field values.
  1498 		 *     Header names and field values.
       
  1499 		 *
       
  1500 		 *     @type string $Expires       Expires header.
       
  1501 		 *     @type string $Cache-Control Cache-Control header.
       
  1502 		 * }
       
  1503 		 */
  1513 		 */
  1504 		$headers = (array) apply_filters( 'nocache_headers', $headers );
  1514 		$headers = (array) apply_filters( 'nocache_headers', $headers );
  1505 	}
  1515 	}
  1506 	$headers['Last-Modified'] = false;
  1516 	$headers['Last-Modified'] = false;
  1507 	return $headers;
  1517 	return $headers;
  1508 }
  1518 }
  1509 
  1519 
  1510 /**
  1520 /**
  1511  * Set the headers to prevent caching for the different browsers.
  1521  * Sets the HTTP headers to prevent caching for the different browsers.
  1512  *
  1522  *
  1513  * Different browsers support different nocache headers, so several
  1523  * Different browsers support different nocache headers, so several
  1514  * headers must be sent so that all of them get the point that no
  1524  * headers must be sent so that all of them get the point that no
  1515  * caching should occur.
  1525  * caching should occur.
  1516  *
  1526  *
  1533 		header( "{$name}: {$field_value}" );
  1543 		header( "{$name}: {$field_value}" );
  1534 	}
  1544 	}
  1535 }
  1545 }
  1536 
  1546 
  1537 /**
  1547 /**
  1538  * Set the headers for caching for 10 days with JavaScript content type.
  1548  * Sets the HTTP headers for caching for 10 days with JavaScript content type.
  1539  *
  1549  *
  1540  * @since 2.1.0
  1550  * @since 2.1.0
  1541  */
  1551  */
  1542 function cache_javascript_headers() {
  1552 function cache_javascript_headers() {
  1543 	$expiresOffset = 10 * DAY_IN_SECONDS;
  1553 	$expires_offset = 10 * DAY_IN_SECONDS;
  1544 
  1554 
  1545 	header( 'Content-Type: text/javascript; charset=' . get_bloginfo( 'charset' ) );
  1555 	header( 'Content-Type: text/javascript; charset=' . get_bloginfo( 'charset' ) );
  1546 	header( 'Vary: Accept-Encoding' ); // Handle proxies.
  1556 	header( 'Vary: Accept-Encoding' ); // Handle proxies.
  1547 	header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', time() + $expiresOffset ) . ' GMT' );
  1557 	header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', time() + $expires_offset ) . ' GMT' );
  1548 }
  1558 }
  1549 
  1559 
  1550 /**
  1560 /**
  1551  * Retrieve the number of database queries during the WordPress execution.
  1561  * Retrieves the number of database queries during the WordPress execution.
  1552  *
  1562  *
  1553  * @since 2.0.0
  1563  * @since 2.0.0
  1554  *
  1564  *
  1555  * @global wpdb $wpdb WordPress database abstraction object.
  1565  * @global wpdb $wpdb WordPress database abstraction object.
  1556  *
  1566  *
  1560 	global $wpdb;
  1570 	global $wpdb;
  1561 	return $wpdb->num_queries;
  1571 	return $wpdb->num_queries;
  1562 }
  1572 }
  1563 
  1573 
  1564 /**
  1574 /**
  1565  * Whether input is yes or no.
  1575  * Determines whether input is yes or no.
  1566  *
  1576  *
  1567  * Must be 'y' to be true.
  1577  * Must be 'y' to be true.
  1568  *
  1578  *
  1569  * @since 1.0.0
  1579  * @since 1.0.0
  1570  *
  1580  *
  1574 function bool_from_yn( $yn ) {
  1584 function bool_from_yn( $yn ) {
  1575 	return ( 'y' === strtolower( $yn ) );
  1585 	return ( 'y' === strtolower( $yn ) );
  1576 }
  1586 }
  1577 
  1587 
  1578 /**
  1588 /**
  1579  * Load the feed template from the use of an action hook.
  1589  * Loads the feed template from the use of an action hook.
  1580  *
  1590  *
  1581  * If the feed action does not have a hook, then the function will die with a
  1591  * If the feed action does not have a hook, then the function will die with a
  1582  * message telling the visitor that the feed is not valid.
  1592  * message telling the visitor that the feed is not valid.
  1583  *
  1593  *
  1584  * It is better to only have one hook for each feed.
  1594  * It is better to only have one hook for each feed.
  1598 	if ( '' === $feed || 'feed' === $feed ) {
  1608 	if ( '' === $feed || 'feed' === $feed ) {
  1599 		$feed = get_default_feed();
  1609 		$feed = get_default_feed();
  1600 	}
  1610 	}
  1601 
  1611 
  1602 	if ( ! has_action( "do_feed_{$feed}" ) ) {
  1612 	if ( ! has_action( "do_feed_{$feed}" ) ) {
  1603 		wp_die( __( '<strong>Error</strong>: This is not a valid feed template.' ), '', array( 'response' => 404 ) );
  1613 		wp_die( __( '<strong>Error:</strong> This is not a valid feed template.' ), '', array( 'response' => 404 ) );
  1604 	}
  1614 	}
  1605 
  1615 
  1606 	/**
  1616 	/**
  1607 	 * Fires once the given feed is loaded.
  1617 	 * Fires once the given feed is loaded.
  1608 	 *
  1618 	 *
  1623 	 */
  1633 	 */
  1624 	do_action( "do_feed_{$feed}", $wp_query->is_comment_feed, $feed );
  1634 	do_action( "do_feed_{$feed}", $wp_query->is_comment_feed, $feed );
  1625 }
  1635 }
  1626 
  1636 
  1627 /**
  1637 /**
  1628  * Load the RDF RSS 0.91 Feed template.
  1638  * Loads the RDF RSS 0.91 Feed template.
  1629  *
  1639  *
  1630  * @since 2.1.0
  1640  * @since 2.1.0
  1631  *
  1641  *
  1632  * @see load_template()
  1642  * @see load_template()
  1633  */
  1643  */
  1634 function do_feed_rdf() {
  1644 function do_feed_rdf() {
  1635 	load_template( ABSPATH . WPINC . '/feed-rdf.php' );
  1645 	load_template( ABSPATH . WPINC . '/feed-rdf.php' );
  1636 }
  1646 }
  1637 
  1647 
  1638 /**
  1648 /**
  1639  * Load the RSS 1.0 Feed Template.
  1649  * Loads the RSS 1.0 Feed Template.
  1640  *
  1650  *
  1641  * @since 2.1.0
  1651  * @since 2.1.0
  1642  *
  1652  *
  1643  * @see load_template()
  1653  * @see load_template()
  1644  */
  1654  */
  1645 function do_feed_rss() {
  1655 function do_feed_rss() {
  1646 	load_template( ABSPATH . WPINC . '/feed-rss.php' );
  1656 	load_template( ABSPATH . WPINC . '/feed-rss.php' );
  1647 }
  1657 }
  1648 
  1658 
  1649 /**
  1659 /**
  1650  * Load either the RSS2 comment feed or the RSS2 posts feed.
  1660  * Loads either the RSS2 comment feed or the RSS2 posts feed.
  1651  *
  1661  *
  1652  * @since 2.1.0
  1662  * @since 2.1.0
  1653  *
  1663  *
  1654  * @see load_template()
  1664  * @see load_template()
  1655  *
  1665  *
  1662 		load_template( ABSPATH . WPINC . '/feed-rss2.php' );
  1672 		load_template( ABSPATH . WPINC . '/feed-rss2.php' );
  1663 	}
  1673 	}
  1664 }
  1674 }
  1665 
  1675 
  1666 /**
  1676 /**
  1667  * Load either Atom comment feed or Atom posts feed.
  1677  * Loads either Atom comment feed or Atom posts feed.
  1668  *
  1678  *
  1669  * @since 2.1.0
  1679  * @since 2.1.0
  1670  *
  1680  *
  1671  * @see load_template()
  1681  * @see load_template()
  1672  *
  1682  *
  1682 
  1692 
  1683 /**
  1693 /**
  1684  * Displays the default robots.txt file content.
  1694  * Displays the default robots.txt file content.
  1685  *
  1695  *
  1686  * @since 2.1.0
  1696  * @since 2.1.0
  1687  * @since 5.3.0 Remove the "Disallow: /" output if search engine visiblity is
  1697  * @since 5.3.0 Remove the "Disallow: /" output if search engine visibility is
  1688  *              discouraged in favor of robots meta HTML tag via wp_robots_no_robots()
  1698  *              discouraged in favor of robots meta HTML tag via wp_robots_no_robots()
  1689  *              filter callback.
  1699  *              filter callback.
  1690  */
  1700  */
  1691 function do_robots() {
  1701 function do_robots() {
  1692 	header( 'Content-Type: text/plain; charset=utf-8' );
  1702 	header( 'Content-Type: text/plain; charset=utf-8' );
  1716 	 */
  1726 	 */
  1717 	echo apply_filters( 'robots_txt', $output, $public );
  1727 	echo apply_filters( 'robots_txt', $output, $public );
  1718 }
  1728 }
  1719 
  1729 
  1720 /**
  1730 /**
  1721  * Display the favicon.ico file content.
  1731  * Displays the favicon.ico file content.
  1722  *
  1732  *
  1723  * @since 5.4.0
  1733  * @since 5.4.0
  1724  */
  1734  */
  1725 function do_favicon() {
  1735 function do_favicon() {
  1726 	/**
  1736 	/**
  1763 	if ( wp_cache_get( 'is_blog_installed' ) ) {
  1773 	if ( wp_cache_get( 'is_blog_installed' ) ) {
  1764 		return true;
  1774 		return true;
  1765 	}
  1775 	}
  1766 
  1776 
  1767 	$suppress = $wpdb->suppress_errors();
  1777 	$suppress = $wpdb->suppress_errors();
       
  1778 
  1768 	if ( ! wp_installing() ) {
  1779 	if ( ! wp_installing() ) {
  1769 		$alloptions = wp_load_alloptions();
  1780 		$alloptions = wp_load_alloptions();
  1770 	}
  1781 	}
       
  1782 
  1771 	// If siteurl is not set to autoload, check it specifically.
  1783 	// If siteurl is not set to autoload, check it specifically.
  1772 	if ( ! isset( $alloptions['siteurl'] ) ) {
  1784 	if ( ! isset( $alloptions['siteurl'] ) ) {
  1773 		$installed = $wpdb->get_var( "SELECT option_value FROM $wpdb->options WHERE option_name = 'siteurl'" );
  1785 		$installed = $wpdb->get_var( "SELECT option_value FROM $wpdb->options WHERE option_name = 'siteurl'" );
  1774 	} else {
  1786 	} else {
  1775 		$installed = $alloptions['siteurl'];
  1787 		$installed = $alloptions['siteurl'];
  1776 	}
  1788 	}
       
  1789 
  1777 	$wpdb->suppress_errors( $suppress );
  1790 	$wpdb->suppress_errors( $suppress );
  1778 
  1791 
  1779 	$installed = ! empty( $installed );
  1792 	$installed = ! empty( $installed );
  1780 	wp_cache_set( 'is_blog_installed', $installed );
  1793 	wp_cache_set( 'is_blog_installed', $installed );
  1781 
  1794 
  1796 	 * options table could not be accessed.
  1809 	 * options table could not be accessed.
  1797 	 */
  1810 	 */
  1798 	$wp_tables = $wpdb->tables();
  1811 	$wp_tables = $wpdb->tables();
  1799 	foreach ( $wp_tables as $table ) {
  1812 	foreach ( $wp_tables as $table ) {
  1800 		// The existence of custom user tables shouldn't suggest an unwise state or prevent a clean installation.
  1813 		// The existence of custom user tables shouldn't suggest an unwise state or prevent a clean installation.
  1801 		if ( defined( 'CUSTOM_USER_TABLE' ) && CUSTOM_USER_TABLE == $table ) {
  1814 		if ( defined( 'CUSTOM_USER_TABLE' ) && CUSTOM_USER_TABLE === $table ) {
  1802 			continue;
  1815 			continue;
  1803 		}
  1816 		}
  1804 		if ( defined( 'CUSTOM_USER_META_TABLE' ) && CUSTOM_USER_META_TABLE == $table ) {
  1817 
       
  1818 		if ( defined( 'CUSTOM_USER_META_TABLE' ) && CUSTOM_USER_META_TABLE === $table ) {
  1805 			continue;
  1819 			continue;
  1806 		}
  1820 		}
  1807 
  1821 
  1808 		$described_table = $wpdb->get_results( "DESCRIBE $table;" );
  1822 		$described_table = $wpdb->get_results( "DESCRIBE $table;" );
  1809 		if (
  1823 		if (
  1833 
  1847 
  1834 	return false;
  1848 	return false;
  1835 }
  1849 }
  1836 
  1850 
  1837 /**
  1851 /**
  1838  * Retrieve URL with nonce added to URL query.
  1852  * Retrieves URL with nonce added to URL query.
  1839  *
  1853  *
  1840  * @since 2.0.4
  1854  * @since 2.0.4
  1841  *
  1855  *
  1842  * @param string     $actionurl URL to add nonce action.
  1856  * @param string     $actionurl URL to add nonce action.
  1843  * @param int|string $action    Optional. Nonce action name. Default -1.
  1857  * @param int|string $action    Optional. Nonce action name. Default -1.
  1848 	$actionurl = str_replace( '&amp;', '&', $actionurl );
  1862 	$actionurl = str_replace( '&amp;', '&', $actionurl );
  1849 	return esc_html( add_query_arg( $name, wp_create_nonce( $action ), $actionurl ) );
  1863 	return esc_html( add_query_arg( $name, wp_create_nonce( $action ), $actionurl ) );
  1850 }
  1864 }
  1851 
  1865 
  1852 /**
  1866 /**
  1853  * Retrieve or display nonce hidden field for forms.
  1867  * Retrieves or display nonce hidden field for forms.
  1854  *
  1868  *
  1855  * The nonce field is used to validate that the contents of the form came from
  1869  * The nonce field is used to validate that the contents of the form came from
  1856  * the location on the current site and not somewhere else. The nonce does not
  1870  * the location on the current site and not somewhere else. The nonce does not
  1857  * offer absolute protection, but should protect against most cases. It is very
  1871  * offer absolute protection, but should protect against most cases. It is very
  1858  * important to use nonce field in forms.
  1872  * important to use nonce field in forms.
  1870  * @since 2.0.4
  1884  * @since 2.0.4
  1871  *
  1885  *
  1872  * @param int|string $action  Optional. Action name. Default -1.
  1886  * @param int|string $action  Optional. Action name. Default -1.
  1873  * @param string     $name    Optional. Nonce name. Default '_wpnonce'.
  1887  * @param string     $name    Optional. Nonce name. Default '_wpnonce'.
  1874  * @param bool       $referer Optional. Whether to set the referer field for validation. Default true.
  1888  * @param bool       $referer Optional. Whether to set the referer field for validation. Default true.
  1875  * @param bool       $echo    Optional. Whether to display or return hidden form field. Default true.
  1889  * @param bool       $display Optional. Whether to display or return hidden form field. Default true.
  1876  * @return string Nonce field HTML markup.
  1890  * @return string Nonce field HTML markup.
  1877  */
  1891  */
  1878 function wp_nonce_field( $action = -1, $name = '_wpnonce', $referer = true, $echo = true ) {
  1892 function wp_nonce_field( $action = -1, $name = '_wpnonce', $referer = true, $display = true ) {
  1879 	$name        = esc_attr( $name );
  1893 	$name        = esc_attr( $name );
  1880 	$nonce_field = '<input type="hidden" id="' . $name . '" name="' . $name . '" value="' . wp_create_nonce( $action ) . '" />';
  1894 	$nonce_field = '<input type="hidden" id="' . $name . '" name="' . $name . '" value="' . wp_create_nonce( $action ) . '" />';
  1881 
  1895 
  1882 	if ( $referer ) {
  1896 	if ( $referer ) {
  1883 		$nonce_field .= wp_referer_field( false );
  1897 		$nonce_field .= wp_referer_field( false );
  1884 	}
  1898 	}
  1885 
  1899 
  1886 	if ( $echo ) {
  1900 	if ( $display ) {
  1887 		echo $nonce_field;
  1901 		echo $nonce_field;
  1888 	}
  1902 	}
  1889 
  1903 
  1890 	return $nonce_field;
  1904 	return $nonce_field;
  1891 }
  1905 }
  1892 
  1906 
  1893 /**
  1907 /**
  1894  * Retrieve or display referer hidden field for forms.
  1908  * Retrieves or displays referer hidden field for forms.
  1895  *
  1909  *
  1896  * The referer link is the current Request URI from the server super global. The
  1910  * The referer link is the current Request URI from the server super global. The
  1897  * input name is '_wp_http_referer', in case you wanted to check manually.
  1911  * input name is '_wp_http_referer', in case you wanted to check manually.
  1898  *
  1912  *
  1899  * @since 2.0.4
  1913  * @since 2.0.4
  1900  *
  1914  *
  1901  * @param bool $echo Optional. Whether to echo or return the referer field. Default true.
  1915  * @param bool $display Optional. Whether to echo or return the referer field. Default true.
  1902  * @return string Referer field HTML markup.
  1916  * @return string Referer field HTML markup.
  1903  */
  1917  */
  1904 function wp_referer_field( $echo = true ) {
  1918 function wp_referer_field( $display = true ) {
  1905 	$referer_field = '<input type="hidden" name="_wp_http_referer" value="' . esc_attr( wp_unslash( $_SERVER['REQUEST_URI'] ) ) . '" />';
  1919 	$request_url   = remove_query_arg( '_wp_http_referer' );
  1906 
  1920 	$referer_field = '<input type="hidden" name="_wp_http_referer" value="' . esc_url( $request_url ) . '" />';
  1907 	if ( $echo ) {
  1921 
       
  1922 	if ( $display ) {
  1908 		echo $referer_field;
  1923 		echo $referer_field;
  1909 	}
  1924 	}
  1910 
  1925 
  1911 	return $referer_field;
  1926 	return $referer_field;
  1912 }
  1927 }
  1913 
  1928 
  1914 /**
  1929 /**
  1915  * Retrieve or display original referer hidden field for forms.
  1930  * Retrieves or displays original referer hidden field for forms.
  1916  *
  1931  *
  1917  * The input name is '_wp_original_http_referer' and will be either the same
  1932  * The input name is '_wp_original_http_referer' and will be either the same
  1918  * value of wp_referer_field(), if that was posted already or it will be the
  1933  * value of wp_referer_field(), if that was posted already or it will be the
  1919  * current page, if it doesn't exist.
  1934  * current page, if it doesn't exist.
  1920  *
  1935  *
  1921  * @since 2.0.4
  1936  * @since 2.0.4
  1922  *
  1937  *
  1923  * @param bool   $echo         Optional. Whether to echo the original http referer. Default true.
  1938  * @param bool   $display      Optional. Whether to echo the original http referer. Default true.
  1924  * @param string $jump_back_to Optional. Can be 'previous' or page you want to jump back to.
  1939  * @param string $jump_back_to Optional. Can be 'previous' or page you want to jump back to.
  1925  *                             Default 'current'.
  1940  *                             Default 'current'.
  1926  * @return string Original referer field.
  1941  * @return string Original referer field.
  1927  */
  1942  */
  1928 function wp_original_referer_field( $echo = true, $jump_back_to = 'current' ) {
  1943 function wp_original_referer_field( $display = true, $jump_back_to = 'current' ) {
  1929 	$ref = wp_get_original_referer();
  1944 	$ref = wp_get_original_referer();
  1930 
  1945 
  1931 	if ( ! $ref ) {
  1946 	if ( ! $ref ) {
  1932 		$ref = ( 'previous' === $jump_back_to ) ? wp_get_referer() : wp_unslash( $_SERVER['REQUEST_URI'] );
  1947 		$ref = ( 'previous' === $jump_back_to ) ? wp_get_referer() : wp_unslash( $_SERVER['REQUEST_URI'] );
  1933 	}
  1948 	}
  1934 
  1949 
  1935 	$orig_referer_field = '<input type="hidden" name="_wp_original_http_referer" value="' . esc_attr( $ref ) . '" />';
  1950 	$orig_referer_field = '<input type="hidden" name="_wp_original_http_referer" value="' . esc_attr( $ref ) . '" />';
  1936 
  1951 
  1937 	if ( $echo ) {
  1952 	if ( $display ) {
  1938 		echo $orig_referer_field;
  1953 		echo $orig_referer_field;
  1939 	}
  1954 	}
  1940 
  1955 
  1941 	return $orig_referer_field;
  1956 	return $orig_referer_field;
  1942 }
  1957 }
  1943 
  1958 
  1944 /**
  1959 /**
  1945  * Retrieve referer from '_wp_http_referer' or HTTP referer.
  1960  * Retrieves referer from '_wp_http_referer' or HTTP referer.
  1946  *
  1961  *
  1947  * If it's the same as the current request URL, will return false.
  1962  * If it's the same as the current request URL, will return false.
  1948  *
  1963  *
  1949  * @since 2.0.4
  1964  * @since 2.0.4
  1950  *
  1965  *
  1951  * @return string|false Referer URL on success, false on failure.
  1966  * @return string|false Referer URL on success, false on failure.
  1952  */
  1967  */
  1953 function wp_get_referer() {
  1968 function wp_get_referer() {
       
  1969 	// Return early if called before wp_validate_redirect() is defined.
  1954 	if ( ! function_exists( 'wp_validate_redirect' ) ) {
  1970 	if ( ! function_exists( 'wp_validate_redirect' ) ) {
  1955 		return false;
  1971 		return false;
  1956 	}
  1972 	}
  1957 
  1973 
  1958 	$ref = wp_get_raw_referer();
  1974 	$ref = wp_get_raw_referer();
  1959 
  1975 
  1960 	if ( $ref && wp_unslash( $_SERVER['REQUEST_URI'] ) !== $ref && home_url() . wp_unslash( $_SERVER['REQUEST_URI'] ) !== $ref ) {
  1976 	if ( $ref && wp_unslash( $_SERVER['REQUEST_URI'] ) !== $ref
       
  1977 		&& home_url() . wp_unslash( $_SERVER['REQUEST_URI'] ) !== $ref
       
  1978 	) {
  1961 		return wp_validate_redirect( $ref, false );
  1979 		return wp_validate_redirect( $ref, false );
  1962 	}
  1980 	}
  1963 
  1981 
  1964 	return false;
  1982 	return false;
  1965 }
  1983 }
  1966 
  1984 
  1967 /**
  1985 /**
  1968  * Retrieves unvalidated referer from '_wp_http_referer' or HTTP referer.
  1986  * Retrieves unvalidated referer from the '_wp_http_referer' URL query variable or the HTTP referer.
       
  1987  *
       
  1988  * If the value of the '_wp_http_referer' URL query variable is not a string then it will be ignored.
  1969  *
  1989  *
  1970  * Do not use for redirects, use wp_get_referer() instead.
  1990  * Do not use for redirects, use wp_get_referer() instead.
  1971  *
  1991  *
  1972  * @since 4.5.0
  1992  * @since 4.5.0
  1973  *
  1993  *
  1974  * @return string|false Referer URL on success, false on failure.
  1994  * @return string|false Referer URL on success, false on failure.
  1975  */
  1995  */
  1976 function wp_get_raw_referer() {
  1996 function wp_get_raw_referer() {
  1977 	if ( ! empty( $_REQUEST['_wp_http_referer'] ) ) {
  1997 	if ( ! empty( $_REQUEST['_wp_http_referer'] ) && is_string( $_REQUEST['_wp_http_referer'] ) ) {
  1978 		return wp_unslash( $_REQUEST['_wp_http_referer'] );
  1998 		return wp_unslash( $_REQUEST['_wp_http_referer'] );
  1979 	} elseif ( ! empty( $_SERVER['HTTP_REFERER'] ) ) {
  1999 	} elseif ( ! empty( $_SERVER['HTTP_REFERER'] ) ) {
  1980 		return wp_unslash( $_SERVER['HTTP_REFERER'] );
  2000 		return wp_unslash( $_SERVER['HTTP_REFERER'] );
  1981 	}
  2001 	}
  1982 
  2002 
  1983 	return false;
  2003 	return false;
  1984 }
  2004 }
  1985 
  2005 
  1986 /**
  2006 /**
  1987  * Retrieve original referer that was posted, if it exists.
  2007  * Retrieves original referer that was posted, if it exists.
  1988  *
  2008  *
  1989  * @since 2.0.4
  2009  * @since 2.0.4
  1990  *
  2010  *
  1991  * @return string|false Original referer URL on success, false on failure.
  2011  * @return string|false Original referer URL on success, false on failure.
  1992  */
  2012  */
  1993 function wp_get_original_referer() {
  2013 function wp_get_original_referer() {
  1994 	if ( ! empty( $_REQUEST['_wp_original_http_referer'] ) && function_exists( 'wp_validate_redirect' ) ) {
  2014 	// Return early if called before wp_validate_redirect() is defined.
       
  2015 	if ( ! function_exists( 'wp_validate_redirect' ) ) {
       
  2016 		return false;
       
  2017 	}
       
  2018 
       
  2019 	if ( ! empty( $_REQUEST['_wp_original_http_referer'] ) ) {
  1995 		return wp_validate_redirect( wp_unslash( $_REQUEST['_wp_original_http_referer'] ), false );
  2020 		return wp_validate_redirect( wp_unslash( $_REQUEST['_wp_original_http_referer'] ), false );
  1996 	}
  2021 	}
  1997 
  2022 
  1998 	return false;
  2023 	return false;
  1999 }
  2024 }
  2036 	if ( file_exists( $target ) ) {
  2061 	if ( file_exists( $target ) ) {
  2037 		return @is_dir( $target );
  2062 		return @is_dir( $target );
  2038 	}
  2063 	}
  2039 
  2064 
  2040 	// Do not allow path traversals.
  2065 	// Do not allow path traversals.
  2041 	if ( false !== strpos( $target, '../' ) || false !== strpos( $target, '..' . DIRECTORY_SEPARATOR ) ) {
  2066 	if ( str_contains( $target, '../' ) || str_contains( $target, '..' . DIRECTORY_SEPARATOR ) ) {
  2042 		return false;
  2067 		return false;
  2043 	}
  2068 	}
  2044 
  2069 
  2045 	// We need to find the permissions of the parent folder that exists and inherit that.
  2070 	// We need to find the permissions of the parent folder that exists and inherit that.
  2046 	$target_parent = dirname( $target );
  2071 	$target_parent = dirname( $target );
  2060 
  2085 
  2061 		/*
  2086 		/*
  2062 		 * If a umask is set that modifies $dir_perms, we'll have to re-set
  2087 		 * If a umask is set that modifies $dir_perms, we'll have to re-set
  2063 		 * the $dir_perms correctly with chmod()
  2088 		 * the $dir_perms correctly with chmod()
  2064 		 */
  2089 		 */
  2065 		if ( ( $dir_perms & ~umask() ) != $dir_perms ) {
  2090 		if ( ( $dir_perms & ~umask() ) !== $dir_perms ) {
  2066 			$folder_parts = explode( '/', substr( $target, strlen( $target_parent ) + 1 ) );
  2091 			$folder_parts = explode( '/', substr( $target, strlen( $target_parent ) + 1 ) );
  2067 			for ( $i = 1, $c = count( $folder_parts ); $i <= $c; $i++ ) {
  2092 			for ( $i = 1, $c = count( $folder_parts ); $i <= $c; $i++ ) {
  2068 				chmod( $target_parent . '/' . implode( '/', array_slice( $folder_parts, 0, $i ) ), $dir_perms );
  2093 				chmod( $target_parent . '/' . implode( '/', array_slice( $folder_parts, 0, $i ) ), $dir_perms );
  2069 			}
  2094 			}
  2070 		}
  2095 		}
  2074 
  2099 
  2075 	return false;
  2100 	return false;
  2076 }
  2101 }
  2077 
  2102 
  2078 /**
  2103 /**
  2079  * Test if a given filesystem path is absolute.
  2104  * Tests if a given filesystem path is absolute.
  2080  *
  2105  *
  2081  * For example, '/foo/bar', or 'c:\windows'.
  2106  * For example, '/foo/bar', or 'c:\windows'.
  2082  *
  2107  *
  2083  * @since 2.5.0
  2108  * @since 2.5.0
  2084  *
  2109  *
  2096 
  2121 
  2097 	/*
  2122 	/*
  2098 	 * This is definitive if true but fails if $path does not exist or contains
  2123 	 * This is definitive if true but fails if $path does not exist or contains
  2099 	 * a symbolic link.
  2124 	 * a symbolic link.
  2100 	 */
  2125 	 */
  2101 	if ( realpath( $path ) == $path ) {
  2126 	if ( realpath( $path ) === $path ) {
  2102 		return true;
  2127 		return true;
  2103 	}
  2128 	}
  2104 
  2129 
  2105 	if ( strlen( $path ) == 0 || '.' === $path[0] ) {
  2130 	if ( strlen( $path ) === 0 || '.' === $path[0] ) {
  2106 		return false;
  2131 		return false;
  2107 	}
  2132 	}
  2108 
  2133 
  2109 	// Windows allows absolute paths like this.
  2134 	// Windows allows absolute paths like this.
  2110 	if ( preg_match( '#^[a-zA-Z]:\\\\#', $path ) ) {
  2135 	if ( preg_match( '#^[a-zA-Z]:\\\\#', $path ) ) {
  2114 	// A path starting with / or \ is absolute; anything else is relative.
  2139 	// A path starting with / or \ is absolute; anything else is relative.
  2115 	return ( '/' === $path[0] || '\\' === $path[0] );
  2140 	return ( '/' === $path[0] || '\\' === $path[0] );
  2116 }
  2141 }
  2117 
  2142 
  2118 /**
  2143 /**
  2119  * Join two filesystem paths together.
  2144  * Joins two filesystem paths together.
  2120  *
  2145  *
  2121  * For example, 'give me $path relative to $base'. If the $path is absolute,
  2146  * For example, 'give me $path relative to $base'. If the $path is absolute,
  2122  * then it the full path is returned.
  2147  * then it the full path is returned.
  2123  *
  2148  *
  2124  * @since 2.5.0
  2149  * @since 2.5.0
  2130 function path_join( $base, $path ) {
  2155 function path_join( $base, $path ) {
  2131 	if ( path_is_absolute( $path ) ) {
  2156 	if ( path_is_absolute( $path ) ) {
  2132 		return $path;
  2157 		return $path;
  2133 	}
  2158 	}
  2134 
  2159 
  2135 	return rtrim( $base, '/' ) . '/' . ltrim( $path, '/' );
  2160 	return rtrim( $base, '/' ) . '/' . $path;
  2136 }
  2161 }
  2137 
  2162 
  2138 /**
  2163 /**
  2139  * Normalize a filesystem path.
  2164  * Normalizes a filesystem path.
  2140  *
  2165  *
  2141  * On windows systems, replaces backslashes with forward slashes
  2166  * On windows systems, replaces backslashes with forward slashes
  2142  * and forces upper-case drive letters.
  2167  * and forces upper-case drive letters.
  2143  * Allows for two leading slashes for Windows network shares, but
  2168  * Allows for two leading slashes for Windows network shares, but
  2144  * ensures that all other duplicate slashes are reduced to a single.
  2169  * ensures that all other duplicate slashes are reduced to a single.
  2173 
  2198 
  2174 	return $wrapper . $path;
  2199 	return $wrapper . $path;
  2175 }
  2200 }
  2176 
  2201 
  2177 /**
  2202 /**
  2178  * Determine a writable directory for temporary files.
  2203  * Determines a writable directory for temporary files.
  2179  *
  2204  *
  2180  * Function's preference is the return value of sys_get_temp_dir(),
  2205  * Function's preference is the return value of sys_get_temp_dir(),
  2181  * followed by your PHP temporary upload directory, followed by WP_CONTENT_DIR,
  2206  * followed by your PHP temporary upload directory, followed by WP_CONTENT_DIR,
  2182  * before finally defaulting to /tmp/
  2207  * before finally defaulting to /tmp/
  2183  *
  2208  *
  2217 
  2242 
  2218 	return '/tmp/';
  2243 	return '/tmp/';
  2219 }
  2244 }
  2220 
  2245 
  2221 /**
  2246 /**
  2222  * Determine if a directory is writable.
  2247  * Determines if a directory is writable.
  2223  *
  2248  *
  2224  * This function is used to work around certain ACL issues in PHP primarily
  2249  * This function is used to work around certain ACL issues in PHP primarily
  2225  * affecting Windows Servers.
  2250  * affecting Windows Servers.
  2226  *
  2251  *
  2227  * @since 3.6.0
  2252  * @since 3.6.0
  2243  * Workaround for Windows bug in is_writable() function
  2268  * Workaround for Windows bug in is_writable() function
  2244  *
  2269  *
  2245  * PHP has issues with Windows ACL's for determine if a
  2270  * PHP has issues with Windows ACL's for determine if a
  2246  * directory is writable or not, this works around them by
  2271  * directory is writable or not, this works around them by
  2247  * checking the ability to open files rather than relying
  2272  * checking the ability to open files rather than relying
  2248  * upon PHP to interprate the OS ACL.
  2273  * upon PHP to interpret the OS ACL.
  2249  *
  2274  *
  2250  * @since 2.8.0
  2275  * @since 2.8.0
  2251  *
  2276  *
  2252  * @see https://bugs.php.net/bug.php?id=27609
  2277  * @see https://bugs.php.net/bug.php?id=27609
  2253  * @see https://bugs.php.net/bug.php?id=30931
  2278  * @see https://bugs.php.net/bug.php?id=30931
  2317  * directory is not writable by the server.
  2342  * directory is not writable by the server.
  2318  *
  2343  *
  2319  * @since 2.0.0
  2344  * @since 2.0.0
  2320  * @uses _wp_upload_dir()
  2345  * @uses _wp_upload_dir()
  2321  *
  2346  *
  2322  * @param string $time Optional. Time formatted in 'yyyy/mm'. Default null.
  2347  * @param string|null $time          Optional. Time formatted in 'yyyy/mm'. Default null.
  2323  * @param bool   $create_dir Optional. Whether to check and create the uploads directory.
  2348  * @param bool        $create_dir    Optional. Whether to check and create the uploads directory.
  2324  *                           Default true for backward compatibility.
  2349  *                                   Default true for backward compatibility.
  2325  * @param bool   $refresh_cache Optional. Whether to refresh the cache. Default false.
  2350  * @param bool        $refresh_cache Optional. Whether to refresh the cache. Default false.
  2326  * @return array {
  2351  * @return array {
  2327  *     Array of information about the upload directory.
  2352  *     Array of information about the upload directory.
  2328  *
  2353  *
  2329  *     @type string       $path    Base directory and subdirectory or full path to upload directory.
  2354  *     @type string       $path    Base directory and subdirectory or full path to upload directory.
  2330  *     @type string       $url     Base URL and subdirectory or absolute URL to upload directory.
  2355  *     @type string       $url     Base URL and subdirectory or absolute URL to upload directory.
  2366 
  2391 
  2367 		if ( array_key_exists( $path, $tested_paths ) ) {
  2392 		if ( array_key_exists( $path, $tested_paths ) ) {
  2368 			$uploads['error'] = $tested_paths[ $path ];
  2393 			$uploads['error'] = $tested_paths[ $path ];
  2369 		} else {
  2394 		} else {
  2370 			if ( ! wp_mkdir_p( $path ) ) {
  2395 			if ( ! wp_mkdir_p( $path ) ) {
  2371 				if ( 0 === strpos( $uploads['basedir'], ABSPATH ) ) {
  2396 				if ( str_starts_with( $uploads['basedir'], ABSPATH ) ) {
  2372 					$error_path = str_replace( ABSPATH, '', $uploads['basedir'] ) . $uploads['subdir'];
  2397 					$error_path = str_replace( ABSPATH, '', $uploads['basedir'] ) . $uploads['subdir'];
  2373 				} else {
  2398 				} else {
  2374 					$error_path = wp_basename( $uploads['basedir'] ) . $uploads['subdir'];
  2399 					$error_path = wp_basename( $uploads['basedir'] ) . $uploads['subdir'];
  2375 				}
  2400 				}
  2376 
  2401 
  2392  * A non-filtered, non-cached version of wp_upload_dir() that doesn't check the path.
  2417  * A non-filtered, non-cached version of wp_upload_dir() that doesn't check the path.
  2393  *
  2418  *
  2394  * @since 4.5.0
  2419  * @since 4.5.0
  2395  * @access private
  2420  * @access private
  2396  *
  2421  *
  2397  * @param string $time Optional. Time formatted in 'yyyy/mm'. Default null.
  2422  * @param string|null $time Optional. Time formatted in 'yyyy/mm'. Default null.
  2398  * @return array See wp_upload_dir()
  2423  * @return array See wp_upload_dir()
  2399  */
  2424  */
  2400 function _wp_upload_dir( $time = null ) {
  2425 function _wp_upload_dir( $time = null ) {
  2401 	$siteurl     = get_option( 'siteurl' );
  2426 	$siteurl     = get_option( 'siteurl' );
  2402 	$upload_path = trim( get_option( 'upload_path' ) );
  2427 	$upload_path = trim( get_option( 'upload_path' ) );
  2403 
  2428 
  2404 	if ( empty( $upload_path ) || 'wp-content/uploads' === $upload_path ) {
  2429 	if ( empty( $upload_path ) || 'wp-content/uploads' === $upload_path ) {
  2405 		$dir = WP_CONTENT_DIR . '/uploads';
  2430 		$dir = WP_CONTENT_DIR . '/uploads';
  2406 	} elseif ( 0 !== strpos( $upload_path, ABSPATH ) ) {
  2431 	} elseif ( ! str_starts_with( $upload_path, ABSPATH ) ) {
  2407 		// $dir is absolute, $upload_path is (maybe) relative to ABSPATH.
  2432 		// $dir is absolute, $upload_path is (maybe) relative to ABSPATH.
  2408 		$dir = path_join( ABSPATH, $upload_path );
  2433 		$dir = path_join( ABSPATH, $upload_path );
  2409 	} else {
  2434 	} else {
  2410 		$dir = $upload_path;
  2435 		$dir = $upload_path;
  2411 	}
  2436 	}
  2412 
  2437 
  2413 	$url = get_option( 'upload_url_path' );
  2438 	$url = get_option( 'upload_url_path' );
  2414 	if ( ! $url ) {
  2439 	if ( ! $url ) {
  2415 		if ( empty( $upload_path ) || ( 'wp-content/uploads' === $upload_path ) || ( $upload_path == $dir ) ) {
  2440 		if ( empty( $upload_path ) || ( 'wp-content/uploads' === $upload_path ) || ( $upload_path === $dir ) ) {
  2416 			$url = WP_CONTENT_URL . '/uploads';
  2441 			$url = WP_CONTENT_URL . '/uploads';
  2417 		} else {
  2442 		} else {
  2418 			$url = trailingslashit( $siteurl ) . $upload_path;
  2443 			$url = trailingslashit( $siteurl ) . $upload_path;
  2419 		}
  2444 		}
  2420 	}
  2445 	}
  2500 		'error'   => false,
  2525 		'error'   => false,
  2501 	);
  2526 	);
  2502 }
  2527 }
  2503 
  2528 
  2504 /**
  2529 /**
  2505  * Get a filename that is sanitized and unique for the given directory.
  2530  * Gets a filename that is sanitized and unique for the given directory.
  2506  *
  2531  *
  2507  * If the filename is not unique, then a number will be added to the filename
  2532  * If the filename is not unique, then a number will be added to the filename
  2508  * before the extension, and will continue adding numbers until the filename
  2533  * before the extension, and will continue adding numbers until the filename
  2509  * is unique.
  2534  * is unique.
  2510  *
  2535  *
  2563 		 * in _wp_handle_upload(). Using wp_check_filetype() would be sufficient here.
  2588 		 * in _wp_handle_upload(). Using wp_check_filetype() would be sufficient here.
  2564 		 */
  2589 		 */
  2565 		$file_type = wp_check_filetype( $filename );
  2590 		$file_type = wp_check_filetype( $filename );
  2566 		$mime_type = $file_type['type'];
  2591 		$mime_type = $file_type['type'];
  2567 
  2592 
  2568 		$is_image    = ( ! empty( $mime_type ) && 0 === strpos( $mime_type, 'image/' ) );
  2593 		$is_image    = ( ! empty( $mime_type ) && str_starts_with( $mime_type, 'image/' ) );
  2569 		$upload_dir  = wp_get_upload_dir();
  2594 		$upload_dir  = wp_get_upload_dir();
  2570 		$lc_filename = null;
  2595 		$lc_filename = null;
  2571 
  2596 
  2572 		$lc_ext = strtolower( $ext );
  2597 		$lc_ext = strtolower( $ext );
  2573 		$_dir   = trailingslashit( $dir );
  2598 		$_dir   = trailingslashit( $dir );
  2623 
  2648 
  2624 		$files = array();
  2649 		$files = array();
  2625 		$count = 10000;
  2650 		$count = 10000;
  2626 
  2651 
  2627 		// The (resized) image files would have name and extension, and will be in the uploads dir.
  2652 		// The (resized) image files would have name and extension, and will be in the uploads dir.
  2628 		if ( $name && $ext && @is_dir( $dir ) && false !== strpos( $dir, $upload_dir['basedir'] ) ) {
  2653 		if ( $name && $ext && @is_dir( $dir ) && str_contains( $dir, $upload_dir['basedir'] ) ) {
  2629 			/**
  2654 			/**
  2630 			 * Filters the file list used for calculating a unique filename for a newly added file.
  2655 			 * Filters the file list used for calculating a unique filename for a newly added file.
  2631 			 *
  2656 			 *
  2632 			 * Returning an array from the filter will effectively short-circuit retrieval
  2657 			 * Returning an array from the filter will effectively short-circuit retrieval
  2633 			 * from the filesystem and return the passed value instead.
  2658 			 * from the filesystem and return the passed value instead.
  2669 						"-{$new_number}{$lc_ext}",
  2694 						"-{$new_number}{$lc_ext}",
  2670 						$filename
  2695 						$filename
  2671 					);
  2696 					);
  2672 
  2697 
  2673 					$number = $new_number;
  2698 					$number = $new_number;
  2674 					$i++;
  2699 					++$i;
  2675 				}
  2700 				}
  2676 			}
  2701 			}
  2677 		}
  2702 		}
  2678 
  2703 
  2679 		/*
  2704 		/*
  2742 						"-{$new_number}{$lc_ext}",
  2767 						"-{$new_number}{$lc_ext}",
  2743 						$filename
  2768 						$filename
  2744 					);
  2769 					);
  2745 
  2770 
  2746 					$number = $new_number;
  2771 					$number = $new_number;
  2747 					$i++;
  2772 					++$i;
  2748 				}
  2773 				}
  2749 			}
  2774 			}
  2750 		}
  2775 		}
  2751 	}
  2776 	}
  2752 
  2777 
  2825 
  2850 
  2826 	return false;
  2851 	return false;
  2827 }
  2852 }
  2828 
  2853 
  2829 /**
  2854 /**
  2830  * Create a file in the upload folder with given content.
  2855  * Creates a file in the upload folder with given content.
  2831  *
  2856  *
  2832  * If there is an error, then the key 'error' will exist with the error message.
  2857  * If there is an error, then the key 'error' will exist with the error message.
  2833  * If success, then the key 'file' will have the unique file path, the 'url' key
  2858  * If success, then the key 'file' will have the unique file path, the 'url' key
  2834  * will have the link to the new file. and the 'error' key will be set to false.
  2859  * will have the link to the new file. and the 'error' key will be set to false.
  2835  *
  2860  *
  2844  * @since 2.0.0
  2869  * @since 2.0.0
  2845  *
  2870  *
  2846  * @param string      $name       Filename.
  2871  * @param string      $name       Filename.
  2847  * @param null|string $deprecated Never used. Set to null.
  2872  * @param null|string $deprecated Never used. Set to null.
  2848  * @param string      $bits       File content
  2873  * @param string      $bits       File content
  2849  * @param string      $time       Optional. Time formatted in 'yyyy/mm'. Default null.
  2874  * @param string|null $time       Optional. Time formatted in 'yyyy/mm'. Default null.
  2850  * @return array {
  2875  * @return array {
  2851  *     Information about the newly-uploaded file.
  2876  *     Information about the newly-uploaded file.
  2852  *
  2877  *
  2853  *     @type string       $file  Filename of the newly-uploaded file.
  2878  *     @type string       $file  Filename of the newly-uploaded file.
  2854  *     @type string       $url   URL of the uploaded file.
  2879  *     @type string       $url   URL of the uploaded file.
  2901 
  2926 
  2902 	$filename = wp_unique_filename( $upload['path'], $name );
  2927 	$filename = wp_unique_filename( $upload['path'], $name );
  2903 
  2928 
  2904 	$new_file = $upload['path'] . "/$filename";
  2929 	$new_file = $upload['path'] . "/$filename";
  2905 	if ( ! wp_mkdir_p( dirname( $new_file ) ) ) {
  2930 	if ( ! wp_mkdir_p( dirname( $new_file ) ) ) {
  2906 		if ( 0 === strpos( $upload['basedir'], ABSPATH ) ) {
  2931 		if ( str_starts_with( $upload['basedir'], ABSPATH ) ) {
  2907 			$error_path = str_replace( ABSPATH, '', $upload['basedir'] ) . $upload['subdir'];
  2932 			$error_path = str_replace( ABSPATH, '', $upload['basedir'] ) . $upload['subdir'];
  2908 		} else {
  2933 		} else {
  2909 			$error_path = wp_basename( $upload['basedir'] ) . $upload['subdir'];
  2934 			$error_path = wp_basename( $upload['basedir'] ) . $upload['subdir'];
  2910 		}
  2935 		}
  2911 
  2936 
  2955 		'sideload'
  2980 		'sideload'
  2956 	);
  2981 	);
  2957 }
  2982 }
  2958 
  2983 
  2959 /**
  2984 /**
  2960  * Retrieve the file type based on the extension name.
  2985  * Retrieves the file type based on the extension name.
  2961  *
  2986  *
  2962  * @since 2.5.0
  2987  * @since 2.5.0
  2963  *
  2988  *
  2964  * @param string $ext The extension to search.
  2989  * @param string $ext The extension to search.
  2965  * @return string|void The file type, example: audio, video, document, spreadsheet, etc.
  2990  * @return string|void The file type, example: audio, video, document, spreadsheet, etc.
  2994 
  3019 
  2995 	return $extensions[0];
  3020 	return $extensions[0];
  2996 }
  3021 }
  2997 
  3022 
  2998 /**
  3023 /**
  2999  * Retrieve the file type from the file name.
  3024  * Retrieves the file type from the file name.
  3000  *
  3025  *
  3001  * You can optionally define the mime array, if needed.
  3026  * You can optionally define the mime array, if needed.
  3002  *
  3027  *
  3003  * @since 2.0.4
  3028  * @since 2.0.4
  3004  *
  3029  *
  3005  * @param string   $filename File name or path.
  3030  * @param string        $filename File name or path.
  3006  * @param string[] $mimes    Optional. Array of allowed mime types keyed by their file extension regex.
  3031  * @param string[]|null $mimes    Optional. Array of allowed mime types keyed by their file extension regex.
       
  3032  *                                Defaults to the result of get_allowed_mime_types().
  3007  * @return array {
  3033  * @return array {
  3008  *     Values for the extension and mime type.
  3034  *     Values for the extension and mime type.
  3009  *
  3035  *
  3010  *     @type string|false $ext  File extension, or false if the file doesn't match a mime type.
  3036  *     @type string|false $ext  File extension, or false if the file doesn't match a mime type.
  3011  *     @type string|false $type File mime type, or false if the file doesn't match a mime type.
  3037  *     @type string|false $type File mime type, or false if the file doesn't match a mime type.
  3029 
  3055 
  3030 	return compact( 'ext', 'type' );
  3056 	return compact( 'ext', 'type' );
  3031 }
  3057 }
  3032 
  3058 
  3033 /**
  3059 /**
  3034  * Attempt to determine the real file type of a file.
  3060  * Attempts to determine the real file type of a file.
  3035  *
  3061  *
  3036  * If unable to, the file name extension will be used to determine type.
  3062  * If unable to, the file name extension will be used to determine type.
  3037  *
  3063  *
  3038  * If it's determined that the extension does not match the file's real type,
  3064  * If it's determined that the extension does not match the file's real type,
  3039  * then the "proper_filename" value will be set with a proper filename and extension.
  3065  * then the "proper_filename" value will be set with a proper filename and extension.
  3040  *
  3066  *
  3041  * Currently this function only supports renaming images validated via wp_get_image_mime().
  3067  * Currently this function only supports renaming images validated via wp_get_image_mime().
  3042  *
  3068  *
  3043  * @since 3.0.0
  3069  * @since 3.0.0
  3044  *
  3070  *
  3045  * @param string   $file     Full path to the file.
  3071  * @param string        $file     Full path to the file.
  3046  * @param string   $filename The name of the file (may differ from $file due to $file being
  3072  * @param string        $filename The name of the file (may differ from $file due to $file being
  3047  *                           in a tmp directory).
  3073  *                                in a tmp directory).
  3048  * @param string[] $mimes    Optional. Array of allowed mime types keyed by their file extension regex.
  3074  * @param string[]|null $mimes    Optional. Array of allowed mime types keyed by their file extension regex.
       
  3075  *                                Defaults to the result of get_allowed_mime_types().
  3049  * @return array {
  3076  * @return array {
  3050  *     Values for the extension, mime type, and corrected filename.
  3077  *     Values for the extension, mime type, and corrected filename.
  3051  *
  3078  *
  3052  *     @type string|false $ext             File extension, or false if the file doesn't match a mime type.
  3079  *     @type string|false $ext             File extension, or false if the file doesn't match a mime type.
  3053  *     @type string|false $type            File mime type, or false if the file doesn't match a mime type.
  3080  *     @type string|false $type            File mime type, or false if the file doesn't match a mime type.
  3068 	}
  3095 	}
  3069 
  3096 
  3070 	$real_mime = false;
  3097 	$real_mime = false;
  3071 
  3098 
  3072 	// Validate image types.
  3099 	// Validate image types.
  3073 	if ( $type && 0 === strpos( $type, 'image/' ) ) {
  3100 	if ( $type && str_starts_with( $type, 'image/' ) ) {
  3074 
  3101 
  3075 		// Attempt to figure out what type of image it actually is.
  3102 		// Attempt to figure out what type of image it actually is.
  3076 		$real_mime = wp_get_image_mime( $file );
  3103 		$real_mime = wp_get_image_mime( $file );
  3077 
  3104 
  3078 		if ( $real_mime && $real_mime != $type ) {
  3105 		if ( $real_mime && $real_mime !== $type ) {
  3079 			/**
  3106 			/**
  3080 			 * Filters the list mapping image mime types to their respective extensions.
  3107 			 * Filters the list mapping image mime types to their respective extensions.
  3081 			 *
  3108 			 *
  3082 			 * @since 3.0.0
  3109 			 * @since 3.0.0
  3083 			 *
  3110 			 *
  3090 					'image/png'  => 'png',
  3117 					'image/png'  => 'png',
  3091 					'image/gif'  => 'gif',
  3118 					'image/gif'  => 'gif',
  3092 					'image/bmp'  => 'bmp',
  3119 					'image/bmp'  => 'bmp',
  3093 					'image/tiff' => 'tif',
  3120 					'image/tiff' => 'tif',
  3094 					'image/webp' => 'webp',
  3121 					'image/webp' => 'webp',
       
  3122 					'image/avif' => 'avif',
  3095 				)
  3123 				)
  3096 			);
  3124 			);
  3097 
  3125 
  3098 			// Replace whatever is after the last period in the filename with the correct extension.
  3126 			// Replace whatever is after the last period in the filename with the correct extension.
  3099 			if ( ! empty( $mime_to_ext[ $real_mime ] ) ) {
  3127 			if ( ! empty( $mime_to_ext[ $real_mime ] ) ) {
  3100 				$filename_parts = explode( '.', $filename );
  3128 				$filename_parts = explode( '.', $filename );
  3101 				array_pop( $filename_parts );
  3129 				array_pop( $filename_parts );
  3102 				$filename_parts[] = $mime_to_ext[ $real_mime ];
  3130 				$filename_parts[] = $mime_to_ext[ $real_mime ];
  3103 				$new_filename     = implode( '.', $filename_parts );
  3131 				$new_filename     = implode( '.', $filename_parts );
  3104 
  3132 
  3105 				if ( $new_filename != $filename ) {
  3133 				if ( $new_filename !== $filename ) {
  3106 					$proper_filename = $new_filename; // Mark that it changed.
  3134 					$proper_filename = $new_filename; // Mark that it changed.
  3107 				}
  3135 				}
       
  3136 
  3108 				// Redefine the extension / MIME.
  3137 				// Redefine the extension / MIME.
  3109 				$wp_filetype = wp_check_filetype( $new_filename, $mimes );
  3138 				$wp_filetype = wp_check_filetype( $new_filename, $mimes );
  3110 				$ext         = $wp_filetype['ext'];
  3139 				$ext         = $wp_filetype['ext'];
  3111 				$type        = $wp_filetype['type'];
  3140 				$type        = $wp_filetype['type'];
  3112 			} else {
  3141 			} else {
  3119 	// Validate files that didn't get validated during previous checks.
  3148 	// Validate files that didn't get validated during previous checks.
  3120 	if ( $type && ! $real_mime && extension_loaded( 'fileinfo' ) ) {
  3149 	if ( $type && ! $real_mime && extension_loaded( 'fileinfo' ) ) {
  3121 		$finfo     = finfo_open( FILEINFO_MIME_TYPE );
  3150 		$finfo     = finfo_open( FILEINFO_MIME_TYPE );
  3122 		$real_mime = finfo_file( $finfo, $file );
  3151 		$real_mime = finfo_file( $finfo, $file );
  3123 		finfo_close( $finfo );
  3152 		finfo_close( $finfo );
       
  3153 
       
  3154 		$google_docs_types = array(
       
  3155 			'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
       
  3156 			'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
       
  3157 		);
       
  3158 
       
  3159 		foreach ( $google_docs_types as $google_docs_type ) {
       
  3160 			/*
       
  3161 			 * finfo_file() can return duplicate mime type for Google docs,
       
  3162 			 * this conditional reduces it to a single instance.
       
  3163 			 *
       
  3164 			 * @see https://bugs.php.net/bug.php?id=77784
       
  3165 			 * @see https://core.trac.wordpress.org/ticket/57898
       
  3166 			 */
       
  3167 			if ( 2 === substr_count( $real_mime, $google_docs_type ) ) {
       
  3168 				$real_mime = $google_docs_type;
       
  3169 			}
       
  3170 		}
  3124 
  3171 
  3125 		// fileinfo often misidentifies obscure files as one of these types.
  3172 		// fileinfo often misidentifies obscure files as one of these types.
  3126 		$nonspecific_types = array(
  3173 		$nonspecific_types = array(
  3127 			'application/octet-stream',
  3174 			'application/octet-stream',
  3128 			'application/encrypted',
  3175 			'application/encrypted',
  3139 			// File is a non-specific binary type. That's ok if it's a type that generally tends to be binary.
  3186 			// File is a non-specific binary type. That's ok if it's a type that generally tends to be binary.
  3140 			if ( ! in_array( substr( $type, 0, strcspn( $type, '/' ) ), array( 'application', 'video', 'audio' ), true ) ) {
  3187 			if ( ! in_array( substr( $type, 0, strcspn( $type, '/' ) ), array( 'application', 'video', 'audio' ), true ) ) {
  3141 				$type = false;
  3188 				$type = false;
  3142 				$ext  = false;
  3189 				$ext  = false;
  3143 			}
  3190 			}
  3144 		} elseif ( 0 === strpos( $real_mime, 'video/' ) || 0 === strpos( $real_mime, 'audio/' ) ) {
  3191 		} elseif ( str_starts_with( $real_mime, 'video/' ) || str_starts_with( $real_mime, 'audio/' ) ) {
  3145 			/*
  3192 			/*
  3146 			 * For these types, only the major type must match the real value.
  3193 			 * For these types, only the major type must match the real value.
  3147 			 * This means that common mismatches are forgiven: application/vnd.apple.numbers is often misidentified as application/zip,
  3194 			 * This means that common mismatches are forgiven: application/vnd.apple.numbers is often misidentified as application/zip,
  3148 			 * and some media files are commonly named with the wrong extension (.mov instead of .mp4)
  3195 			 * and some media files are commonly named with the wrong extension (.mov instead of .mp4)
  3149 			 */
  3196 			 */
  3225 	 * Filters the "real" file type of the given file.
  3272 	 * Filters the "real" file type of the given file.
  3226 	 *
  3273 	 *
  3227 	 * @since 3.0.0
  3274 	 * @since 3.0.0
  3228 	 * @since 5.1.0 The $real_mime parameter was added.
  3275 	 * @since 5.1.0 The $real_mime parameter was added.
  3229 	 *
  3276 	 *
  3230 	 * @param array        $wp_check_filetype_and_ext {
  3277 	 * @param array         $wp_check_filetype_and_ext {
  3231 	 *     Values for the extension, mime type, and corrected filename.
  3278 	 *     Values for the extension, mime type, and corrected filename.
  3232 	 *
  3279 	 *
  3233 	 *     @type string|false $ext             File extension, or false if the file doesn't match a mime type.
  3280 	 *     @type string|false $ext             File extension, or false if the file doesn't match a mime type.
  3234 	 *     @type string|false $type            File mime type, or false if the file doesn't match a mime type.
  3281 	 *     @type string|false $type            File mime type, or false if the file doesn't match a mime type.
  3235 	 *     @type string|false $proper_filename File name with its correct extension, or false if it cannot be determined.
  3282 	 *     @type string|false $proper_filename File name with its correct extension, or false if it cannot be determined.
  3236 	 * }
  3283 	 * }
  3237 	 * @param string       $file                      Full path to the file.
  3284 	 * @param string        $file                      Full path to the file.
  3238 	 * @param string       $filename                  The name of the file (may differ from $file due to
  3285 	 * @param string        $filename                  The name of the file (may differ from $file due to
  3239 	 *                                                $file being in a tmp directory).
  3286 	 *                                                 $file being in a tmp directory).
  3240 	 * @param string[]     $mimes                     Array of mime types keyed by their file extension regex.
  3287 	 * @param string[]|null $mimes                     Array of mime types keyed by their file extension regex, or null if
  3241 	 * @param string|false $real_mime                 The actual mime type or false if the type cannot be determined.
  3288 	 *                                                 none were provided.
       
  3289 	 * @param string|false  $real_mime                 The actual mime type or false if the type cannot be determined.
  3242 	 */
  3290 	 */
  3243 	return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes, $real_mime );
  3291 	return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes, $real_mime );
  3244 }
  3292 }
  3245 
  3293 
  3246 /**
  3294 /**
  3248  *
  3296  *
  3249  * This depends on exif_imagetype() or getimagesize() to determine real mime types.
  3297  * This depends on exif_imagetype() or getimagesize() to determine real mime types.
  3250  *
  3298  *
  3251  * @since 4.7.1
  3299  * @since 4.7.1
  3252  * @since 5.8.0 Added support for WebP images.
  3300  * @since 5.8.0 Added support for WebP images.
       
  3301  * @since 6.5.0 Added support for AVIF images.
  3253  *
  3302  *
  3254  * @param string $file Full path to the file.
  3303  * @param string $file Full path to the file.
  3255  * @return string|false The actual mime type or false if the type cannot be determined.
  3304  * @return string|false The actual mime type or false if the type cannot be determined.
  3256  */
  3305  */
  3257 function wp_get_image_mime( $file ) {
  3306 function wp_get_image_mime( $file ) {
  3270 				&& ! defined( 'WP_RUN_CORE_TESTS' )
  3319 				&& ! defined( 'WP_RUN_CORE_TESTS' )
  3271 			) {
  3320 			) {
  3272 				// Not using wp_getimagesize() here to avoid an infinite loop.
  3321 				// Not using wp_getimagesize() here to avoid an infinite loop.
  3273 				$imagesize = getimagesize( $file );
  3322 				$imagesize = getimagesize( $file );
  3274 			} else {
  3323 			} else {
  3275 				// phpcs:ignore WordPress.PHP.NoSilencedErrors
       
  3276 				$imagesize = @getimagesize( $file );
  3324 				$imagesize = @getimagesize( $file );
  3277 			}
  3325 			}
  3278 
  3326 
  3279 			$mime = ( isset( $imagesize['mime'] ) ) ? $imagesize['mime'] : false;
  3327 			$mime = ( isset( $imagesize['mime'] ) ) ? $imagesize['mime'] : false;
  3280 		} else {
  3328 		} else {
  3297 		 * https://github.com/webmproject/libwebp/blob/master/imageio/image_dec.c#L30
  3345 		 * https://github.com/webmproject/libwebp/blob/master/imageio/image_dec.c#L30
  3298 		 */
  3346 		 */
  3299 		$magic = bin2hex( $magic );
  3347 		$magic = bin2hex( $magic );
  3300 		if (
  3348 		if (
  3301 			// RIFF.
  3349 			// RIFF.
  3302 			( 0 === strpos( $magic, '52494646' ) ) &&
  3350 			( str_starts_with( $magic, '52494646' ) ) &&
  3303 			// WEBP.
  3351 			// WEBP.
  3304 			( 16 === strpos( $magic, '57454250' ) )
  3352 			( 16 === strpos( $magic, '57454250' ) )
  3305 		) {
  3353 		) {
  3306 			$mime = 'image/webp';
  3354 			$mime = 'image/webp';
  3307 		}
  3355 		}
       
  3356 
       
  3357 		/**
       
  3358 		 * Add AVIF fallback detection when image library doesn't support AVIF.
       
  3359 		 *
       
  3360 		 * Detection based on section 4.3.1 File-type box definition of the ISO/IEC 14496-12
       
  3361 		 * specification and the AV1-AVIF spec, see https://aomediacodec.github.io/av1-avif/v1.1.0.html#brands.
       
  3362 		 */
       
  3363 
       
  3364 		// Divide the header string into 4 byte groups.
       
  3365 		$magic = str_split( $magic, 8 );
       
  3366 
       
  3367 		if (
       
  3368 			isset( $magic[1] ) &&
       
  3369 			isset( $magic[2] ) &&
       
  3370 			'ftyp' === hex2bin( $magic[1] ) &&
       
  3371 			( 'avif' === hex2bin( $magic[2] ) || 'avis' === hex2bin( $magic[2] ) )
       
  3372 		) {
       
  3373 			$mime = 'image/avif';
       
  3374 		}
  3308 	} catch ( Exception $e ) {
  3375 	} catch ( Exception $e ) {
  3309 		$mime = false;
  3376 		$mime = false;
  3310 	}
  3377 	}
  3311 
  3378 
  3312 	return $mime;
  3379 	return $mime;
  3313 }
  3380 }
  3314 
  3381 
  3315 /**
  3382 /**
  3316  * Retrieve list of mime types and file extensions.
  3383  * Retrieves the list of mime types and file extensions.
  3317  *
  3384  *
  3318  * @since 3.5.0
  3385  * @since 3.5.0
  3319  * @since 4.2.0 Support was added for GIMP (.xcf) files.
  3386  * @since 4.2.0 Support was added for GIMP (.xcf) files.
  3320  * @since 4.9.2 Support was added for Flac (.flac) files.
  3387  * @since 4.9.2 Support was added for Flac (.flac) files.
  3321  * @since 4.9.6 Support was added for AAC (.aac) files.
  3388  * @since 4.9.6 Support was added for AAC (.aac) files.
  3330 	 * mime types, use the {@see 'upload_mimes'} filter.
  3397 	 * mime types, use the {@see 'upload_mimes'} filter.
  3331 	 *
  3398 	 *
  3332 	 * @since 3.5.0
  3399 	 * @since 3.5.0
  3333 	 *
  3400 	 *
  3334 	 * @param string[] $wp_get_mime_types Mime types keyed by the file extension regex
  3401 	 * @param string[] $wp_get_mime_types Mime types keyed by the file extension regex
  3335 	 *                                 corresponding to those types.
  3402 	 *                                    corresponding to those types.
  3336 	 */
  3403 	 */
  3337 	return apply_filters(
  3404 	return apply_filters(
  3338 		'mime_types',
  3405 		'mime_types',
  3339 		array(
  3406 		array(
  3340 			// Image formats.
  3407 			// Image formats.
  3342 			'gif'                          => 'image/gif',
  3409 			'gif'                          => 'image/gif',
  3343 			'png'                          => 'image/png',
  3410 			'png'                          => 'image/png',
  3344 			'bmp'                          => 'image/bmp',
  3411 			'bmp'                          => 'image/bmp',
  3345 			'tiff|tif'                     => 'image/tiff',
  3412 			'tiff|tif'                     => 'image/tiff',
  3346 			'webp'                         => 'image/webp',
  3413 			'webp'                         => 'image/webp',
       
  3414 			'avif'                         => 'image/avif',
  3347 			'ico'                          => 'image/x-icon',
  3415 			'ico'                          => 'image/x-icon',
  3348 			'heic'                         => 'image/heic',
  3416 			'heic'                         => 'image/heic',
  3349 			// Video formats.
  3417 			// Video formats.
  3350 			'asf|asx'                      => 'video/x-ms-asf',
  3418 			'asf|asx'                      => 'video/x-ms-asf',
  3351 			'wmv'                          => 'video/x-ms-wmv',
  3419 			'wmv'                          => 'video/x-ms-wmv',
  3463 	 * @param array[] $ext2type Multi-dimensional array of file extensions types keyed by the type of file.
  3531 	 * @param array[] $ext2type Multi-dimensional array of file extensions types keyed by the type of file.
  3464 	 */
  3532 	 */
  3465 	return apply_filters(
  3533 	return apply_filters(
  3466 		'ext2type',
  3534 		'ext2type',
  3467 		array(
  3535 		array(
  3468 			'image'       => array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'bmp', 'tif', 'tiff', 'ico', 'heic', 'webp' ),
  3536 			'image'       => array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'bmp', 'tif', 'tiff', 'ico', 'heic', 'webp', 'avif' ),
  3469 			'audio'       => array( 'aac', 'ac3', 'aif', 'aiff', 'flac', 'm3a', 'm4a', 'm4b', 'mka', 'mp1', 'mp2', 'mp3', 'ogg', 'oga', 'ram', 'wav', 'wma' ),
  3537 			'audio'       => array( 'aac', 'ac3', 'aif', 'aiff', 'flac', 'm3a', 'm4a', 'm4b', 'mka', 'mp1', 'mp2', 'mp3', 'ogg', 'oga', 'ram', 'wav', 'wma' ),
  3470 			'video'       => array( '3g2', '3gp', '3gpp', 'asf', 'avi', 'divx', 'dv', 'flv', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'mpv', 'ogm', 'ogv', 'qt', 'rm', 'vob', 'wmv' ),
  3538 			'video'       => array( '3g2', '3gp', '3gpp', 'asf', 'avi', 'divx', 'dv', 'flv', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'mpv', 'ogm', 'ogv', 'qt', 'rm', 'vob', 'wmv' ),
  3471 			'document'    => array( 'doc', 'docx', 'docm', 'dotm', 'odt', 'pages', 'pdf', 'xps', 'oxps', 'rtf', 'wp', 'wpd', 'psd', 'xcf' ),
  3539 			'document'    => array( 'doc', 'docx', 'docm', 'dotm', 'odt', 'pages', 'pdf', 'xps', 'oxps', 'rtf', 'wp', 'wpd', 'psd', 'xcf' ),
  3472 			'spreadsheet' => array( 'numbers', 'ods', 'xls', 'xlsx', 'xlsm', 'xlsb' ),
  3540 			'spreadsheet' => array( 'numbers', 'ods', 'xls', 'xlsx', 'xlsm', 'xlsb' ),
  3473 			'interactive' => array( 'swf', 'key', 'ppt', 'pptx', 'pptm', 'pps', 'ppsx', 'ppsm', 'sldx', 'sldm', 'odp' ),
  3541 			'interactive' => array( 'swf', 'key', 'ppt', 'pptx', 'pptm', 'pps', 'ppsx', 'ppsm', 'sldx', 'sldm', 'odp' ),
  3515 	 */
  3583 	 */
  3516 	return (int) apply_filters( 'wp_filesize', $size, $path );
  3584 	return (int) apply_filters( 'wp_filesize', $size, $path );
  3517 }
  3585 }
  3518 
  3586 
  3519 /**
  3587 /**
  3520  * Retrieve list of allowed mime types and file extensions.
  3588  * Retrieves the list of allowed mime types and file extensions.
  3521  *
  3589  *
  3522  * @since 2.8.6
  3590  * @since 2.8.6
  3523  *
  3591  *
  3524  * @param int|WP_User $user Optional. User to check. Defaults to current user.
  3592  * @param int|WP_User $user Optional. User to check. Defaults to current user.
  3525  * @return string[] Array of mime types keyed by the file extension regex corresponding
  3593  * @return string[] Array of mime types keyed by the file extension regex corresponding
  3536 	if ( empty( $unfiltered ) ) {
  3604 	if ( empty( $unfiltered ) ) {
  3537 		unset( $t['htm|html'], $t['js'] );
  3605 		unset( $t['htm|html'], $t['js'] );
  3538 	}
  3606 	}
  3539 
  3607 
  3540 	/**
  3608 	/**
  3541 	 * Filters list of allowed mime types and file extensions.
  3609 	 * Filters the list of allowed mime types and file extensions.
  3542 	 *
  3610 	 *
  3543 	 * @since 2.0.0
  3611 	 * @since 2.0.0
  3544 	 *
  3612 	 *
  3545 	 * @param array            $t    Mime types keyed by the file extension regex corresponding to those types.
  3613 	 * @param array            $t    Mime types keyed by the file extension regex corresponding to those types.
  3546 	 * @param int|WP_User|null $user User ID, User object or null if not provided (indicates current user).
  3614 	 * @param int|WP_User|null $user User ID, User object or null if not provided (indicates current user).
  3547 	 */
  3615 	 */
  3548 	return apply_filters( 'upload_mimes', $t, $user );
  3616 	return apply_filters( 'upload_mimes', $t, $user );
  3549 }
  3617 }
  3550 
  3618 
  3551 /**
  3619 /**
  3552  * Display "Are You Sure" message to confirm the action being taken.
  3620  * Displays "Are You Sure" message to confirm the action being taken.
  3553  *
  3621  *
  3554  * If the action has the nonce explain message, then it will be displayed
  3622  * If the action has the nonce explain message, then it will be displayed
  3555  * along with the "Are you sure?" message.
  3623  * along with the "Are you sure?" message.
  3556  *
  3624  *
  3557  * @since 2.0.4
  3625  * @since 2.0.4
  3567 		$title = sprintf(
  3635 		$title = sprintf(
  3568 			/* translators: %s: Site title. */
  3636 			/* translators: %s: Site title. */
  3569 			__( 'You are attempting to log out of %s' ),
  3637 			__( 'You are attempting to log out of %s' ),
  3570 			get_bloginfo( 'name' )
  3638 			get_bloginfo( 'name' )
  3571 		);
  3639 		);
  3572 		$html        = $title;
  3640 
  3573 		$html       .= '</p><p>';
       
  3574 		$redirect_to = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '';
  3641 		$redirect_to = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '';
  3575 		$html       .= sprintf(
  3642 
       
  3643 		$html  = $title;
       
  3644 		$html .= '</p><p>';
       
  3645 		$html .= sprintf(
  3576 			/* translators: %s: Logout URL. */
  3646 			/* translators: %s: Logout URL. */
  3577 			__( 'Do you really want to <a href="%s">log out</a>?' ),
  3647 			__( 'Do you really want to <a href="%s">log out</a>?' ),
  3578 			wp_logout_url( $redirect_to )
  3648 			wp_logout_url( $redirect_to )
  3579 		);
  3649 		);
  3580 	} else {
  3650 	} else {
  3581 		$html = __( 'The link you followed has expired.' );
  3651 		$html = __( 'The link you followed has expired.' );
       
  3652 
  3582 		if ( wp_get_referer() ) {
  3653 		if ( wp_get_referer() ) {
       
  3654 			$wp_http_referer = remove_query_arg( 'updated', wp_get_referer() );
       
  3655 			$wp_http_referer = wp_validate_redirect( sanitize_url( $wp_http_referer ) );
       
  3656 
  3583 			$html .= '</p><p>';
  3657 			$html .= '</p><p>';
  3584 			$html .= sprintf(
  3658 			$html .= sprintf(
  3585 				'<a href="%s">%s</a>',
  3659 				'<a href="%s">%s</a>',
  3586 				esc_url( remove_query_arg( 'updated', wp_get_referer() ) ),
  3660 				esc_url( $wp_http_referer ),
  3587 				__( 'Please try again.' )
  3661 				__( 'Please try again.' )
  3588 			);
  3662 			);
  3589 		}
  3663 		}
  3590 	}
  3664 	}
  3591 
  3665 
  3614  *
  3688  *
  3615  * @global WP_Query $wp_query WordPress Query object.
  3689  * @global WP_Query $wp_query WordPress Query object.
  3616  *
  3690  *
  3617  * @param string|WP_Error  $message Optional. Error message. If this is a WP_Error object,
  3691  * @param string|WP_Error  $message Optional. Error message. If this is a WP_Error object,
  3618  *                                  and not an Ajax or XML-RPC request, the error's messages are used.
  3692  *                                  and not an Ajax or XML-RPC request, the error's messages are used.
  3619  *                                  Default empty.
  3693  *                                  Default empty string.
  3620  * @param string|int       $title   Optional. Error title. If `$message` is a `WP_Error` object,
  3694  * @param string|int       $title   Optional. Error title. If `$message` is a `WP_Error` object,
  3621  *                                  error data with the key 'title' may be used to specify the title.
  3695  *                                  error data with the key 'title' may be used to specify the title.
  3622  *                                  If `$title` is an integer, then it is treated as the response
  3696  *                                  If `$title` is an integer, then it is treated as the response code.
  3623  *                                  code. Default empty.
  3697  *                                  Default empty string.
  3624  * @param string|array|int $args {
  3698  * @param string|array|int $args {
  3625  *     Optional. Arguments to control behavior. If `$args` is an integer, then it is treated
  3699  *     Optional. Arguments to control behavior. If `$args` is an integer, then it is treated
  3626  *     as the response code. Default empty array.
  3700  *     as the response code. Default empty array.
  3627  *
  3701  *
  3628  *     @type int    $response       The HTTP response code. Default 200 for Ajax requests, 500 otherwise.
  3702  *     @type int    $response       The HTTP response code. Default 200 for Ajax requests, 500 otherwise.
  3666 		 * @since 5.1.0
  3740 		 * @since 5.1.0
  3667 		 *
  3741 		 *
  3668 		 * @param callable $callback Callback function name.
  3742 		 * @param callable $callback Callback function name.
  3669 		 */
  3743 		 */
  3670 		$callback = apply_filters( 'wp_die_json_handler', '_json_wp_die_handler' );
  3744 		$callback = apply_filters( 'wp_die_json_handler', '_json_wp_die_handler' );
  3671 	} elseif ( defined( 'REST_REQUEST' ) && REST_REQUEST && wp_is_jsonp_request() ) {
  3745 	} elseif ( wp_is_serving_rest_request() && wp_is_jsonp_request() ) {
  3672 		/**
  3746 		/**
  3673 		 * Filters the callback for killing WordPress execution for JSONP REST requests.
  3747 		 * Filters the callback for killing WordPress execution for JSONP REST requests.
  3674 		 *
  3748 		 *
  3675 		 * @since 5.2.0
  3749 		 * @since 5.2.0
  3676 		 *
  3750 		 *
  3721  *
  3795  *
  3722  * @since 3.0.0
  3796  * @since 3.0.0
  3723  * @access private
  3797  * @access private
  3724  *
  3798  *
  3725  * @param string|WP_Error $message Error message or WP_Error object.
  3799  * @param string|WP_Error $message Error message or WP_Error object.
  3726  * @param string          $title   Optional. Error title. Default empty.
  3800  * @param string          $title   Optional. Error title. Default empty string.
  3727  * @param string|array    $args    Optional. Arguments to control behavior. Default empty array.
  3801  * @param string|array    $args    Optional. Arguments to control behavior. Default empty array.
  3728  */
  3802  */
  3729 function _default_wp_die_handler( $message, $title = '', $args = array() ) {
  3803 function _default_wp_die_handler( $message, $title = '', $args = array() ) {
  3730 	list( $message, $title, $parsed_args ) = _wp_die_process_input( $message, $title, $args );
  3804 	list( $message, $title, $parsed_args ) = _wp_die_process_input( $message, $title, $args );
  3731 
  3805 
  3768 		}
  3842 		}
  3769 
  3843 
  3770 		$text_direction = $parsed_args['text_direction'];
  3844 		$text_direction = $parsed_args['text_direction'];
  3771 		$dir_attr       = "dir='$text_direction'";
  3845 		$dir_attr       = "dir='$text_direction'";
  3772 
  3846 
  3773 		// If `text_direction` was not explicitly passed,
  3847 		/*
  3774 		// use get_language_attributes() if available.
  3848 		 * If `text_direction` was not explicitly passed,
       
  3849 		 * use get_language_attributes() if available.
       
  3850 		 */
  3775 		if ( empty( $args['text_direction'] )
  3851 		if ( empty( $args['text_direction'] )
  3776 			&& function_exists( 'language_attributes' ) && function_exists( 'is_rtl' )
  3852 			&& function_exists( 'language_attributes' ) && function_exists( 'is_rtl' )
  3777 		) {
  3853 		) {
  3778 			$dir_attr = get_language_attributes();
  3854 			$dir_attr = get_language_attributes();
  3779 		}
  3855 		}
  3784 	<meta http-equiv="Content-Type" content="text/html; charset=<?php echo $parsed_args['charset']; ?>" />
  3860 	<meta http-equiv="Content-Type" content="text/html; charset=<?php echo $parsed_args['charset']; ?>" />
  3785 	<meta name="viewport" content="width=device-width">
  3861 	<meta name="viewport" content="width=device-width">
  3786 		<?php
  3862 		<?php
  3787 		if ( function_exists( 'wp_robots' ) && function_exists( 'wp_robots_no_robots' ) && function_exists( 'add_filter' ) ) {
  3863 		if ( function_exists( 'wp_robots' ) && function_exists( 'wp_robots_no_robots' ) && function_exists( 'add_filter' ) ) {
  3788 			add_filter( 'wp_robots', 'wp_robots_no_robots' );
  3864 			add_filter( 'wp_robots', 'wp_robots_no_robots' );
       
  3865 			// Prevent warnings because of $wp_query not existing.
       
  3866 			remove_filter( 'wp_robots', 'wp_robots_noindex_embeds' );
       
  3867 			remove_filter( 'wp_robots', 'wp_robots_noindex_search' );
  3789 			wp_robots();
  3868 			wp_robots();
  3790 		}
  3869 		}
  3791 		?>
  3870 		?>
  3792 	<title><?php echo $title; ?></title>
  3871 	<title><?php echo $title; ?></title>
  3793 	<style type="text/css">
  3872 	<style type="text/css">
  3829 		ul li {
  3908 		ul li {
  3830 			margin-bottom: 10px;
  3909 			margin-bottom: 10px;
  3831 			font-size: 14px ;
  3910 			font-size: 14px ;
  3832 		}
  3911 		}
  3833 		a {
  3912 		a {
  3834 			color: #0073aa;
  3913 			color: #2271b1;
  3835 		}
  3914 		}
  3836 		a:hover,
  3915 		a:hover,
  3837 		a:active {
  3916 		a:active {
  3838 			color: #006799;
  3917 			color: #135e96;
  3839 		}
  3918 		}
  3840 		a:focus {
  3919 		a:focus {
  3841 			color: #124964;
  3920 			color: #043959;
  3842 			-webkit-box-shadow:
  3921 			box-shadow: 0 0 0 2px #2271b1;
  3843 				0 0 0 1px #5b9dd9,
  3922 			outline: 2px solid transparent;
  3844 				0 0 2px 1px rgba(30, 140, 190, 0.8);
       
  3845 			box-shadow:
       
  3846 				0 0 0 1px #5b9dd9,
       
  3847 				0 0 2px 1px rgba(30, 140, 190, 0.8);
       
  3848 			outline: none;
       
  3849 		}
  3923 		}
  3850 		.button {
  3924 		.button {
  3851 			background: #f3f5f6;
  3925 			background: #f3f5f6;
  3852 			border: 1px solid #016087;
  3926 			border: 1px solid #016087;
  3853 			color: #016087;
  3927 			color: #016087;
  3923  *
  3997  *
  3924  * @since 3.4.0
  3998  * @since 3.4.0
  3925  * @access private
  3999  * @access private
  3926  *
  4000  *
  3927  * @param string       $message Error message.
  4001  * @param string       $message Error message.
  3928  * @param string       $title   Optional. Error title (unused). Default empty.
  4002  * @param string       $title   Optional. Error title (unused). Default empty string.
  3929  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  4003  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  3930  */
  4004  */
  3931 function _ajax_wp_die_handler( $message, $title = '', $args = array() ) {
  4005 function _ajax_wp_die_handler( $message, $title = '', $args = array() ) {
  3932 	// Set default 'response' to 200 for Ajax requests.
  4006 	// Set default 'response' to 200 for Ajax requests.
  3933 	$args = wp_parse_args(
  4007 	$args = wp_parse_args(
  3965  *
  4039  *
  3966  * @since 5.1.0
  4040  * @since 5.1.0
  3967  * @access private
  4041  * @access private
  3968  *
  4042  *
  3969  * @param string       $message Error message.
  4043  * @param string       $message Error message.
  3970  * @param string       $title   Optional. Error title. Default empty.
  4044  * @param string       $title   Optional. Error title. Default empty string.
  3971  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  4045  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  3972  */
  4046  */
  3973 function _json_wp_die_handler( $message, $title = '', $args = array() ) {
  4047 function _json_wp_die_handler( $message, $title = '', $args = array() ) {
  3974 	list( $message, $title, $parsed_args ) = _wp_die_process_input( $message, $title, $args );
  4048 	list( $message, $title, $parsed_args ) = _wp_die_process_input( $message, $title, $args );
  3975 
  4049 
  3980 			'status' => $parsed_args['response'],
  4054 			'status' => $parsed_args['response'],
  3981 		),
  4055 		),
  3982 		'additional_errors' => $parsed_args['additional_errors'],
  4056 		'additional_errors' => $parsed_args['additional_errors'],
  3983 	);
  4057 	);
  3984 
  4058 
       
  4059 	if ( isset( $parsed_args['error_data'] ) ) {
       
  4060 		$data['data']['error'] = $parsed_args['error_data'];
       
  4061 	}
       
  4062 
  3985 	if ( ! headers_sent() ) {
  4063 	if ( ! headers_sent() ) {
  3986 		header( "Content-Type: application/json; charset={$parsed_args['charset']}" );
  4064 		header( "Content-Type: application/json; charset={$parsed_args['charset']}" );
  3987 		if ( null !== $parsed_args['response'] ) {
  4065 		if ( null !== $parsed_args['response'] ) {
  3988 			status_header( $parsed_args['response'] );
  4066 			status_header( $parsed_args['response'] );
  3989 		}
  4067 		}
  4003  *
  4081  *
  4004  * @since 5.2.0
  4082  * @since 5.2.0
  4005  * @access private
  4083  * @access private
  4006  *
  4084  *
  4007  * @param string       $message Error message.
  4085  * @param string       $message Error message.
  4008  * @param string       $title   Optional. Error title. Default empty.
  4086  * @param string       $title   Optional. Error title. Default empty string.
  4009  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  4087  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  4010  */
  4088  */
  4011 function _jsonp_wp_die_handler( $message, $title = '', $args = array() ) {
  4089 function _jsonp_wp_die_handler( $message, $title = '', $args = array() ) {
  4012 	list( $message, $title, $parsed_args ) = _wp_die_process_input( $message, $title, $args );
  4090 	list( $message, $title, $parsed_args ) = _wp_die_process_input( $message, $title, $args );
  4013 
  4091 
  4018 			'status' => $parsed_args['response'],
  4096 			'status' => $parsed_args['response'],
  4019 		),
  4097 		),
  4020 		'additional_errors' => $parsed_args['additional_errors'],
  4098 		'additional_errors' => $parsed_args['additional_errors'],
  4021 	);
  4099 	);
  4022 
  4100 
       
  4101 	if ( isset( $parsed_args['error_data'] ) ) {
       
  4102 		$data['data']['error'] = $parsed_args['error_data'];
       
  4103 	}
       
  4104 
  4023 	if ( ! headers_sent() ) {
  4105 	if ( ! headers_sent() ) {
  4024 		header( "Content-Type: application/javascript; charset={$parsed_args['charset']}" );
  4106 		header( "Content-Type: application/javascript; charset={$parsed_args['charset']}" );
  4025 		header( 'X-Content-Type-Options: nosniff' );
  4107 		header( 'X-Content-Type-Options: nosniff' );
  4026 		header( 'X-Robots-Tag: noindex' );
  4108 		header( 'X-Robots-Tag: noindex' );
  4027 		if ( null !== $parsed_args['response'] ) {
  4109 		if ( null !== $parsed_args['response'] ) {
  4047  * @access private
  4129  * @access private
  4048  *
  4130  *
  4049  * @global wp_xmlrpc_server $wp_xmlrpc_server
  4131  * @global wp_xmlrpc_server $wp_xmlrpc_server
  4050  *
  4132  *
  4051  * @param string       $message Error message.
  4133  * @param string       $message Error message.
  4052  * @param string       $title   Optional. Error title. Default empty.
  4134  * @param string       $title   Optional. Error title. Default empty string.
  4053  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  4135  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  4054  */
  4136  */
  4055 function _xmlrpc_wp_die_handler( $message, $title = '', $args = array() ) {
  4137 function _xmlrpc_wp_die_handler( $message, $title = '', $args = array() ) {
  4056 	global $wp_xmlrpc_server;
  4138 	global $wp_xmlrpc_server;
  4057 
  4139 
  4077  *
  4159  *
  4078  * @since 5.2.0
  4160  * @since 5.2.0
  4079  * @access private
  4161  * @access private
  4080  *
  4162  *
  4081  * @param string       $message Error message.
  4163  * @param string       $message Error message.
  4082  * @param string       $title   Optional. Error title. Default empty.
  4164  * @param string       $title   Optional. Error title. Default empty string.
  4083  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  4165  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  4084  */
  4166  */
  4085 function _xml_wp_die_handler( $message, $title = '', $args = array() ) {
  4167 function _xml_wp_die_handler( $message, $title = '', $args = array() ) {
  4086 	list( $message, $title, $parsed_args ) = _wp_die_process_input( $message, $title, $args );
  4168 	list( $message, $title, $parsed_args ) = _wp_die_process_input( $message, $title, $args );
  4087 
  4169 
  4121  *
  4203  *
  4122  * @since 3.4.0
  4204  * @since 3.4.0
  4123  * @since 5.1.0 Added the $title and $args parameters.
  4205  * @since 5.1.0 Added the $title and $args parameters.
  4124  * @access private
  4206  * @access private
  4125  *
  4207  *
  4126  * @param string       $message Optional. Response to print. Default empty.
  4208  * @param string       $message Optional. Response to print. Default empty string.
  4127  * @param string       $title   Optional. Error title (unused). Default empty.
  4209  * @param string       $title   Optional. Error title (unused). Default empty string.
  4128  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  4210  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  4129  */
  4211  */
  4130 function _scalar_wp_die_handler( $message = '', $title = '', $args = array() ) {
  4212 function _scalar_wp_die_handler( $message = '', $title = '', $args = array() ) {
  4131 	list( $message, $title, $parsed_args ) = _wp_die_process_input( $message, $title, $args );
  4213 	list( $message, $title, $parsed_args ) = _wp_die_process_input( $message, $title, $args );
  4132 
  4214 
  4147  *
  4229  *
  4148  * @since 5.1.0
  4230  * @since 5.1.0
  4149  * @access private
  4231  * @access private
  4150  *
  4232  *
  4151  * @param string|WP_Error $message Error message or WP_Error object.
  4233  * @param string|WP_Error $message Error message or WP_Error object.
  4152  * @param string          $title   Optional. Error title. Default empty.
  4234  * @param string          $title   Optional. Error title. Default empty string.
  4153  * @param string|array    $args    Optional. Arguments to control behavior. Default empty array.
  4235  * @param string|array    $args    Optional. Arguments to control behavior. Default empty array.
  4154  * @return array {
  4236  * @return array {
  4155  *     Processed arguments.
  4237  *     Processed arguments.
  4156  *
  4238  *
  4157  *     @type string $0 Error message.
  4239  *     @type string $0 Error message.
  4195 				$args['response'] = $errors[0]['data']['status'];
  4277 				$args['response'] = $errors[0]['data']['status'];
  4196 			}
  4278 			}
  4197 			if ( empty( $title ) && is_array( $errors[0]['data'] ) && ! empty( $errors[0]['data']['title'] ) ) {
  4279 			if ( empty( $title ) && is_array( $errors[0]['data'] ) && ! empty( $errors[0]['data']['title'] ) ) {
  4198 				$title = $errors[0]['data']['title'];
  4280 				$title = $errors[0]['data']['title'];
  4199 			}
  4281 			}
       
  4282 			if ( WP_DEBUG_DISPLAY && is_array( $errors[0]['data'] ) && ! empty( $errors[0]['data']['error'] ) ) {
       
  4283 				$args['error_data'] = $errors[0]['data']['error'];
       
  4284 			}
  4200 
  4285 
  4201 			unset( $errors[0] );
  4286 			unset( $errors[0] );
  4202 			$args['additional_errors'] = array_values( $errors );
  4287 			$args['additional_errors'] = array_values( $errors );
  4203 		} else {
  4288 		} else {
  4204 			$message = '';
  4289 			$message = '';
  4230 
  4315 
  4231 	return array( $message, $title, $args );
  4316 	return array( $message, $title, $args );
  4232 }
  4317 }
  4233 
  4318 
  4234 /**
  4319 /**
  4235  * Encode a variable into JSON, with some sanity checks.
  4320  * Encodes a variable into JSON, with some confidence checks.
  4236  *
  4321  *
  4237  * @since 4.1.0
  4322  * @since 4.1.0
  4238  * @since 5.3.0 No longer handles support for PHP < 5.6.
  4323  * @since 5.3.0 No longer handles support for PHP < 5.6.
  4239  *
  4324  * @since 6.5.0 The `$data` parameter has been renamed to `$value` and
  4240  * @param mixed $data    Variable (usually an array or object) to encode as JSON.
  4325  *              the `$options` parameter to `$flags` for parity with PHP.
  4241  * @param int   $options Optional. Options to be passed to json_encode(). Default 0.
  4326  *
  4242  * @param int   $depth   Optional. Maximum depth to walk through $data. Must be
  4327  * @param mixed $value Variable (usually an array or object) to encode as JSON.
  4243  *                       greater than 0. Default 512.
  4328  * @param int   $flags Optional. Options to be passed to json_encode(). Default 0.
       
  4329  * @param int   $depth Optional. Maximum depth to walk through $value. Must be
       
  4330  *                     greater than 0. Default 512.
  4244  * @return string|false The JSON encoded string, or false if it cannot be encoded.
  4331  * @return string|false The JSON encoded string, or false if it cannot be encoded.
  4245  */
  4332  */
  4246 function wp_json_encode( $data, $options = 0, $depth = 512 ) {
  4333 function wp_json_encode( $value, $flags = 0, $depth = 512 ) {
  4247 	$json = json_encode( $data, $options, $depth );
  4334 	$json = json_encode( $value, $flags, $depth );
  4248 
  4335 
  4249 	// If json_encode() was successful, no need to do more sanity checking.
  4336 	// If json_encode() was successful, no need to do more confidence checking.
  4250 	if ( false !== $json ) {
  4337 	if ( false !== $json ) {
  4251 		return $json;
  4338 		return $json;
  4252 	}
  4339 	}
  4253 
  4340 
  4254 	try {
  4341 	try {
  4255 		$data = _wp_json_sanity_check( $data, $depth );
  4342 		$value = _wp_json_sanity_check( $value, $depth );
  4256 	} catch ( Exception $e ) {
  4343 	} catch ( Exception $e ) {
  4257 		return false;
  4344 		return false;
  4258 	}
  4345 	}
  4259 
  4346 
  4260 	return json_encode( $data, $options, $depth );
  4347 	return json_encode( $value, $flags, $depth );
  4261 }
  4348 }
  4262 
  4349 
  4263 /**
  4350 /**
  4264  * Perform sanity checks on data that shall be encoded to JSON.
  4351  * Performs confidence checks on data that shall be encoded to JSON.
  4265  *
  4352  *
  4266  * @ignore
  4353  * @ignore
  4267  * @since 4.1.0
  4354  * @since 4.1.0
  4268  * @access private
  4355  * @access private
  4269  *
  4356  *
  4270  * @see wp_json_encode()
  4357  * @see wp_json_encode()
  4271  *
  4358  *
  4272  * @throws Exception If depth limit is reached.
  4359  * @throws Exception If depth limit is reached.
  4273  *
  4360  *
  4274  * @param mixed $data  Variable (usually an array or object) to encode as JSON.
  4361  * @param mixed $value Variable (usually an array or object) to encode as JSON.
  4275  * @param int   $depth Maximum depth to walk through $data. Must be greater than 0.
  4362  * @param int   $depth Maximum depth to walk through $value. Must be greater than 0.
  4276  * @return mixed The sanitized data that shall be encoded to JSON.
  4363  * @return mixed The sanitized data that shall be encoded to JSON.
  4277  */
  4364  */
  4278 function _wp_json_sanity_check( $data, $depth ) {
  4365 function _wp_json_sanity_check( $value, $depth ) {
  4279 	if ( $depth < 0 ) {
  4366 	if ( $depth < 0 ) {
  4280 		throw new Exception( 'Reached depth limit' );
  4367 		throw new Exception( 'Reached depth limit' );
  4281 	}
  4368 	}
  4282 
  4369 
  4283 	if ( is_array( $data ) ) {
  4370 	if ( is_array( $value ) ) {
  4284 		$output = array();
  4371 		$output = array();
  4285 		foreach ( $data as $id => $el ) {
  4372 		foreach ( $value as $id => $el ) {
  4286 			// Don't forget to sanitize the ID!
  4373 			// Don't forget to sanitize the ID!
  4287 			if ( is_string( $id ) ) {
  4374 			if ( is_string( $id ) ) {
  4288 				$clean_id = _wp_json_convert_string( $id );
  4375 				$clean_id = _wp_json_convert_string( $id );
  4289 			} else {
  4376 			} else {
  4290 				$clean_id = $id;
  4377 				$clean_id = $id;
  4297 				$output[ $clean_id ] = _wp_json_convert_string( $el );
  4384 				$output[ $clean_id ] = _wp_json_convert_string( $el );
  4298 			} else {
  4385 			} else {
  4299 				$output[ $clean_id ] = $el;
  4386 				$output[ $clean_id ] = $el;
  4300 			}
  4387 			}
  4301 		}
  4388 		}
  4302 	} elseif ( is_object( $data ) ) {
  4389 	} elseif ( is_object( $value ) ) {
  4303 		$output = new stdClass;
  4390 		$output = new stdClass();
  4304 		foreach ( $data as $id => $el ) {
  4391 		foreach ( $value as $id => $el ) {
  4305 			if ( is_string( $id ) ) {
  4392 			if ( is_string( $id ) ) {
  4306 				$clean_id = _wp_json_convert_string( $id );
  4393 				$clean_id = _wp_json_convert_string( $id );
  4307 			} else {
  4394 			} else {
  4308 				$clean_id = $id;
  4395 				$clean_id = $id;
  4309 			}
  4396 			}
  4314 				$output->$clean_id = _wp_json_convert_string( $el );
  4401 				$output->$clean_id = _wp_json_convert_string( $el );
  4315 			} else {
  4402 			} else {
  4316 				$output->$clean_id = $el;
  4403 				$output->$clean_id = $el;
  4317 			}
  4404 			}
  4318 		}
  4405 		}
  4319 	} elseif ( is_string( $data ) ) {
  4406 	} elseif ( is_string( $value ) ) {
  4320 		return _wp_json_convert_string( $data );
  4407 		return _wp_json_convert_string( $value );
  4321 	} else {
  4408 	} else {
  4322 		return $data;
  4409 		return $value;
  4323 	}
  4410 	}
  4324 
  4411 
  4325 	return $output;
  4412 	return $output;
  4326 }
  4413 }
  4327 
  4414 
  4328 /**
  4415 /**
  4329  * Convert a string to UTF-8, so that it can be safely encoded to JSON.
  4416  * Converts a string to UTF-8, so that it can be safely encoded to JSON.
  4330  *
  4417  *
  4331  * @ignore
  4418  * @ignore
  4332  * @since 4.1.0
  4419  * @since 4.1.0
  4333  * @access private
  4420  * @access private
  4334  *
  4421  *
  4335  * @see _wp_json_sanity_check()
  4422  * @see _wp_json_sanity_check()
  4336  *
  4423  *
  4337  * @param string $string The string which is to be converted.
  4424  * @param string $input_string The string which is to be converted.
  4338  * @return string The checked string.
  4425  * @return string The checked string.
  4339  */
  4426  */
  4340 function _wp_json_convert_string( $string ) {
  4427 function _wp_json_convert_string( $input_string ) {
  4341 	static $use_mb = null;
  4428 	static $use_mb = null;
  4342 	if ( is_null( $use_mb ) ) {
  4429 	if ( is_null( $use_mb ) ) {
  4343 		$use_mb = function_exists( 'mb_convert_encoding' );
  4430 		$use_mb = function_exists( 'mb_convert_encoding' );
  4344 	}
  4431 	}
  4345 
  4432 
  4346 	if ( $use_mb ) {
  4433 	if ( $use_mb ) {
  4347 		$encoding = mb_detect_encoding( $string, mb_detect_order(), true );
  4434 		$encoding = mb_detect_encoding( $input_string, mb_detect_order(), true );
  4348 		if ( $encoding ) {
  4435 		if ( $encoding ) {
  4349 			return mb_convert_encoding( $string, 'UTF-8', $encoding );
  4436 			return mb_convert_encoding( $input_string, 'UTF-8', $encoding );
  4350 		} else {
  4437 		} else {
  4351 			return mb_convert_encoding( $string, 'UTF-8', 'UTF-8' );
  4438 			return mb_convert_encoding( $input_string, 'UTF-8', 'UTF-8' );
  4352 		}
  4439 		}
  4353 	} else {
  4440 	} else {
  4354 		return wp_check_invalid_utf8( $string, true );
  4441 		return wp_check_invalid_utf8( $input_string, true );
  4355 	}
  4442 	}
  4356 }
  4443 }
  4357 
  4444 
  4358 /**
  4445 /**
  4359  * Prepares response data to be serialized to JSON.
  4446  * Prepares response data to be serialized to JSON.
  4364  * @since 4.4.0
  4451  * @since 4.4.0
  4365  * @deprecated 5.3.0 This function is no longer needed as support for PHP 5.2-5.3
  4452  * @deprecated 5.3.0 This function is no longer needed as support for PHP 5.2-5.3
  4366  *                   has been dropped.
  4453  *                   has been dropped.
  4367  * @access private
  4454  * @access private
  4368  *
  4455  *
  4369  * @param mixed $data Native representation.
  4456  * @param mixed $value Native representation.
  4370  * @return bool|int|float|null|string|array Data ready for `json_encode()`.
  4457  * @return bool|int|float|null|string|array Data ready for `json_encode()`.
  4371  */
  4458  */
  4372 function _wp_json_prepare_data( $data ) {
  4459 function _wp_json_prepare_data( $value ) {
  4373 	_deprecated_function( __FUNCTION__, '5.3.0' );
  4460 	_deprecated_function( __FUNCTION__, '5.3.0' );
  4374 	return $data;
  4461 	return $value;
  4375 }
  4462 }
  4376 
  4463 
  4377 /**
  4464 /**
  4378  * Send a JSON response back to an Ajax request.
  4465  * Sends a JSON response back to an Ajax request.
  4379  *
  4466  *
  4380  * @since 3.5.0
  4467  * @since 3.5.0
  4381  * @since 4.7.0 The `$status_code` parameter was added.
  4468  * @since 4.7.0 The `$status_code` parameter was added.
  4382  * @since 5.6.0 The `$options` parameter was added.
  4469  * @since 5.6.0 The `$flags` parameter was added.
  4383  *
  4470  *
  4384  * @param mixed $response    Variable (usually an array or object) to encode as JSON,
  4471  * @param mixed $response    Variable (usually an array or object) to encode as JSON,
  4385  *                           then print and die.
  4472  *                           then print and die.
  4386  * @param int   $status_code Optional. The HTTP status code to output. Default null.
  4473  * @param int   $status_code Optional. The HTTP status code to output. Default null.
  4387  * @param int   $options     Optional. Options to be passed to json_encode(). Default 0.
  4474  * @param int   $flags       Optional. Options to be passed to json_encode(). Default 0.
  4388  */
  4475  */
  4389 function wp_send_json( $response, $status_code = null, $options = 0 ) {
  4476 function wp_send_json( $response, $status_code = null, $flags = 0 ) {
  4390 	if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
  4477 	if ( wp_is_serving_rest_request() ) {
  4391 		_doing_it_wrong(
  4478 		_doing_it_wrong(
  4392 			__FUNCTION__,
  4479 			__FUNCTION__,
  4393 			sprintf(
  4480 			sprintf(
  4394 				/* translators: 1: WP_REST_Response, 2: WP_Error */
  4481 				/* translators: 1: WP_REST_Response, 2: WP_Error */
  4395 				__( 'Return a %1$s or %2$s object from your callback when using the REST API.' ),
  4482 				__( 'Return a %1$s or %2$s object from your callback when using the REST API.' ),
  4405 		if ( null !== $status_code ) {
  4492 		if ( null !== $status_code ) {
  4406 			status_header( $status_code );
  4493 			status_header( $status_code );
  4407 		}
  4494 		}
  4408 	}
  4495 	}
  4409 
  4496 
  4410 	echo wp_json_encode( $response, $options );
  4497 	echo wp_json_encode( $response, $flags );
  4411 
  4498 
  4412 	if ( wp_doing_ajax() ) {
  4499 	if ( wp_doing_ajax() ) {
  4413 		wp_die(
  4500 		wp_die(
  4414 			'',
  4501 			'',
  4415 			'',
  4502 			'',
  4421 		die;
  4508 		die;
  4422 	}
  4509 	}
  4423 }
  4510 }
  4424 
  4511 
  4425 /**
  4512 /**
  4426  * Send a JSON response back to an Ajax request, indicating success.
  4513  * Sends a JSON response back to an Ajax request, indicating success.
  4427  *
  4514  *
  4428  * @since 3.5.0
  4515  * @since 3.5.0
  4429  * @since 4.7.0 The `$status_code` parameter was added.
  4516  * @since 4.7.0 The `$status_code` parameter was added.
  4430  * @since 5.6.0 The `$options` parameter was added.
  4517  * @since 5.6.0 The `$flags` parameter was added.
  4431  *
  4518  *
  4432  * @param mixed $data        Optional. Data to encode as JSON, then print and die. Default null.
  4519  * @param mixed $value       Optional. Data to encode as JSON, then print and die. Default null.
  4433  * @param int   $status_code Optional. The HTTP status code to output. Default null.
  4520  * @param int   $status_code Optional. The HTTP status code to output. Default null.
  4434  * @param int   $options     Optional. Options to be passed to json_encode(). Default 0.
  4521  * @param int   $flags       Optional. Options to be passed to json_encode(). Default 0.
  4435  */
  4522  */
  4436 function wp_send_json_success( $data = null, $status_code = null, $options = 0 ) {
  4523 function wp_send_json_success( $value = null, $status_code = null, $flags = 0 ) {
  4437 	$response = array( 'success' => true );
  4524 	$response = array( 'success' => true );
  4438 
  4525 
  4439 	if ( isset( $data ) ) {
  4526 	if ( isset( $value ) ) {
  4440 		$response['data'] = $data;
  4527 		$response['data'] = $value;
  4441 	}
  4528 	}
  4442 
  4529 
  4443 	wp_send_json( $response, $status_code, $options );
  4530 	wp_send_json( $response, $status_code, $flags );
  4444 }
  4531 }
  4445 
  4532 
  4446 /**
  4533 /**
  4447  * Send a JSON response back to an Ajax request, indicating failure.
  4534  * Sends a JSON response back to an Ajax request, indicating failure.
  4448  *
  4535  *
  4449  * If the `$data` parameter is a WP_Error object, the errors
  4536  * If the `$value` parameter is a WP_Error object, the errors
  4450  * within the object are processed and output as an array of error
  4537  * within the object are processed and output as an array of error
  4451  * codes and corresponding messages. All other types are output
  4538  * codes and corresponding messages. All other types are output
  4452  * without further processing.
  4539  * without further processing.
  4453  *
  4540  *
  4454  * @since 3.5.0
  4541  * @since 3.5.0
  4455  * @since 4.1.0 The `$data` parameter is now processed if a WP_Error object is passed in.
  4542  * @since 4.1.0 The `$value` parameter is now processed if a WP_Error object is passed in.
  4456  * @since 4.7.0 The `$status_code` parameter was added.
  4543  * @since 4.7.0 The `$status_code` parameter was added.
  4457  * @since 5.6.0 The `$options` parameter was added.
  4544  * @since 5.6.0 The `$flags` parameter was added.
  4458  *
  4545  *
  4459  * @param mixed $data        Optional. Data to encode as JSON, then print and die. Default null.
  4546  * @param mixed $value       Optional. Data to encode as JSON, then print and die. Default null.
  4460  * @param int   $status_code Optional. The HTTP status code to output. Default null.
  4547  * @param int   $status_code Optional. The HTTP status code to output. Default null.
  4461  * @param int   $options     Optional. Options to be passed to json_encode(). Default 0.
  4548  * @param int   $flags       Optional. Options to be passed to json_encode(). Default 0.
  4462  */
  4549  */
  4463 function wp_send_json_error( $data = null, $status_code = null, $options = 0 ) {
  4550 function wp_send_json_error( $value = null, $status_code = null, $flags = 0 ) {
  4464 	$response = array( 'success' => false );
  4551 	$response = array( 'success' => false );
  4465 
  4552 
  4466 	if ( isset( $data ) ) {
  4553 	if ( isset( $value ) ) {
  4467 		if ( is_wp_error( $data ) ) {
  4554 		if ( is_wp_error( $value ) ) {
  4468 			$result = array();
  4555 			$result = array();
  4469 			foreach ( $data->errors as $code => $messages ) {
  4556 			foreach ( $value->errors as $code => $messages ) {
  4470 				foreach ( $messages as $message ) {
  4557 				foreach ( $messages as $message ) {
  4471 					$result[] = array(
  4558 					$result[] = array(
  4472 						'code'    => $code,
  4559 						'code'    => $code,
  4473 						'message' => $message,
  4560 						'message' => $message,
  4474 					);
  4561 					);
  4475 				}
  4562 				}
  4476 			}
  4563 			}
  4477 
  4564 
  4478 			$response['data'] = $result;
  4565 			$response['data'] = $result;
  4479 		} else {
  4566 		} else {
  4480 			$response['data'] = $data;
  4567 			$response['data'] = $value;
  4481 		}
  4568 		}
  4482 	}
  4569 	}
  4483 
  4570 
  4484 	wp_send_json( $response, $status_code, $options );
  4571 	wp_send_json( $response, $status_code, $flags );
  4485 }
  4572 }
  4486 
  4573 
  4487 /**
  4574 /**
  4488  * Checks that a JSONP callback is a valid JavaScript callback name.
  4575  * Checks that a JSONP callback is a valid JavaScript callback name.
  4489  *
  4576  *
  4514  * @param string $filename Path to the JSON file.
  4601  * @param string $filename Path to the JSON file.
  4515  * @param array  $options  {
  4602  * @param array  $options  {
  4516  *     Optional. Options to be used with `json_decode()`.
  4603  *     Optional. Options to be used with `json_decode()`.
  4517  *
  4604  *
  4518  *     @type bool $associative Optional. When `true`, JSON objects will be returned as associative arrays.
  4605  *     @type bool $associative Optional. When `true`, JSON objects will be returned as associative arrays.
  4519  *                             When `false`, JSON objects will be returned as objects.
  4606  *                             When `false`, JSON objects will be returned as objects. Default false.
  4520  * }
  4607  * }
  4521  *
  4608  *
  4522  * @return mixed Returns the value encoded in JSON in appropriate PHP type.
  4609  * @return mixed Returns the value encoded in JSON in appropriate PHP type.
  4523  *               `null` is returned if the file is not found, or its content can't be decoded.
  4610  *               `null` is returned if the file is not found, or its content can't be decoded.
  4524  */
  4611  */
  4525 function wp_json_file_decode( $filename, $options = array() ) {
  4612 function wp_json_file_decode( $filename, $options = array() ) {
  4526 	$result   = null;
  4613 	$result   = null;
  4527 	$filename = wp_normalize_path( realpath( $filename ) );
  4614 	$filename = wp_normalize_path( realpath( $filename ) );
  4528 	if ( ! file_exists( $filename ) ) {
  4615 
  4529 		trigger_error(
  4616 	if ( ! $filename ) {
       
  4617 		wp_trigger_error(
       
  4618 			__FUNCTION__,
  4530 			sprintf(
  4619 			sprintf(
  4531 				/* translators: %s: Path to the JSON file. */
  4620 				/* translators: %s: Path to the JSON file. */
  4532 				__( "File %s doesn't exist!" ),
  4621 				__( "File %s doesn't exist!" ),
  4533 				$filename
  4622 				$filename
  4534 			)
  4623 			)
  4538 
  4627 
  4539 	$options      = wp_parse_args( $options, array( 'associative' => false ) );
  4628 	$options      = wp_parse_args( $options, array( 'associative' => false ) );
  4540 	$decoded_file = json_decode( file_get_contents( $filename ), $options['associative'] );
  4629 	$decoded_file = json_decode( file_get_contents( $filename ), $options['associative'] );
  4541 
  4630 
  4542 	if ( JSON_ERROR_NONE !== json_last_error() ) {
  4631 	if ( JSON_ERROR_NONE !== json_last_error() ) {
  4543 		trigger_error(
  4632 		wp_trigger_error(
       
  4633 			__FUNCTION__,
  4544 			sprintf(
  4634 			sprintf(
  4545 				/* translators: 1: Path to the JSON file, 2: Error message. */
  4635 				/* translators: 1: Path to the JSON file, 2: Error message. */
  4546 				__( 'Error when decoding a JSON file at path %1$s: %2$s' ),
  4636 				__( 'Error when decoding a JSON file at path %1$s: %2$s' ),
  4547 				$filename,
  4637 				$filename,
  4548 				json_last_error_msg()
  4638 				json_last_error_msg()
  4553 
  4643 
  4554 	return $decoded_file;
  4644 	return $decoded_file;
  4555 }
  4645 }
  4556 
  4646 
  4557 /**
  4647 /**
  4558  * Retrieve the WordPress home page URL.
  4648  * Retrieves the WordPress home page URL.
  4559  *
  4649  *
  4560  * If the constant named 'WP_HOME' exists, then it will be used and returned
  4650  * If the constant named 'WP_HOME' exists, then it will be used and returned
  4561  * by the function. This can be used to counter the redirection on your local
  4651  * by the function. This can be used to counter the redirection on your local
  4562  * development environment.
  4652  * development environment.
  4563  *
  4653  *
  4575 	}
  4665 	}
  4576 	return $url;
  4666 	return $url;
  4577 }
  4667 }
  4578 
  4668 
  4579 /**
  4669 /**
  4580  * Retrieve the WordPress site URL.
  4670  * Retrieves the WordPress site URL.
  4581  *
  4671  *
  4582  * If the constant named 'WP_SITEURL' is defined, then the value in that
  4672  * If the constant named 'WP_SITEURL' is defined, then the value in that
  4583  * constant will always be returned. This can be used for debugging a site
  4673  * constant will always be returned. This can be used for debugging a site
  4584  * on your localhost while not having to change the database to your URL.
  4674  * on your localhost while not having to change the database to your URL.
  4585  *
  4675  *
  4597 	}
  4687 	}
  4598 	return $url;
  4688 	return $url;
  4599 }
  4689 }
  4600 
  4690 
  4601 /**
  4691 /**
  4602  * Delete the fresh site option.
  4692  * Deletes the fresh site option.
  4603  *
  4693  *
  4604  * @since 4.7.0
  4694  * @since 4.7.0
  4605  * @access private
  4695  * @access private
  4606  */
  4696  */
  4607 function _delete_option_fresh_site() {
  4697 function _delete_option_fresh_site() {
  4608 	update_option( 'fresh_site', '0' );
  4698 	update_option( 'fresh_site', '0' );
  4609 }
  4699 }
  4610 
  4700 
  4611 /**
  4701 /**
  4612  * Set the localized direction for MCE plugin.
  4702  * Sets the localized direction for MCE plugin.
  4613  *
  4703  *
  4614  * Will only set the direction to 'rtl', if the WordPress locale has
  4704  * Will only set the direction to 'rtl', if the WordPress locale has
  4615  * the text direction set to 'rtl'.
  4705  * the text direction set to 'rtl'.
  4616  *
  4706  *
  4617  * Fills in the 'directionality' setting, enables the 'directionality'
  4707  * Fills in the 'directionality' setting, enables the 'directionality'
  4628 function _mce_set_direction( $mce_init ) {
  4718 function _mce_set_direction( $mce_init ) {
  4629 	if ( is_rtl() ) {
  4719 	if ( is_rtl() ) {
  4630 		$mce_init['directionality'] = 'rtl';
  4720 		$mce_init['directionality'] = 'rtl';
  4631 		$mce_init['rtl_ui']         = true;
  4721 		$mce_init['rtl_ui']         = true;
  4632 
  4722 
  4633 		if ( ! empty( $mce_init['plugins'] ) && strpos( $mce_init['plugins'], 'directionality' ) === false ) {
  4723 		if ( ! empty( $mce_init['plugins'] ) && ! str_contains( $mce_init['plugins'], 'directionality' ) ) {
  4634 			$mce_init['plugins'] .= ',directionality';
  4724 			$mce_init['plugins'] .= ',directionality';
  4635 		}
  4725 		}
  4636 
  4726 
  4637 		if ( ! empty( $mce_init['toolbar1'] ) && ! preg_match( '/\bltr\b/', $mce_init['toolbar1'] ) ) {
  4727 		if ( ! empty( $mce_init['toolbar1'] ) && ! preg_match( '/\bltr\b/', $mce_init['toolbar1'] ) ) {
  4638 			$mce_init['toolbar1'] .= ',ltr';
  4728 			$mce_init['toolbar1'] .= ',ltr';
  4640 	}
  4730 	}
  4641 
  4731 
  4642 	return $mce_init;
  4732 	return $mce_init;
  4643 }
  4733 }
  4644 
  4734 
  4645 
  4735 /**
  4646 /**
  4736  * Determines whether WordPress is currently serving a REST API request.
  4647  * Convert smiley code to the icon graphic file equivalent.
  4737  *
       
  4738  * The function relies on the 'REST_REQUEST' global. As such, it only returns true when an actual REST _request_ is
       
  4739  * being made. It does not return true when a REST endpoint is hit as part of another request, e.g. for preloading a
       
  4740  * REST response. See {@see wp_is_rest_endpoint()} for that purpose.
       
  4741  *
       
  4742  * This function should not be called until the {@see 'parse_request'} action, as the constant is only defined then,
       
  4743  * even for an actual REST request.
       
  4744  *
       
  4745  * @since 6.5.0
       
  4746  *
       
  4747  * @return bool True if it's a WordPress REST API request, false otherwise.
       
  4748  */
       
  4749 function wp_is_serving_rest_request() {
       
  4750 	return defined( 'REST_REQUEST' ) && REST_REQUEST;
       
  4751 }
       
  4752 
       
  4753 /**
       
  4754  * Converts smiley code to the icon graphic file equivalent.
  4648  *
  4755  *
  4649  * You can turn off smilies, by going to the write setting screen and unchecking
  4756  * You can turn off smilies, by going to the write setting screen and unchecking
  4650  * the box, or by setting 'use_smilies' option to false or removing the option.
  4757  * the box, or by setting 'use_smilies' option to false or removing the option.
  4651  *
  4758  *
  4652  * Plugins may override the default smiley list by setting the $wpsmiliestrans
  4759  * Plugins may override the default smiley list by setting the $wpsmiliestrans
  4658  *
  4765  *
  4659  * The full list of smilies can be found in the function and won't be listed in
  4766  * The full list of smilies can be found in the function and won't be listed in
  4660  * the description. Probably should create a Codex page for it, so that it is
  4767  * the description. Probably should create a Codex page for it, so that it is
  4661  * available.
  4768  * available.
  4662  *
  4769  *
       
  4770  * @since 2.2.0
       
  4771  *
  4663  * @global array $wpsmiliestrans
  4772  * @global array $wpsmiliestrans
  4664  * @global array $wp_smiliessearch
  4773  * @global array $wp_smiliessearch
  4665  *
       
  4666  * @since 2.2.0
       
  4667  */
  4774  */
  4668 function smilies_init() {
  4775 function smilies_init() {
  4669 	global $wpsmiliestrans, $wp_smiliessearch;
  4776 	global $wpsmiliestrans, $wp_smiliessearch;
  4670 
  4777 
  4671 	// Don't bother setting up smilies if they are disabled.
  4778 	// Don't bother setting up smilies if they are disabled.
  4733 	 *
  4840 	 *
  4734 	 * @param string[] $wpsmiliestrans List of the smilies' hexadecimal representations, keyed by their smily code.
  4841 	 * @param string[] $wpsmiliestrans List of the smilies' hexadecimal representations, keyed by their smily code.
  4735 	 */
  4842 	 */
  4736 	$wpsmiliestrans = apply_filters( 'smilies', $wpsmiliestrans );
  4843 	$wpsmiliestrans = apply_filters( 'smilies', $wpsmiliestrans );
  4737 
  4844 
  4738 	if ( count( $wpsmiliestrans ) == 0 ) {
  4845 	if ( count( $wpsmiliestrans ) === 0 ) {
  4739 		return;
  4846 		return;
  4740 	}
  4847 	}
  4741 
  4848 
  4742 	/*
  4849 	/*
  4743 	 * NOTE: we sort the smilies in reverse key order. This is to make sure
  4850 	 * NOTE: we sort the smilies in reverse key order. This is to make sure
  4755 	foreach ( (array) $wpsmiliestrans as $smiley => $img ) {
  4862 	foreach ( (array) $wpsmiliestrans as $smiley => $img ) {
  4756 		$firstchar = substr( $smiley, 0, 1 );
  4863 		$firstchar = substr( $smiley, 0, 1 );
  4757 		$rest      = substr( $smiley, 1 );
  4864 		$rest      = substr( $smiley, 1 );
  4758 
  4865 
  4759 		// New subpattern?
  4866 		// New subpattern?
  4760 		if ( $firstchar != $subchar ) {
  4867 		if ( $firstchar !== $subchar ) {
  4761 			if ( '' !== $subchar ) {
  4868 			if ( '' !== $subchar ) {
  4762 				$wp_smiliessearch .= ')(?=' . $spaces . '|$)';  // End previous "subpattern".
  4869 				$wp_smiliessearch .= ')(?=' . $spaces . '|$)';  // End previous "subpattern".
  4763 				$wp_smiliessearch .= '|(?<=' . $spaces . '|^)'; // Begin another "subpattern".
  4870 				$wp_smiliessearch .= '|(?<=' . $spaces . '|^)'; // Begin another "subpattern".
  4764 			}
  4871 			}
       
  4872 
  4765 			$subchar           = $firstchar;
  4873 			$subchar           = $firstchar;
  4766 			$wp_smiliessearch .= preg_quote( $firstchar, '/' ) . '(?:';
  4874 			$wp_smiliessearch .= preg_quote( $firstchar, '/' ) . '(?:';
  4767 		} else {
  4875 		} else {
  4768 			$wp_smiliessearch .= '|';
  4876 			$wp_smiliessearch .= '|';
  4769 		}
  4877 		}
       
  4878 
  4770 		$wp_smiliessearch .= preg_quote( $rest, '/' );
  4879 		$wp_smiliessearch .= preg_quote( $rest, '/' );
  4771 	}
  4880 	}
  4772 
  4881 
  4773 	$wp_smiliessearch .= ')(?=' . $spaces . '|$)/m';
  4882 	$wp_smiliessearch .= ')(?=' . $spaces . '|$)/m';
  4774 
       
  4775 }
  4883 }
  4776 
  4884 
  4777 /**
  4885 /**
  4778  * Merges user defined arguments into defaults array.
  4886  * Merges user defined arguments into defaults array.
  4779  *
  4887  *
  4806 /**
  4914 /**
  4807  * Converts a comma- or space-separated list of scalar values to an array.
  4915  * Converts a comma- or space-separated list of scalar values to an array.
  4808  *
  4916  *
  4809  * @since 5.1.0
  4917  * @since 5.1.0
  4810  *
  4918  *
  4811  * @param array|string $list List of values.
  4919  * @param array|string $input_list List of values.
  4812  * @return array Array of values.
  4920  * @return array Array of values.
  4813  */
  4921  */
  4814 function wp_parse_list( $list ) {
  4922 function wp_parse_list( $input_list ) {
  4815 	if ( ! is_array( $list ) ) {
  4923 	if ( ! is_array( $input_list ) ) {
  4816 		return preg_split( '/[\s,]+/', $list, -1, PREG_SPLIT_NO_EMPTY );
  4924 		return preg_split( '/[\s,]+/', $input_list, -1, PREG_SPLIT_NO_EMPTY );
  4817 	}
  4925 	}
  4818 
  4926 
  4819 	return $list;
  4927 	// Validate all entries of the list are scalar.
       
  4928 	$input_list = array_filter( $input_list, 'is_scalar' );
       
  4929 
       
  4930 	return $input_list;
  4820 }
  4931 }
  4821 
  4932 
  4822 /**
  4933 /**
  4823  * Cleans up an array, comma- or space-separated list of IDs.
  4934  * Cleans up an array, comma- or space-separated list of IDs.
  4824  *
  4935  *
  4825  * @since 3.0.0
  4936  * @since 3.0.0
  4826  * @since 5.1.0 Refactored to use wp_parse_list().
  4937  * @since 5.1.0 Refactored to use wp_parse_list().
  4827  *
  4938  *
  4828  * @param array|string $list List of IDs.
  4939  * @param array|string $input_list List of IDs.
  4829  * @return int[] Sanitized array of IDs.
  4940  * @return int[] Sanitized array of IDs.
  4830  */
  4941  */
  4831 function wp_parse_id_list( $list ) {
  4942 function wp_parse_id_list( $input_list ) {
  4832 	$list = wp_parse_list( $list );
  4943 	$input_list = wp_parse_list( $input_list );
  4833 
  4944 
  4834 	return array_unique( array_map( 'absint', $list ) );
  4945 	return array_unique( array_map( 'absint', $input_list ) );
  4835 }
  4946 }
  4836 
  4947 
  4837 /**
  4948 /**
  4838  * Cleans up an array, comma- or space-separated list of slugs.
  4949  * Cleans up an array, comma- or space-separated list of slugs.
  4839  *
  4950  *
  4840  * @since 4.7.0
  4951  * @since 4.7.0
  4841  * @since 5.1.0 Refactored to use wp_parse_list().
  4952  * @since 5.1.0 Refactored to use wp_parse_list().
  4842  *
  4953  *
  4843  * @param array|string $list List of slugs.
  4954  * @param array|string $input_list List of slugs.
  4844  * @return string[] Sanitized array of slugs.
  4955  * @return string[] Sanitized array of slugs.
  4845  */
  4956  */
  4846 function wp_parse_slug_list( $list ) {
  4957 function wp_parse_slug_list( $input_list ) {
  4847 	$list = wp_parse_list( $list );
  4958 	$input_list = wp_parse_list( $input_list );
  4848 
  4959 
  4849 	return array_unique( array_map( 'sanitize_title', $list ) );
  4960 	return array_unique( array_map( 'sanitize_title', $input_list ) );
  4850 }
  4961 }
  4851 
  4962 
  4852 /**
  4963 /**
  4853  * Extract a slice of an array, given a list of keys.
  4964  * Extracts a slice of an array, given a list of keys.
  4854  *
  4965  *
  4855  * @since 3.1.0
  4966  * @since 3.1.0
  4856  *
  4967  *
  4857  * @param array $array The original array.
  4968  * @param array $input_array The original array.
  4858  * @param array $keys  The list of keys.
  4969  * @param array $keys        The list of keys.
  4859  * @return array The array slice.
  4970  * @return array The array slice.
  4860  */
  4971  */
  4861 function wp_array_slice_assoc( $array, $keys ) {
  4972 function wp_array_slice_assoc( $input_array, $keys ) {
  4862 	$slice = array();
  4973 	$slice = array();
  4863 
  4974 
  4864 	foreach ( $keys as $key ) {
  4975 	foreach ( $keys as $key ) {
  4865 		if ( isset( $array[ $key ] ) ) {
  4976 		if ( isset( $input_array[ $key ] ) ) {
  4866 			$slice[ $key ] = $array[ $key ];
  4977 			$slice[ $key ] = $input_array[ $key ];
  4867 		}
  4978 		}
  4868 	}
  4979 	}
  4869 
  4980 
  4870 	return $slice;
  4981 	return $slice;
       
  4982 }
       
  4983 
       
  4984 /**
       
  4985  * Sorts the keys of an array alphabetically.
       
  4986  *
       
  4987  * The array is passed by reference so it doesn't get returned
       
  4988  * which mimics the behavior of `ksort()`.
       
  4989  *
       
  4990  * @since 6.0.0
       
  4991  *
       
  4992  * @param array $input_array The array to sort, passed by reference.
       
  4993  */
       
  4994 function wp_recursive_ksort( &$input_array ) {
       
  4995 	foreach ( $input_array as &$value ) {
       
  4996 		if ( is_array( $value ) ) {
       
  4997 			wp_recursive_ksort( $value );
       
  4998 		}
       
  4999 	}
       
  5000 
       
  5001 	ksort( $input_array );
  4871 }
  5002 }
  4872 
  5003 
  4873 /**
  5004 /**
  4874  * Accesses an array in depth based on a path of keys.
  5005  * Accesses an array in depth based on a path of keys.
  4875  *
  5006  *
  4876  * It is the PHP equivalent of JavaScript's `lodash.get()` and mirroring it may help other components
  5007  * It is the PHP equivalent of JavaScript's `lodash.get()` and mirroring it may help other components
  4877  * retain some symmetry between client and server implementations.
  5008  * retain some symmetry between client and server implementations.
  4878  *
  5009  *
  4879  * Example usage:
  5010  * Example usage:
  4880  *
  5011  *
  4881  *     $array = array(
  5012  *     $input_array = array(
  4882  *         'a' => array(
  5013  *         'a' => array(
  4883  *             'b' => array(
  5014  *             'b' => array(
  4884  *                 'c' => 1,
  5015  *                 'c' => 1,
  4885  *             ),
  5016  *             ),
  4886  *         ),
  5017  *         ),
  4887  *     );
  5018  *     );
  4888  *     _wp_array_get( $array, array( 'a', 'b', 'c' ) );
  5019  *     _wp_array_get( $input_array, array( 'a', 'b', 'c' ) );
  4889  *
  5020  *
  4890  * @internal
  5021  * @internal
  4891  *
  5022  *
  4892  * @since 5.6.0
  5023  * @since 5.6.0
  4893  * @access private
  5024  * @access private
  4894  *
  5025  *
  4895  * @param array $array   An array from which we want to retrieve some information.
  5026  * @param array $input_array   An array from which we want to retrieve some information.
  4896  * @param array $path    An array of keys describing the path with which to retrieve information.
  5027  * @param array $path          An array of keys describing the path with which to retrieve information.
  4897  * @param mixed $default The return value if the path does not exist within the array,
  5028  * @param mixed $default_value Optional. The return value if the path does not exist within the array,
  4898  *                       or if `$array` or `$path` are not arrays.
  5029  *                             or if `$input_array` or `$path` are not arrays. Default null.
  4899  * @return mixed The value from the path specified.
  5030  * @return mixed The value from the path specified.
  4900  */
  5031  */
  4901 function _wp_array_get( $array, $path, $default = null ) {
  5032 function _wp_array_get( $input_array, $path, $default_value = null ) {
  4902 	// Confirm $path is valid.
  5033 	// Confirm $path is valid.
  4903 	if ( ! is_array( $path ) || 0 === count( $path ) ) {
  5034 	if ( ! is_array( $path ) || 0 === count( $path ) ) {
  4904 		return $default;
  5035 		return $default_value;
  4905 	}
  5036 	}
  4906 
  5037 
  4907 	foreach ( $path as $path_element ) {
  5038 	foreach ( $path as $path_element ) {
  4908 		if (
  5039 		if ( ! is_array( $input_array ) ) {
  4909 			! is_array( $array ) ||
  5040 			return $default_value;
  4910 			( ! is_string( $path_element ) && ! is_integer( $path_element ) && ! is_null( $path_element ) ) ||
  5041 		}
  4911 			! array_key_exists( $path_element, $array )
  5042 
       
  5043 		if ( is_string( $path_element )
       
  5044 			|| is_integer( $path_element )
       
  5045 			|| null === $path_element
  4912 		) {
  5046 		) {
  4913 			return $default;
  5047 			/*
  4914 		}
  5048 			 * Check if the path element exists in the input array.
  4915 		$array = $array[ $path_element ];
  5049 			 * We check with `isset()` first, as it is a lot faster
  4916 	}
  5050 			 * than `array_key_exists()`.
  4917 
  5051 			 */
  4918 	return $array;
  5052 			if ( isset( $input_array[ $path_element ] ) ) {
       
  5053 				$input_array = $input_array[ $path_element ];
       
  5054 				continue;
       
  5055 			}
       
  5056 
       
  5057 			/*
       
  5058 			 * If `isset()` returns false, we check with `array_key_exists()`,
       
  5059 			 * which also checks for `null` values.
       
  5060 			 */
       
  5061 			if ( array_key_exists( $path_element, $input_array ) ) {
       
  5062 				$input_array = $input_array[ $path_element ];
       
  5063 				continue;
       
  5064 			}
       
  5065 		}
       
  5066 
       
  5067 		return $default_value;
       
  5068 	}
       
  5069 
       
  5070 	return $input_array;
  4919 }
  5071 }
  4920 
  5072 
  4921 /**
  5073 /**
  4922  * Sets an array in depth based on a path of keys.
  5074  * Sets an array in depth based on a path of keys.
  4923  *
  5075  *
  4924  * It is the PHP equivalent of JavaScript's `lodash.set()` and mirroring it may help other components
  5076  * It is the PHP equivalent of JavaScript's `lodash.set()` and mirroring it may help other components
  4925  * retain some symmetry between client and server implementations.
  5077  * retain some symmetry between client and server implementations.
  4926  *
  5078  *
  4927  * Example usage:
  5079  * Example usage:
  4928  *
  5080  *
  4929  *     $array = array();
  5081  *     $input_array = array();
  4930  *     _wp_array_set( $array, array( 'a', 'b', 'c', 1 ) );
  5082  *     _wp_array_set( $input_array, array( 'a', 'b', 'c', 1 ) );
  4931  *
  5083  *
  4932  *     $array becomes:
  5084  *     $input_array becomes:
  4933  *     array(
  5085  *     array(
  4934  *         'a' => array(
  5086  *         'a' => array(
  4935  *             'b' => array(
  5087  *             'b' => array(
  4936  *                 'c' => 1,
  5088  *                 'c' => 1,
  4937  *             ),
  5089  *             ),
  4941  * @internal
  5093  * @internal
  4942  *
  5094  *
  4943  * @since 5.8.0
  5095  * @since 5.8.0
  4944  * @access private
  5096  * @access private
  4945  *
  5097  *
  4946  * @param array $array An array that we want to mutate to include a specific value in a path.
  5098  * @param array $input_array An array that we want to mutate to include a specific value in a path.
  4947  * @param array $path  An array of keys describing the path that we want to mutate.
  5099  * @param array $path        An array of keys describing the path that we want to mutate.
  4948  * @param mixed $value The value that will be set.
  5100  * @param mixed $value       The value that will be set.
  4949  */
  5101  */
  4950 function _wp_array_set( &$array, $path, $value = null ) {
  5102 function _wp_array_set( &$input_array, $path, $value = null ) {
  4951 	// Confirm $array is valid.
  5103 	// Confirm $input_array is valid.
  4952 	if ( ! is_array( $array ) ) {
  5104 	if ( ! is_array( $input_array ) ) {
  4953 		return;
  5105 		return;
  4954 	}
  5106 	}
  4955 
  5107 
  4956 	// Confirm $path is valid.
  5108 	// Confirm $path is valid.
  4957 	if ( ! is_array( $path ) ) {
  5109 	if ( ! is_array( $path ) ) {
  4974 	}
  5126 	}
  4975 
  5127 
  4976 	for ( $i = 0; $i < $path_length - 1; ++$i ) {
  5128 	for ( $i = 0; $i < $path_length - 1; ++$i ) {
  4977 		$path_element = $path[ $i ];
  5129 		$path_element = $path[ $i ];
  4978 		if (
  5130 		if (
  4979 			! array_key_exists( $path_element, $array ) ||
  5131 			! array_key_exists( $path_element, $input_array ) ||
  4980 			! is_array( $array[ $path_element ] )
  5132 			! is_array( $input_array[ $path_element ] )
  4981 		) {
  5133 		) {
  4982 			$array[ $path_element ] = array();
  5134 			$input_array[ $path_element ] = array();
  4983 		}
  5135 		}
  4984 		$array = &$array[ $path_element ]; // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.VariableRedeclaration
  5136 		$input_array = &$input_array[ $path_element ];
  4985 	}
  5137 	}
  4986 
  5138 
  4987 	$array[ $path[ $i ] ] = $value;
  5139 	$input_array[ $path[ $i ] ] = $value;
  4988 }
  5140 }
  4989 
  5141 
  4990 /**
  5142 /**
  4991  * This function is trying to replicate what
  5143  * This function is trying to replicate what
  4992  * lodash's kebabCase (JS library) does in the client.
  5144  * lodash's kebabCase (JS library) does in the client.
  5006  * @link https://github.com/lodash/lodash/blob/4.17/dist/lodash.js#L14369
  5158  * @link https://github.com/lodash/lodash/blob/4.17/dist/lodash.js#L14369
  5007  * @link https://github.com/lodash/lodash/blob/4.17/dist/lodash.js#L278
  5159  * @link https://github.com/lodash/lodash/blob/4.17/dist/lodash.js#L278
  5008  * @link https://github.com/lodash-php/lodash-php/blob/master/src/String/kebabCase.php
  5160  * @link https://github.com/lodash-php/lodash-php/blob/master/src/String/kebabCase.php
  5009  * @link https://github.com/lodash-php/lodash-php/blob/master/src/internal/unicodeWords.php
  5161  * @link https://github.com/lodash-php/lodash-php/blob/master/src/internal/unicodeWords.php
  5010  *
  5162  *
  5011  * @param string $string The string to kebab-case.
  5163  * @param string $input_string The string to kebab-case.
  5012  *
  5164  *
  5013  * @return string kebab-cased-string.
  5165  * @return string kebab-cased-string.
  5014  */
  5166  */
  5015 function _wp_to_kebab_case( $string ) {
  5167 function _wp_to_kebab_case( $input_string ) {
  5016 	//phpcs:disable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
  5168 	// Ignore the camelCase names for variables so the names are the same as lodash so comparing and porting new changes is easier.
  5017 	// ignore the camelCase names for variables so the names are the same as lodash
  5169 	// phpcs:disable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
  5018 	// so comparing and porting new changes is easier.
       
  5019 
  5170 
  5020 	/*
  5171 	/*
  5021 	 * Some notable things we've removed compared to the lodash version are:
  5172 	 * Some notable things we've removed compared to the lodash version are:
  5022 	 *
  5173 	 *
  5023 	 * - non-alphanumeric characters: rsAstralRange, rsEmoji, etc
  5174 	 * - non-alphanumeric characters: rsAstralRange, rsEmoji, etc
  5057 			$rsOrdLower,
  5208 			$rsOrdLower,
  5058 			$rsDigits,
  5209 			$rsDigits,
  5059 		)
  5210 		)
  5060 	) . '/u';
  5211 	) . '/u';
  5061 
  5212 
  5062 	preg_match_all( $regexp, str_replace( "'", '', $string ), $matches );
  5213 	preg_match_all( $regexp, str_replace( "'", '', $input_string ), $matches );
  5063 	return strtolower( implode( '-', $matches[0] ) );
  5214 	return strtolower( implode( '-', $matches[0] ) );
  5064 	//phpcs:enable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
  5215 	// phpcs:enable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
  5065 }
  5216 }
  5066 
  5217 
  5067 /**
  5218 /**
  5068  * Determines if the variable is a numeric-indexed array.
  5219  * Determines if the variable is a numeric-indexed array.
  5069  *
  5220  *
  5098  * only does the filtering.
  5249  * only does the filtering.
  5099  *
  5250  *
  5100  * @since 3.0.0
  5251  * @since 3.0.0
  5101  * @since 4.7.0 Uses `WP_List_Util` class.
  5252  * @since 4.7.0 Uses `WP_List_Util` class.
  5102  *
  5253  *
  5103  * @param array       $list     An array of objects to filter.
  5254  * @param array       $input_list An array of objects to filter.
  5104  * @param array       $args     Optional. An array of key => value arguments to match
  5255  * @param array       $args       Optional. An array of key => value arguments to match
  5105  *                              against each object. Default empty array.
  5256  *                                against each object. Default empty array.
  5106  * @param string      $operator Optional. The logical operation to perform. 'AND' means
  5257  * @param string      $operator   Optional. The logical operation to perform. 'AND' means
  5107  *                              all elements from the array must match. 'OR' means only
  5258  *                                all elements from the array must match. 'OR' means only
  5108  *                              one element needs to match. 'NOT' means no elements may
  5259  *                                one element needs to match. 'NOT' means no elements may
  5109  *                              match. Default 'AND'.
  5260  *                                match. Default 'AND'.
  5110  * @param bool|string $field    Optional. A field from the object to place instead
  5261  * @param bool|string $field      Optional. A field from the object to place instead
  5111  *                              of the entire object. Default false.
  5262  *                                of the entire object. Default false.
  5112  * @return array A list of objects or object fields.
  5263  * @return array A list of objects or object fields.
  5113  */
  5264  */
  5114 function wp_filter_object_list( $list, $args = array(), $operator = 'and', $field = false ) {
  5265 function wp_filter_object_list( $input_list, $args = array(), $operator = 'and', $field = false ) {
  5115 	if ( ! is_array( $list ) ) {
  5266 	if ( ! is_array( $input_list ) ) {
  5116 		return array();
  5267 		return array();
  5117 	}
  5268 	}
  5118 
  5269 
  5119 	$util = new WP_List_Util( $list );
  5270 	$util = new WP_List_Util( $input_list );
  5120 
  5271 
  5121 	$util->filter( $args, $operator );
  5272 	$util->filter( $args, $operator );
  5122 
  5273 
  5123 	if ( $field ) {
  5274 	if ( $field ) {
  5124 		$util->pluck( $field );
  5275 		$util->pluck( $field );
  5142  *
  5293  *
  5143  * @since 3.1.0
  5294  * @since 3.1.0
  5144  * @since 4.7.0 Uses `WP_List_Util` class.
  5295  * @since 4.7.0 Uses `WP_List_Util` class.
  5145  * @since 5.9.0 Converted into a wrapper for `wp_filter_object_list()`.
  5296  * @since 5.9.0 Converted into a wrapper for `wp_filter_object_list()`.
  5146  *
  5297  *
  5147  * @param array  $list     An array of objects to filter.
  5298  * @param array  $input_list An array of objects to filter.
  5148  * @param array  $args     Optional. An array of key => value arguments to match
  5299  * @param array  $args       Optional. An array of key => value arguments to match
  5149  *                         against each object. Default empty array.
  5300  *                           against each object. Default empty array.
  5150  * @param string $operator Optional. The logical operation to perform. 'AND' means
  5301  * @param string $operator   Optional. The logical operation to perform. 'AND' means
  5151  *                         all elements from the array must match. 'OR' means only
  5302  *                           all elements from the array must match. 'OR' means only
  5152  *                         one element needs to match. 'NOT' means no elements may
  5303  *                           one element needs to match. 'NOT' means no elements may
  5153  *                         match. Default 'AND'.
  5304  *                           match. Default 'AND'.
  5154  * @return array Array of found values.
  5305  * @return array Array of found values.
  5155  */
  5306  */
  5156 function wp_list_filter( $list, $args = array(), $operator = 'AND' ) {
  5307 function wp_list_filter( $input_list, $args = array(), $operator = 'AND' ) {
  5157 	return wp_filter_object_list( $list, $args, $operator );
  5308 	return wp_filter_object_list( $input_list, $args, $operator );
  5158 }
  5309 }
  5159 
  5310 
  5160 /**
  5311 /**
  5161  * Plucks a certain field out of each object or array in an array.
  5312  * Plucks a certain field out of each object or array in an array.
  5162  *
  5313  *
  5165  *
  5316  *
  5166  * @since 3.1.0
  5317  * @since 3.1.0
  5167  * @since 4.0.0 $index_key parameter added.
  5318  * @since 4.0.0 $index_key parameter added.
  5168  * @since 4.7.0 Uses `WP_List_Util` class.
  5319  * @since 4.7.0 Uses `WP_List_Util` class.
  5169  *
  5320  *
  5170  * @param array      $list      List of objects or arrays.
  5321  * @param array      $input_list List of objects or arrays.
  5171  * @param int|string $field     Field from the object to place instead of the entire object.
  5322  * @param int|string $field      Field from the object to place instead of the entire object.
  5172  * @param int|string $index_key Optional. Field from the object to use as keys for the new array.
  5323  * @param int|string $index_key  Optional. Field from the object to use as keys for the new array.
  5173  *                              Default null.
  5324  *                               Default null.
  5174  * @return array Array of found values. If `$index_key` is set, an array of found values with keys
  5325  * @return array Array of found values. If `$index_key` is set, an array of found values with keys
  5175  *               corresponding to `$index_key`. If `$index_key` is null, array keys from the original
  5326  *               corresponding to `$index_key`. If `$index_key` is null, array keys from the original
  5176  *               `$list` will be preserved in the results.
  5327  *               `$input_list` will be preserved in the results.
  5177  */
  5328  */
  5178 function wp_list_pluck( $list, $field, $index_key = null ) {
  5329 function wp_list_pluck( $input_list, $field, $index_key = null ) {
  5179 	if ( ! is_array( $list ) ) {
  5330 	if ( ! is_array( $input_list ) ) {
  5180 		return array();
  5331 		return array();
  5181 	}
  5332 	}
  5182 
  5333 
  5183 	$util = new WP_List_Util( $list );
  5334 	$util = new WP_List_Util( $input_list );
  5184 
  5335 
  5185 	return $util->pluck( $field, $index_key );
  5336 	return $util->pluck( $field, $index_key );
  5186 }
  5337 }
  5187 
  5338 
  5188 /**
  5339 /**
  5189  * Sorts an array of objects or arrays based on one or more orderby arguments.
  5340  * Sorts an array of objects or arrays based on one or more orderby arguments.
  5190  *
  5341  *
  5191  * @since 4.7.0
  5342  * @since 4.7.0
  5192  *
  5343  *
  5193  * @param array        $list          An array of objects to sort.
  5344  * @param array        $input_list    An array of objects or arrays to sort.
  5194  * @param string|array $orderby       Optional. Either the field name to order by or an array
  5345  * @param string|array $orderby       Optional. Either the field name to order by or an array
  5195  *                                    of multiple orderby fields as $orderby => $order.
  5346  *                                    of multiple orderby fields as `$orderby => $order`.
  5196  * @param string       $order         Optional. Either 'ASC' or 'DESC'. Only used if $orderby
  5347  *                                    Default empty array.
  5197  *                                    is a string.
  5348  * @param string       $order         Optional. Either 'ASC' or 'DESC'. Only used if `$orderby`
       
  5349  *                                    is a string. Default 'ASC'.
  5198  * @param bool         $preserve_keys Optional. Whether to preserve keys. Default false.
  5350  * @param bool         $preserve_keys Optional. Whether to preserve keys. Default false.
  5199  * @return array The sorted array.
  5351  * @return array The sorted array.
  5200  */
  5352  */
  5201 function wp_list_sort( $list, $orderby = array(), $order = 'ASC', $preserve_keys = false ) {
  5353 function wp_list_sort( $input_list, $orderby = array(), $order = 'ASC', $preserve_keys = false ) {
  5202 	if ( ! is_array( $list ) ) {
  5354 	if ( ! is_array( $input_list ) ) {
  5203 		return array();
  5355 		return array();
  5204 	}
  5356 	}
  5205 
  5357 
  5206 	$util = new WP_List_Util( $list );
  5358 	$util = new WP_List_Util( $input_list );
  5207 
  5359 
  5208 	return $util->sort( $orderby, $order, $preserve_keys );
  5360 	return $util->sort( $orderby, $order, $preserve_keys );
  5209 }
  5361 }
  5210 
  5362 
  5211 /**
  5363 /**
  5236 
  5388 
  5237 	add_action( '_admin_menu', 'wp_widgets_add_menu' );
  5389 	add_action( '_admin_menu', 'wp_widgets_add_menu' );
  5238 }
  5390 }
  5239 
  5391 
  5240 /**
  5392 /**
  5241  * Append the Widgets menu to the themes main menu.
  5393  * Appends the Widgets menu to the themes main menu.
  5242  *
  5394  *
  5243  * @since 2.2.0
  5395  * @since 2.2.0
  5244  * @since 5.9.3 Don't specify menu order when the active theme is a block theme.
  5396  * @since 5.9.3 Don't specify menu order when the active theme is a block theme.
  5245  *
  5397  *
  5246  * @global array $submenu
  5398  * @global array $submenu
  5254 
  5406 
  5255 	$menu_name = __( 'Widgets' );
  5407 	$menu_name = __( 'Widgets' );
  5256 	if ( wp_is_block_theme() ) {
  5408 	if ( wp_is_block_theme() ) {
  5257 		$submenu['themes.php'][] = array( $menu_name, 'edit_theme_options', 'widgets.php' );
  5409 		$submenu['themes.php'][] = array( $menu_name, 'edit_theme_options', 'widgets.php' );
  5258 	} else {
  5410 	} else {
  5259 		$submenu['themes.php'][7] = array( $menu_name, 'edit_theme_options', 'widgets.php' );
  5411 		$submenu['themes.php'][8] = array( $menu_name, 'edit_theme_options', 'widgets.php' );
  5260 	}
  5412 	}
  5261 
  5413 
  5262 	ksort( $submenu['themes.php'], SORT_NUMERIC );
  5414 	ksort( $submenu['themes.php'], SORT_NUMERIC );
  5263 }
  5415 }
  5264 
  5416 
  5265 /**
  5417 /**
  5266  * Flush all output buffers for PHP 5.2.
  5418  * Flushes all output buffers for PHP 5.2.
  5267  *
  5419  *
  5268  * Make sure all output buffers are flushed before our singletons are destroyed.
  5420  * Make sure all output buffers are flushed before our singletons are destroyed.
  5269  *
  5421  *
  5270  * @since 2.2.0
  5422  * @since 2.2.0
  5271  */
  5423  */
  5275 		ob_end_flush();
  5427 		ob_end_flush();
  5276 	}
  5428 	}
  5277 }
  5429 }
  5278 
  5430 
  5279 /**
  5431 /**
  5280  * Load custom DB error or display WordPress DB error.
  5432  * Loads custom DB error or display WordPress DB error.
  5281  *
  5433  *
  5282  * If a file exists in the wp-content directory named db-error.php, then it will
  5434  * If a file exists in the wp-content directory named db-error.php, then it will
  5283  * be loaded instead of displaying the WordPress DB error. If it is not found,
  5435  * be loaded instead of displaying the WordPress DB error. If it is not found,
  5284  * then the WordPress DB error will be displayed instead.
  5436  * then the WordPress DB error will be displayed instead.
  5285  *
  5437  *
  5313 	// Otherwise, be terse.
  5465 	// Otherwise, be terse.
  5314 	wp_die( '<h1>' . __( 'Error establishing a database connection' ) . '</h1>', __( 'Database Error' ) );
  5466 	wp_die( '<h1>' . __( 'Error establishing a database connection' ) . '</h1>', __( 'Database Error' ) );
  5315 }
  5467 }
  5316 
  5468 
  5317 /**
  5469 /**
  5318  * Convert a value to non-negative integer.
  5470  * Converts a value to non-negative integer.
  5319  *
  5471  *
  5320  * @since 2.5.0
  5472  * @since 2.5.0
  5321  *
  5473  *
  5322  * @param mixed $maybeint Data you wish to have converted to a non-negative integer.
  5474  * @param mixed $maybeint Data you wish to have converted to a non-negative integer.
  5323  * @return int A non-negative integer.
  5475  * @return int A non-negative integer.
  5325 function absint( $maybeint ) {
  5477 function absint( $maybeint ) {
  5326 	return abs( (int) $maybeint );
  5478 	return abs( (int) $maybeint );
  5327 }
  5479 }
  5328 
  5480 
  5329 /**
  5481 /**
  5330  * Mark a function as deprecated and inform when it has been used.
  5482  * Marks a function as deprecated and inform when it has been used.
  5331  *
  5483  *
  5332  * There is a {@see 'hook deprecated_function_run'} that will be called that can be used
  5484  * There is a {@see 'deprecated_function_run'} hook that will be called that can be used
  5333  * to get the backtrace up to what file and function called the deprecated
  5485  * to get the backtrace up to what file and function called the deprecated function.
  5334  * function.
       
  5335  *
  5486  *
  5336  * The current behavior is to trigger a user error if `WP_DEBUG` is true.
  5487  * The current behavior is to trigger a user error if `WP_DEBUG` is true.
  5337  *
  5488  *
  5338  * This function is to be used in every function that is deprecated.
  5489  * This function is to be used in every function that is deprecated.
  5339  *
  5490  *
  5340  * @since 2.5.0
  5491  * @since 2.5.0
  5341  * @since 5.4.0 This function is no longer marked as "private".
  5492  * @since 5.4.0 This function is no longer marked as "private".
  5342  * @since 5.4.0 The error type is now classified as E_USER_DEPRECATED (used to default to E_USER_NOTICE).
  5493  * @since 5.4.0 The error type is now classified as E_USER_DEPRECATED (used to default to E_USER_NOTICE).
  5343  *
  5494  *
  5344  * @param string $function    The function that was called.
  5495  * @param string $function_name The function that was called.
  5345  * @param string $version     The version of WordPress that deprecated the function.
  5496  * @param string $version       The version of WordPress that deprecated the function.
  5346  * @param string $replacement Optional. The function that should have been called. Default empty.
  5497  * @param string $replacement   Optional. The function that should have been called. Default empty string.
  5347  */
  5498  */
  5348 function _deprecated_function( $function, $version, $replacement = '' ) {
  5499 function _deprecated_function( $function_name, $version, $replacement = '' ) {
  5349 
  5500 
  5350 	/**
  5501 	/**
  5351 	 * Fires when a deprecated function is called.
  5502 	 * Fires when a deprecated function is called.
  5352 	 *
  5503 	 *
  5353 	 * @since 2.5.0
  5504 	 * @since 2.5.0
  5354 	 *
  5505 	 *
  5355 	 * @param string $function    The function that was called.
  5506 	 * @param string $function_name The function that was called.
  5356 	 * @param string $replacement The function that should have been called.
  5507 	 * @param string $replacement   The function that should have been called.
  5357 	 * @param string $version     The version of WordPress that deprecated the function.
  5508 	 * @param string $version       The version of WordPress that deprecated the function.
  5358 	 */
  5509 	 */
  5359 	do_action( 'deprecated_function_run', $function, $replacement, $version );
  5510 	do_action( 'deprecated_function_run', $function_name, $replacement, $version );
  5360 
  5511 
  5361 	/**
  5512 	/**
  5362 	 * Filters whether to trigger an error for deprecated functions.
  5513 	 * Filters whether to trigger an error for deprecated functions.
  5363 	 *
  5514 	 *
  5364 	 * @since 2.5.0
  5515 	 * @since 2.5.0
  5366 	 * @param bool $trigger Whether to trigger the error for deprecated functions. Default true.
  5517 	 * @param bool $trigger Whether to trigger the error for deprecated functions. Default true.
  5367 	 */
  5518 	 */
  5368 	if ( WP_DEBUG && apply_filters( 'deprecated_function_trigger_error', true ) ) {
  5519 	if ( WP_DEBUG && apply_filters( 'deprecated_function_trigger_error', true ) ) {
  5369 		if ( function_exists( '__' ) ) {
  5520 		if ( function_exists( '__' ) ) {
  5370 			if ( $replacement ) {
  5521 			if ( $replacement ) {
  5371 				trigger_error(
  5522 				$message = sprintf(
  5372 					sprintf(
  5523 					/* translators: 1: PHP function name, 2: Version number, 3: Alternative function name. */
  5373 						/* translators: 1: PHP function name, 2: Version number, 3: Alternative function name. */
  5524 					__( 'Function %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ),
  5374 						__( 'Function %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ),
  5525 					$function_name,
  5375 						$function,
  5526 					$version,
  5376 						$version,
  5527 					$replacement
  5377 						$replacement
       
  5378 					),
       
  5379 					E_USER_DEPRECATED
       
  5380 				);
  5528 				);
  5381 			} else {
  5529 			} else {
  5382 				trigger_error(
  5530 				$message = sprintf(
  5383 					sprintf(
  5531 					/* translators: 1: PHP function name, 2: Version number. */
  5384 						/* translators: 1: PHP function name, 2: Version number. */
  5532 					__( 'Function %1$s is <strong>deprecated</strong> since version %2$s with no alternative available.' ),
  5385 						__( 'Function %1$s is <strong>deprecated</strong> since version %2$s with no alternative available.' ),
  5533 					$function_name,
  5386 						$function,
  5534 					$version
  5387 						$version
       
  5388 					),
       
  5389 					E_USER_DEPRECATED
       
  5390 				);
  5535 				);
  5391 			}
  5536 			}
  5392 		} else {
  5537 		} else {
  5393 			if ( $replacement ) {
  5538 			if ( $replacement ) {
  5394 				trigger_error(
  5539 				$message = sprintf(
  5395 					sprintf(
  5540 					'Function %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.',
  5396 						'Function %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.',
  5541 					$function_name,
  5397 						$function,
  5542 					$version,
  5398 						$version,
  5543 					$replacement
  5399 						$replacement
       
  5400 					),
       
  5401 					E_USER_DEPRECATED
       
  5402 				);
  5544 				);
  5403 			} else {
  5545 			} else {
  5404 				trigger_error(
  5546 				$message = sprintf(
  5405 					sprintf(
  5547 					'Function %1$s is <strong>deprecated</strong> since version %2$s with no alternative available.',
  5406 						'Function %1$s is <strong>deprecated</strong> since version %2$s with no alternative available.',
  5548 					$function_name,
  5407 						$function,
  5549 					$version
  5408 						$version
       
  5409 					),
       
  5410 					E_USER_DEPRECATED
       
  5411 				);
  5550 				);
  5412 			}
  5551 			}
  5413 		}
  5552 		}
       
  5553 
       
  5554 		wp_trigger_error( '', $message, E_USER_DEPRECATED );
  5414 	}
  5555 	}
  5415 }
  5556 }
  5416 
  5557 
  5417 /**
  5558 /**
  5418  * Marks a constructor as deprecated and informs when it has been used.
  5559  * Marks a constructor as deprecated and informs when it has been used.
  5419  *
  5560  *
  5420  * Similar to _deprecated_function(), but with different strings. Used to
  5561  * Similar to _deprecated_function(), but with different strings. Used to
  5421  * remove PHP4 style constructors.
  5562  * remove PHP4-style constructors.
  5422  *
  5563  *
  5423  * The current behavior is to trigger a user error if `WP_DEBUG` is true.
  5564  * The current behavior is to trigger a user error if `WP_DEBUG` is true.
  5424  *
  5565  *
  5425  * This function is to be used in every PHP4 style constructor method that is deprecated.
  5566  * This function is to be used in every PHP4-style constructor method that is deprecated.
  5426  *
  5567  *
  5427  * @since 4.3.0
  5568  * @since 4.3.0
  5428  * @since 4.5.0 Added the `$parent_class` parameter.
  5569  * @since 4.5.0 Added the `$parent_class` parameter.
  5429  * @since 5.4.0 This function is no longer marked as "private".
  5570  * @since 5.4.0 This function is no longer marked as "private".
  5430  * @since 5.4.0 The error type is now classified as E_USER_DEPRECATED (used to default to E_USER_NOTICE).
  5571  * @since 5.4.0 The error type is now classified as E_USER_DEPRECATED (used to default to E_USER_NOTICE).
  5431  *
  5572  *
  5432  * @param string $class        The class containing the deprecated constructor.
  5573  * @param string $class_name   The class containing the deprecated constructor.
  5433  * @param string $version      The version of WordPress that deprecated the function.
  5574  * @param string $version      The version of WordPress that deprecated the function.
  5434  * @param string $parent_class Optional. The parent class calling the deprecated constructor.
  5575  * @param string $parent_class Optional. The parent class calling the deprecated constructor.
  5435  *                             Default empty string.
  5576  *                             Default empty string.
  5436  */
  5577  */
  5437 function _deprecated_constructor( $class, $version, $parent_class = '' ) {
  5578 function _deprecated_constructor( $class_name, $version, $parent_class = '' ) {
  5438 
  5579 
  5439 	/**
  5580 	/**
  5440 	 * Fires when a deprecated constructor is called.
  5581 	 * Fires when a deprecated constructor is called.
  5441 	 *
  5582 	 *
  5442 	 * @since 4.3.0
  5583 	 * @since 4.3.0
  5443 	 * @since 4.5.0 Added the `$parent_class` parameter.
  5584 	 * @since 4.5.0 Added the `$parent_class` parameter.
  5444 	 *
  5585 	 *
  5445 	 * @param string $class        The class containing the deprecated constructor.
  5586 	 * @param string $class_name   The class containing the deprecated constructor.
  5446 	 * @param string $version      The version of WordPress that deprecated the function.
  5587 	 * @param string $version      The version of WordPress that deprecated the function.
  5447 	 * @param string $parent_class The parent class calling the deprecated constructor.
  5588 	 * @param string $parent_class The parent class calling the deprecated constructor.
  5448 	 */
  5589 	 */
  5449 	do_action( 'deprecated_constructor_run', $class, $version, $parent_class );
  5590 	do_action( 'deprecated_constructor_run', $class_name, $version, $parent_class );
  5450 
  5591 
  5451 	/**
  5592 	/**
  5452 	 * Filters whether to trigger an error for deprecated functions.
  5593 	 * Filters whether to trigger an error for deprecated functions.
  5453 	 *
  5594 	 *
  5454 	 * `WP_DEBUG` must be true in addition to the filter evaluating to true.
  5595 	 * `WP_DEBUG` must be true in addition to the filter evaluating to true.
  5458 	 * @param bool $trigger Whether to trigger the error for deprecated functions. Default true.
  5599 	 * @param bool $trigger Whether to trigger the error for deprecated functions. Default true.
  5459 	 */
  5600 	 */
  5460 	if ( WP_DEBUG && apply_filters( 'deprecated_constructor_trigger_error', true ) ) {
  5601 	if ( WP_DEBUG && apply_filters( 'deprecated_constructor_trigger_error', true ) ) {
  5461 		if ( function_exists( '__' ) ) {
  5602 		if ( function_exists( '__' ) ) {
  5462 			if ( $parent_class ) {
  5603 			if ( $parent_class ) {
  5463 				trigger_error(
  5604 				$message = sprintf(
  5464 					sprintf(
  5605 					/* translators: 1: PHP class name, 2: PHP parent class name, 3: Version number, 4: __construct() method. */
  5465 						/* translators: 1: PHP class name, 2: PHP parent class name, 3: Version number, 4: __construct() method. */
  5606 					__( 'The called constructor method for %1$s class in %2$s is <strong>deprecated</strong> since version %3$s! Use %4$s instead.' ),
  5466 						__( 'The called constructor method for %1$s class in %2$s is <strong>deprecated</strong> since version %3$s! Use %4$s instead.' ),
  5607 					$class_name,
  5467 						$class,
  5608 					$parent_class,
  5468 						$parent_class,
  5609 					$version,
  5469 						$version,
  5610 					'<code>__construct()</code>'
  5470 						'<code>__construct()</code>'
       
  5471 					),
       
  5472 					E_USER_DEPRECATED
       
  5473 				);
  5611 				);
  5474 			} else {
  5612 			} else {
  5475 				trigger_error(
  5613 				$message = sprintf(
  5476 					sprintf(
  5614 					/* translators: 1: PHP class name, 2: Version number, 3: __construct() method. */
  5477 						/* translators: 1: PHP class name, 2: Version number, 3: __construct() method. */
  5615 					__( 'The called constructor method for %1$s class is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ),
  5478 						__( 'The called constructor method for %1$s class is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ),
  5616 					$class_name,
  5479 						$class,
  5617 					$version,
  5480 						$version,
  5618 					'<code>__construct()</code>'
  5481 						'<code>__construct()</code>'
       
  5482 					),
       
  5483 					E_USER_DEPRECATED
       
  5484 				);
  5619 				);
  5485 			}
  5620 			}
  5486 		} else {
  5621 		} else {
  5487 			if ( $parent_class ) {
  5622 			if ( $parent_class ) {
  5488 				trigger_error(
  5623 				$message = sprintf(
  5489 					sprintf(
  5624 					'The called constructor method for %1$s class in %2$s is <strong>deprecated</strong> since version %3$s! Use %4$s instead.',
  5490 						'The called constructor method for %1$s class in %2$s is <strong>deprecated</strong> since version %3$s! Use %4$s instead.',
  5625 					$class_name,
  5491 						$class,
  5626 					$parent_class,
  5492 						$parent_class,
  5627 					$version,
  5493 						$version,
  5628 					'<code>__construct()</code>'
  5494 						'<code>__construct()</code>'
       
  5495 					),
       
  5496 					E_USER_DEPRECATED
       
  5497 				);
  5629 				);
  5498 			} else {
  5630 			} else {
  5499 				trigger_error(
  5631 				$message = sprintf(
  5500 					sprintf(
  5632 					'The called constructor method for %1$s class is <strong>deprecated</strong> since version %2$s! Use %3$s instead.',
  5501 						'The called constructor method for %1$s class is <strong>deprecated</strong> since version %2$s! Use %3$s instead.',
  5633 					$class_name,
  5502 						$class,
  5634 					$version,
  5503 						$version,
  5635 					'<code>__construct()</code>'
  5504 						'<code>__construct()</code>'
       
  5505 					),
       
  5506 					E_USER_DEPRECATED
       
  5507 				);
  5636 				);
  5508 			}
  5637 			}
  5509 		}
  5638 		}
  5510 	}
  5639 
  5511 
  5640 		wp_trigger_error( '', $message, E_USER_DEPRECATED );
  5512 }
  5641 	}
  5513 
  5642 }
  5514 /**
  5643 
  5515  * Mark a file as deprecated and inform when it has been used.
  5644 /**
  5516  *
  5645  * Marks a class as deprecated and informs when it has been used.
  5517  * There is a hook {@see 'deprecated_file_included'} that will be called that can be used
  5646  *
  5518  * to get the backtrace up to what file and function included the deprecated
  5647  * There is a {@see 'deprecated_class_run'} hook that will be called that can be used
  5519  * file.
  5648  * to get the backtrace up to what file and function called the deprecated class.
       
  5649  *
       
  5650  * The current behavior is to trigger a user error if `WP_DEBUG` is true.
       
  5651  *
       
  5652  * This function is to be used in the class constructor for every deprecated class.
       
  5653  * See {@see _deprecated_constructor()} for deprecating PHP4-style constructors.
       
  5654  *
       
  5655  * @since 6.4.0
       
  5656  *
       
  5657  * @param string $class_name  The name of the class being instantiated.
       
  5658  * @param string $version     The version of WordPress that deprecated the class.
       
  5659  * @param string $replacement Optional. The class or function that should have been called.
       
  5660  *                            Default empty string.
       
  5661  */
       
  5662 function _deprecated_class( $class_name, $version, $replacement = '' ) {
       
  5663 
       
  5664 	/**
       
  5665 	 * Fires when a deprecated class is called.
       
  5666 	 *
       
  5667 	 * @since 6.4.0
       
  5668 	 *
       
  5669 	 * @param string $class_name  The name of the class being instantiated.
       
  5670 	 * @param string $replacement The class or function that should have been called.
       
  5671 	 * @param string $version     The version of WordPress that deprecated the class.
       
  5672 	 */
       
  5673 	do_action( 'deprecated_class_run', $class_name, $replacement, $version );
       
  5674 
       
  5675 	/**
       
  5676 	 * Filters whether to trigger an error for a deprecated class.
       
  5677 	 *
       
  5678 	 * @since 6.4.0
       
  5679 	 *
       
  5680 	 * @param bool $trigger Whether to trigger an error for a deprecated class. Default true.
       
  5681 	 */
       
  5682 	if ( WP_DEBUG && apply_filters( 'deprecated_class_trigger_error', true ) ) {
       
  5683 		if ( function_exists( '__' ) ) {
       
  5684 			if ( $replacement ) {
       
  5685 				$message = sprintf(
       
  5686 					/* translators: 1: PHP class name, 2: Version number, 3: Alternative class or function name. */
       
  5687 					__( 'Class %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ),
       
  5688 					$class_name,
       
  5689 					$version,
       
  5690 					$replacement
       
  5691 				);
       
  5692 			} else {
       
  5693 				$message = sprintf(
       
  5694 					/* translators: 1: PHP class name, 2: Version number. */
       
  5695 					__( 'Class %1$s is <strong>deprecated</strong> since version %2$s with no alternative available.' ),
       
  5696 					$class_name,
       
  5697 					$version
       
  5698 				);
       
  5699 			}
       
  5700 		} else {
       
  5701 			if ( $replacement ) {
       
  5702 				$message = sprintf(
       
  5703 					'Class %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.',
       
  5704 					$class_name,
       
  5705 					$version,
       
  5706 					$replacement
       
  5707 				);
       
  5708 			} else {
       
  5709 				$message = sprintf(
       
  5710 					'Class %1$s is <strong>deprecated</strong> since version %2$s with no alternative available.',
       
  5711 					$class_name,
       
  5712 					$version
       
  5713 				);
       
  5714 			}
       
  5715 		}
       
  5716 
       
  5717 		wp_trigger_error( '', $message, E_USER_DEPRECATED );
       
  5718 	}
       
  5719 }
       
  5720 
       
  5721 /**
       
  5722  * Marks a file as deprecated and inform when it has been used.
       
  5723  *
       
  5724  * There is a {@see 'deprecated_file_included'} hook that will be called that can be used
       
  5725  * to get the backtrace up to what file and function included the deprecated file.
  5520  *
  5726  *
  5521  * The current behavior is to trigger a user error if `WP_DEBUG` is true.
  5727  * The current behavior is to trigger a user error if `WP_DEBUG` is true.
  5522  *
  5728  *
  5523  * This function is to be used in every file that is deprecated.
  5729  * This function is to be used in every file that is deprecated.
  5524  *
  5730  *
  5527  * @since 5.4.0 The error type is now classified as E_USER_DEPRECATED (used to default to E_USER_NOTICE).
  5733  * @since 5.4.0 The error type is now classified as E_USER_DEPRECATED (used to default to E_USER_NOTICE).
  5528  *
  5734  *
  5529  * @param string $file        The file that was included.
  5735  * @param string $file        The file that was included.
  5530  * @param string $version     The version of WordPress that deprecated the file.
  5736  * @param string $version     The version of WordPress that deprecated the file.
  5531  * @param string $replacement Optional. The file that should have been included based on ABSPATH.
  5737  * @param string $replacement Optional. The file that should have been included based on ABSPATH.
  5532  *                            Default empty.
  5738  *                            Default empty string.
  5533  * @param string $message     Optional. A message regarding the change. Default empty.
  5739  * @param string $message     Optional. A message regarding the change. Default empty string.
  5534  */
  5740  */
  5535 function _deprecated_file( $file, $version, $replacement = '', $message = '' ) {
  5741 function _deprecated_file( $file, $version, $replacement = '', $message = '' ) {
  5536 
  5742 
  5537 	/**
  5743 	/**
  5538 	 * Fires when a deprecated file is called.
  5744 	 * Fires when a deprecated file is called.
  5556 	if ( WP_DEBUG && apply_filters( 'deprecated_file_trigger_error', true ) ) {
  5762 	if ( WP_DEBUG && apply_filters( 'deprecated_file_trigger_error', true ) ) {
  5557 		$message = empty( $message ) ? '' : ' ' . $message;
  5763 		$message = empty( $message ) ? '' : ' ' . $message;
  5558 
  5764 
  5559 		if ( function_exists( '__' ) ) {
  5765 		if ( function_exists( '__' ) ) {
  5560 			if ( $replacement ) {
  5766 			if ( $replacement ) {
  5561 				trigger_error(
  5767 				$message = sprintf(
  5562 					sprintf(
  5768 					/* translators: 1: PHP file name, 2: Version number, 3: Alternative file name. */
  5563 						/* translators: 1: PHP file name, 2: Version number, 3: Alternative file name. */
  5769 					__( 'File %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ),
  5564 						__( 'File %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ),
  5770 					$file,
  5565 						$file,
  5771 					$version,
  5566 						$version,
  5772 					$replacement
  5567 						$replacement
  5773 				) . $message;
  5568 					) . $message,
       
  5569 					E_USER_DEPRECATED
       
  5570 				);
       
  5571 			} else {
  5774 			} else {
  5572 				trigger_error(
  5775 				$message = sprintf(
  5573 					sprintf(
  5776 					/* translators: 1: PHP file name, 2: Version number. */
  5574 						/* translators: 1: PHP file name, 2: Version number. */
  5777 					__( 'File %1$s is <strong>deprecated</strong> since version %2$s with no alternative available.' ),
  5575 						__( 'File %1$s is <strong>deprecated</strong> since version %2$s with no alternative available.' ),
  5778 					$file,
  5576 						$file,
  5779 					$version
  5577 						$version
  5780 				) . $message;
  5578 					) . $message,
       
  5579 					E_USER_DEPRECATED
       
  5580 				);
       
  5581 			}
  5781 			}
  5582 		} else {
  5782 		} else {
  5583 			if ( $replacement ) {
  5783 			if ( $replacement ) {
  5584 				trigger_error(
  5784 				$message = sprintf(
  5585 					sprintf(
  5785 					'File %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.',
  5586 						'File %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.',
  5786 					$file,
  5587 						$file,
  5787 					$version,
  5588 						$version,
  5788 					$replacement
  5589 						$replacement
       
  5590 					) . $message,
       
  5591 					E_USER_DEPRECATED
       
  5592 				);
  5789 				);
  5593 			} else {
  5790 			} else {
  5594 				trigger_error(
  5791 				$message = sprintf(
  5595 					sprintf(
  5792 					'File %1$s is <strong>deprecated</strong> since version %2$s with no alternative available.',
  5596 						'File %1$s is <strong>deprecated</strong> since version %2$s with no alternative available.',
  5793 					$file,
  5597 						$file,
  5794 					$version
  5598 						$version
  5795 				) . $message;
  5599 					) . $message,
       
  5600 					E_USER_DEPRECATED
       
  5601 				);
       
  5602 			}
  5796 			}
  5603 		}
  5797 		}
  5604 	}
  5798 
  5605 }
  5799 		wp_trigger_error( '', $message, E_USER_DEPRECATED );
  5606 /**
  5800 	}
  5607  * Mark a function argument as deprecated and inform when it has been used.
  5801 }
       
  5802 /**
       
  5803  * Marks a function argument as deprecated and inform when it has been used.
  5608  *
  5804  *
  5609  * This function is to be used whenever a deprecated function argument is used.
  5805  * This function is to be used whenever a deprecated function argument is used.
  5610  * Before this function is called, the argument must be checked for whether it was
  5806  * Before this function is called, the argument must be checked for whether it was
  5611  * used by comparing it to its default value or evaluating whether it is empty.
  5807  * used by comparing it to its default value or evaluating whether it is empty.
       
  5808  *
  5612  * For example:
  5809  * For example:
  5613  *
  5810  *
  5614  *     if ( ! empty( $deprecated ) ) {
  5811  *     if ( ! empty( $deprecated ) ) {
  5615  *         _deprecated_argument( __FUNCTION__, '3.0.0' );
  5812  *         _deprecated_argument( __FUNCTION__, '3.0.0' );
  5616  *     }
  5813  *     }
  5617  *
  5814  *
  5618  * There is a hook deprecated_argument_run that will be called that can be used
  5815  * There is a {@see 'deprecated_argument_run'} hook that will be called that can be used
  5619  * to get the backtrace up to what file and function used the deprecated
  5816  * to get the backtrace up to what file and function used the deprecated argument.
  5620  * argument.
       
  5621  *
  5817  *
  5622  * The current behavior is to trigger a user error if WP_DEBUG is true.
  5818  * The current behavior is to trigger a user error if WP_DEBUG is true.
  5623  *
  5819  *
  5624  * @since 3.0.0
  5820  * @since 3.0.0
  5625  * @since 5.4.0 This function is no longer marked as "private".
  5821  * @since 5.4.0 This function is no longer marked as "private".
  5626  * @since 5.4.0 The error type is now classified as E_USER_DEPRECATED (used to default to E_USER_NOTICE).
  5822  * @since 5.4.0 The error type is now classified as E_USER_DEPRECATED (used to default to E_USER_NOTICE).
  5627  *
  5823  *
  5628  * @param string $function The function that was called.
  5824  * @param string $function_name The function that was called.
  5629  * @param string $version  The version of WordPress that deprecated the argument used.
  5825  * @param string $version       The version of WordPress that deprecated the argument used.
  5630  * @param string $message  Optional. A message regarding the change. Default empty.
  5826  * @param string $message       Optional. A message regarding the change. Default empty string.
  5631  */
  5827  */
  5632 function _deprecated_argument( $function, $version, $message = '' ) {
  5828 function _deprecated_argument( $function_name, $version, $message = '' ) {
  5633 
  5829 
  5634 	/**
  5830 	/**
  5635 	 * Fires when a deprecated argument is called.
  5831 	 * Fires when a deprecated argument is called.
  5636 	 *
  5832 	 *
  5637 	 * @since 3.0.0
  5833 	 * @since 3.0.0
  5638 	 *
  5834 	 *
  5639 	 * @param string $function The function that was called.
  5835 	 * @param string $function_name The function that was called.
  5640 	 * @param string $message  A message regarding the change.
  5836 	 * @param string $message       A message regarding the change.
  5641 	 * @param string $version  The version of WordPress that deprecated the argument used.
  5837 	 * @param string $version       The version of WordPress that deprecated the argument used.
  5642 	 */
  5838 	 */
  5643 	do_action( 'deprecated_argument_run', $function, $message, $version );
  5839 	do_action( 'deprecated_argument_run', $function_name, $message, $version );
  5644 
  5840 
  5645 	/**
  5841 	/**
  5646 	 * Filters whether to trigger an error for deprecated arguments.
  5842 	 * Filters whether to trigger an error for deprecated arguments.
  5647 	 *
  5843 	 *
  5648 	 * @since 3.0.0
  5844 	 * @since 3.0.0
  5650 	 * @param bool $trigger Whether to trigger the error for deprecated arguments. Default true.
  5846 	 * @param bool $trigger Whether to trigger the error for deprecated arguments. Default true.
  5651 	 */
  5847 	 */
  5652 	if ( WP_DEBUG && apply_filters( 'deprecated_argument_trigger_error', true ) ) {
  5848 	if ( WP_DEBUG && apply_filters( 'deprecated_argument_trigger_error', true ) ) {
  5653 		if ( function_exists( '__' ) ) {
  5849 		if ( function_exists( '__' ) ) {
  5654 			if ( $message ) {
  5850 			if ( $message ) {
  5655 				trigger_error(
  5851 				$message = sprintf(
  5656 					sprintf(
  5852 					/* translators: 1: PHP function name, 2: Version number, 3: Optional message regarding the change. */
  5657 						/* translators: 1: PHP function name, 2: Version number, 3: Optional message regarding the change. */
  5853 					__( 'Function %1$s was called with an argument that is <strong>deprecated</strong> since version %2$s! %3$s' ),
  5658 						__( 'Function %1$s was called with an argument that is <strong>deprecated</strong> since version %2$s! %3$s' ),
  5854 					$function_name,
  5659 						$function,
  5855 					$version,
  5660 						$version,
  5856 					$message
  5661 						$message
       
  5662 					),
       
  5663 					E_USER_DEPRECATED
       
  5664 				);
  5857 				);
  5665 			} else {
  5858 			} else {
  5666 				trigger_error(
  5859 				$message = sprintf(
  5667 					sprintf(
  5860 					/* translators: 1: PHP function name, 2: Version number. */
  5668 						/* translators: 1: PHP function name, 2: Version number. */
  5861 					__( 'Function %1$s was called with an argument that is <strong>deprecated</strong> since version %2$s with no alternative available.' ),
  5669 						__( 'Function %1$s was called with an argument that is <strong>deprecated</strong> since version %2$s with no alternative available.' ),
  5862 					$function_name,
  5670 						$function,
  5863 					$version
  5671 						$version
       
  5672 					),
       
  5673 					E_USER_DEPRECATED
       
  5674 				);
  5864 				);
  5675 			}
  5865 			}
  5676 		} else {
  5866 		} else {
  5677 			if ( $message ) {
  5867 			if ( $message ) {
  5678 				trigger_error(
  5868 				$message = sprintf(
  5679 					sprintf(
  5869 					'Function %1$s was called with an argument that is <strong>deprecated</strong> since version %2$s! %3$s',
  5680 						'Function %1$s was called with an argument that is <strong>deprecated</strong> since version %2$s! %3$s',
  5870 					$function_name,
  5681 						$function,
  5871 					$version,
  5682 						$version,
  5872 					$message
  5683 						$message
       
  5684 					),
       
  5685 					E_USER_DEPRECATED
       
  5686 				);
  5873 				);
  5687 			} else {
  5874 			} else {
  5688 				trigger_error(
  5875 				$message = sprintf(
  5689 					sprintf(
  5876 					'Function %1$s was called with an argument that is <strong>deprecated</strong> since version %2$s with no alternative available.',
  5690 						'Function %1$s was called with an argument that is <strong>deprecated</strong> since version %2$s with no alternative available.',
  5877 					$function_name,
  5691 						$function,
  5878 					$version
  5692 						$version
       
  5693 					),
       
  5694 					E_USER_DEPRECATED
       
  5695 				);
  5879 				);
  5696 			}
  5880 			}
  5697 		}
  5881 		}
       
  5882 
       
  5883 		wp_trigger_error( '', $message, E_USER_DEPRECATED );
  5698 	}
  5884 	}
  5699 }
  5885 }
  5700 
  5886 
  5701 /**
  5887 /**
  5702  * Marks a deprecated action or filter hook as deprecated and throws a notice.
  5888  * Marks a deprecated action or filter hook as deprecated and throws a notice.
  5713  * @since 5.4.0 The error type is now classified as E_USER_DEPRECATED (used to default to E_USER_NOTICE).
  5899  * @since 5.4.0 The error type is now classified as E_USER_DEPRECATED (used to default to E_USER_NOTICE).
  5714  * @access private
  5900  * @access private
  5715  *
  5901  *
  5716  * @param string $hook        The hook that was used.
  5902  * @param string $hook        The hook that was used.
  5717  * @param string $version     The version of WordPress that deprecated the hook.
  5903  * @param string $version     The version of WordPress that deprecated the hook.
  5718  * @param string $replacement Optional. The hook that should have been used. Default empty.
  5904  * @param string $replacement Optional. The hook that should have been used. Default empty string.
  5719  * @param string $message     Optional. A message regarding the change. Default empty.
  5905  * @param string $message     Optional. A message regarding the change. Default empty.
  5720  */
  5906  */
  5721 function _deprecated_hook( $hook, $version, $replacement = '', $message = '' ) {
  5907 function _deprecated_hook( $hook, $version, $replacement = '', $message = '' ) {
  5722 	/**
  5908 	/**
  5723 	 * Fires when a deprecated hook is called.
  5909 	 * Fires when a deprecated hook is called.
  5741 	 */
  5927 	 */
  5742 	if ( WP_DEBUG && apply_filters( 'deprecated_hook_trigger_error', true ) ) {
  5928 	if ( WP_DEBUG && apply_filters( 'deprecated_hook_trigger_error', true ) ) {
  5743 		$message = empty( $message ) ? '' : ' ' . $message;
  5929 		$message = empty( $message ) ? '' : ' ' . $message;
  5744 
  5930 
  5745 		if ( $replacement ) {
  5931 		if ( $replacement ) {
  5746 			trigger_error(
  5932 			$message = sprintf(
  5747 				sprintf(
  5933 				/* translators: 1: WordPress hook name, 2: Version number, 3: Alternative hook name. */
  5748 					/* translators: 1: WordPress hook name, 2: Version number, 3: Alternative hook name. */
  5934 				__( 'Hook %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ),
  5749 					__( 'Hook %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ),
  5935 				$hook,
  5750 					$hook,
  5936 				$version,
  5751 					$version,
  5937 				$replacement
  5752 					$replacement
  5938 			) . $message;
  5753 				) . $message,
       
  5754 				E_USER_DEPRECATED
       
  5755 			);
       
  5756 		} else {
  5939 		} else {
  5757 			trigger_error(
  5940 			$message = sprintf(
  5758 				sprintf(
  5941 				/* translators: 1: WordPress hook name, 2: Version number. */
  5759 					/* translators: 1: WordPress hook name, 2: Version number. */
  5942 				__( 'Hook %1$s is <strong>deprecated</strong> since version %2$s with no alternative available.' ),
  5760 					__( 'Hook %1$s is <strong>deprecated</strong> since version %2$s with no alternative available.' ),
  5943 				$hook,
  5761 					$hook,
  5944 				$version
  5762 					$version
  5945 			) . $message;
  5763 				) . $message,
  5946 		}
  5764 				E_USER_DEPRECATED
  5947 
  5765 			);
  5948 		wp_trigger_error( '', $message, E_USER_DEPRECATED );
  5766 		}
  5949 	}
  5767 	}
  5950 }
  5768 }
  5951 
  5769 
  5952 /**
  5770 /**
  5953  * Marks something as being incorrectly called.
  5771  * Mark something as being incorrectly called.
  5954  *
  5772  *
  5955  * There is a {@see 'doing_it_wrong_run'} hook that will be called that can be used
  5773  * There is a hook {@see 'doing_it_wrong_run'} that will be called that can be used
  5956  * to get the backtrace up to what file and function called the deprecated function.
  5774  * to get the backtrace up to what file and function called the deprecated
       
  5775  * function.
       
  5776  *
  5957  *
  5777  * The current behavior is to trigger a user error if `WP_DEBUG` is true.
  5958  * The current behavior is to trigger a user error if `WP_DEBUG` is true.
  5778  *
  5959  *
  5779  * @since 3.1.0
  5960  * @since 3.1.0
  5780  * @since 5.4.0 This function is no longer marked as "private".
  5961  * @since 5.4.0 This function is no longer marked as "private".
  5781  *
  5962  *
  5782  * @param string $function The function that was called.
  5963  * @param string $function_name The function that was called.
  5783  * @param string $message  A message explaining what has been done incorrectly.
  5964  * @param string $message       A message explaining what has been done incorrectly.
  5784  * @param string $version  The version of WordPress where the message was added.
  5965  * @param string $version       The version of WordPress where the message was added.
  5785  */
  5966  */
  5786 function _doing_it_wrong( $function, $message, $version ) {
  5967 function _doing_it_wrong( $function_name, $message, $version ) {
  5787 
  5968 
  5788 	/**
  5969 	/**
  5789 	 * Fires when the given function is being used incorrectly.
  5970 	 * Fires when the given function is being used incorrectly.
  5790 	 *
  5971 	 *
  5791 	 * @since 3.1.0
  5972 	 * @since 3.1.0
  5792 	 *
  5973 	 *
  5793 	 * @param string $function The function that was called.
  5974 	 * @param string $function_name The function that was called.
  5794 	 * @param string $message  A message explaining what has been done incorrectly.
  5975 	 * @param string $message       A message explaining what has been done incorrectly.
  5795 	 * @param string $version  The version of WordPress where the message was added.
  5976 	 * @param string $version       The version of WordPress where the message was added.
  5796 	 */
  5977 	 */
  5797 	do_action( 'doing_it_wrong_run', $function, $message, $version );
  5978 	do_action( 'doing_it_wrong_run', $function_name, $message, $version );
  5798 
  5979 
  5799 	/**
  5980 	/**
  5800 	 * Filters whether to trigger an error for _doing_it_wrong() calls.
  5981 	 * Filters whether to trigger an error for _doing_it_wrong() calls.
  5801 	 *
  5982 	 *
  5802 	 * @since 3.1.0
  5983 	 * @since 3.1.0
  5803 	 * @since 5.1.0 Added the $function, $message and $version parameters.
  5984 	 * @since 5.1.0 Added the $function_name, $message and $version parameters.
  5804 	 *
  5985 	 *
  5805 	 * @param bool   $trigger  Whether to trigger the error for _doing_it_wrong() calls. Default true.
  5986 	 * @param bool   $trigger       Whether to trigger the error for _doing_it_wrong() calls. Default true.
  5806 	 * @param string $function The function that was called.
  5987 	 * @param string $function_name The function that was called.
  5807 	 * @param string $message  A message explaining what has been done incorrectly.
  5988 	 * @param string $message       A message explaining what has been done incorrectly.
  5808 	 * @param string $version  The version of WordPress where the message was added.
  5989 	 * @param string $version       The version of WordPress where the message was added.
  5809 	 */
  5990 	 */
  5810 	if ( WP_DEBUG && apply_filters( 'doing_it_wrong_trigger_error', true, $function, $message, $version ) ) {
  5991 	if ( WP_DEBUG && apply_filters( 'doing_it_wrong_trigger_error', true, $function_name, $message, $version ) ) {
  5811 		if ( function_exists( '__' ) ) {
  5992 		if ( function_exists( '__' ) ) {
  5812 			if ( $version ) {
  5993 			if ( $version ) {
  5813 				/* translators: %s: Version number. */
  5994 				/* translators: %s: Version number. */
  5814 				$version = sprintf( __( '(This message was added in version %s.)' ), $version );
  5995 				$version = sprintf( __( '(This message was added in version %s.)' ), $version );
  5815 			}
  5996 			}
  5816 
  5997 
  5817 			$message .= ' ' . sprintf(
  5998 			$message .= ' ' . sprintf(
  5818 				/* translators: %s: Documentation URL. */
  5999 				/* translators: %s: Documentation URL. */
  5819 				__( 'Please see <a href="%s">Debugging in WordPress</a> for more information.' ),
  6000 				__( 'Please see <a href="%s">Debugging in WordPress</a> for more information.' ),
  5820 				__( 'https://wordpress.org/support/article/debugging-in-wordpress/' )
  6001 				__( 'https://developer.wordpress.org/advanced-administration/debug/debug-wordpress/' )
  5821 			);
  6002 			);
  5822 
  6003 
  5823 			trigger_error(
  6004 			$message = sprintf(
  5824 				sprintf(
  6005 				/* translators: Developer debugging message. 1: PHP function name, 2: Explanatory message, 3: WordPress version number. */
  5825 					/* translators: Developer debugging message. 1: PHP function name, 2: Explanatory message, 3: WordPress version number. */
  6006 				__( 'Function %1$s was called <strong>incorrectly</strong>. %2$s %3$s' ),
  5826 					__( 'Function %1$s was called <strong>incorrectly</strong>. %2$s %3$s' ),
  6007 				$function_name,
  5827 					$function,
  6008 				$message,
  5828 					$message,
  6009 				$version
  5829 					$version
       
  5830 				),
       
  5831 				E_USER_NOTICE
       
  5832 			);
  6010 			);
  5833 		} else {
  6011 		} else {
  5834 			if ( $version ) {
  6012 			if ( $version ) {
  5835 				$version = sprintf( '(This message was added in version %s.)', $version );
  6013 				$version = sprintf( '(This message was added in version %s.)', $version );
  5836 			}
  6014 			}
  5837 
  6015 
  5838 			$message .= sprintf(
  6016 			$message .= sprintf(
  5839 				' Please see <a href="%s">Debugging in WordPress</a> for more information.',
  6017 				' Please see <a href="%s">Debugging in WordPress</a> for more information.',
  5840 				'https://wordpress.org/support/article/debugging-in-wordpress/'
  6018 				'https://developer.wordpress.org/advanced-administration/debug/debug-wordpress/'
  5841 			);
  6019 			);
  5842 
  6020 
  5843 			trigger_error(
  6021 			$message = sprintf(
  5844 				sprintf(
  6022 				'Function %1$s was called <strong>incorrectly</strong>. %2$s %3$s',
  5845 					'Function %1$s was called <strong>incorrectly</strong>. %2$s %3$s',
  6023 				$function_name,
  5846 					$function,
  6024 				$message,
  5847 					$message,
  6025 				$version
  5848 					$version
       
  5849 				),
       
  5850 				E_USER_NOTICE
       
  5851 			);
  6026 			);
  5852 		}
  6027 		}
  5853 	}
  6028 
  5854 }
  6029 		wp_trigger_error( '', $message );
  5855 
  6030 	}
  5856 /**
  6031 }
  5857  * Is the server running earlier than 1.5.0 version of lighttpd?
  6032 
       
  6033 /**
       
  6034  * Generates a user-level error/warning/notice/deprecation message.
       
  6035  *
       
  6036  * Generates the message when `WP_DEBUG` is true.
       
  6037  *
       
  6038  * @since 6.4.0
       
  6039  *
       
  6040  * @param string $function_name The function that triggered the error.
       
  6041  * @param string $message       The message explaining the error.
       
  6042  *                              The message can contain allowed HTML 'a' (with href), 'code',
       
  6043  *                              'br', 'em', and 'strong' tags and http or https protocols.
       
  6044  *                              If it contains other HTML tags or protocols, the message should be escaped
       
  6045  *                              before passing to this function to avoid being stripped {@see wp_kses()}.
       
  6046  * @param int    $error_level   Optional. The designated error type for this error.
       
  6047  *                              Only works with E_USER family of constants. Default E_USER_NOTICE.
       
  6048  */
       
  6049 function wp_trigger_error( $function_name, $message, $error_level = E_USER_NOTICE ) {
       
  6050 
       
  6051 	// Bail out if WP_DEBUG is not turned on.
       
  6052 	if ( ! WP_DEBUG ) {
       
  6053 		return;
       
  6054 	}
       
  6055 
       
  6056 	/**
       
  6057 	 * Fires when the given function triggers a user-level error/warning/notice/deprecation message.
       
  6058 	 *
       
  6059 	 * Can be used for debug backtracking.
       
  6060 	 *
       
  6061 	 * @since 6.4.0
       
  6062 	 *
       
  6063 	 * @param string $function_name The function that was called.
       
  6064 	 * @param string $message       A message explaining what has been done incorrectly.
       
  6065 	 * @param int    $error_level   The designated error type for this error.
       
  6066 	 */
       
  6067 	do_action( 'wp_trigger_error_run', $function_name, $message, $error_level );
       
  6068 
       
  6069 	if ( ! empty( $function_name ) ) {
       
  6070 		$message = sprintf( '%s(): %s', $function_name, $message );
       
  6071 	}
       
  6072 
       
  6073 	$message = wp_kses(
       
  6074 		$message,
       
  6075 		array(
       
  6076 			'a'      => array( 'href' => true ),
       
  6077 			'br'     => array(),
       
  6078 			'code'   => array(),
       
  6079 			'em'     => array(),
       
  6080 			'strong' => array(),
       
  6081 		),
       
  6082 		array( 'http', 'https' )
       
  6083 	);
       
  6084 
       
  6085 	trigger_error( $message, $error_level );
       
  6086 }
       
  6087 
       
  6088 /**
       
  6089  * Determines whether the server is running an earlier than 1.5.0 version of lighttpd.
  5858  *
  6090  *
  5859  * @since 2.5.0
  6091  * @since 2.5.0
  5860  *
  6092  *
  5861  * @return bool Whether the server is running lighttpd < 1.5.0.
  6093  * @return bool Whether the server is running lighttpd < 1.5.0.
  5862  */
  6094  */
  5863 function is_lighttpd_before_150() {
  6095 function is_lighttpd_before_150() {
  5864 	$server_parts    = explode( '/', isset( $_SERVER['SERVER_SOFTWARE'] ) ? $_SERVER['SERVER_SOFTWARE'] : '' );
  6096 	$server_parts    = explode( '/', isset( $_SERVER['SERVER_SOFTWARE'] ) ? $_SERVER['SERVER_SOFTWARE'] : '' );
  5865 	$server_parts[1] = isset( $server_parts[1] ) ? $server_parts[1] : '';
  6097 	$server_parts[1] = isset( $server_parts[1] ) ? $server_parts[1] : '';
  5866 
  6098 
  5867 	return ( 'lighttpd' === $server_parts[0] && -1 == version_compare( $server_parts[1], '1.5.0' ) );
  6099 	return ( 'lighttpd' === $server_parts[0] && -1 === version_compare( $server_parts[1], '1.5.0' ) );
  5868 }
  6100 }
  5869 
  6101 
  5870 /**
  6102 /**
  5871  * Does the specified module exist in the Apache config?
  6103  * Determines whether the specified module exist in the Apache config.
  5872  *
  6104  *
  5873  * @since 2.5.0
  6105  * @since 2.5.0
  5874  *
  6106  *
  5875  * @global bool $is_apache
  6107  * @global bool $is_apache
  5876  *
  6108  *
  5877  * @param string $mod     The module, e.g. mod_rewrite.
  6109  * @param string $mod           The module, e.g. mod_rewrite.
  5878  * @param bool   $default Optional. The default return value if the module is not found. Default false.
  6110  * @param bool   $default_value Optional. The default return value if the module is not found. Default false.
  5879  * @return bool Whether the specified module is loaded.
  6111  * @return bool Whether the specified module is loaded.
  5880  */
  6112  */
  5881 function apache_mod_loaded( $mod, $default = false ) {
  6113 function apache_mod_loaded( $mod, $default_value = false ) {
  5882 	global $is_apache;
  6114 	global $is_apache;
  5883 
  6115 
  5884 	if ( ! $is_apache ) {
  6116 	if ( ! $is_apache ) {
  5885 		return false;
  6117 		return false;
  5886 	}
  6118 	}
  5887 
  6119 
       
  6120 	$loaded_mods = array();
       
  6121 
  5888 	if ( function_exists( 'apache_get_modules' ) ) {
  6122 	if ( function_exists( 'apache_get_modules' ) ) {
  5889 		$mods = apache_get_modules();
  6123 		$loaded_mods = apache_get_modules();
  5890 		if ( in_array( $mod, $mods, true ) ) {
  6124 
       
  6125 		if ( in_array( $mod, $loaded_mods, true ) ) {
  5891 			return true;
  6126 			return true;
  5892 		}
  6127 		}
  5893 	} elseif ( function_exists( 'phpinfo' ) && false === strpos( ini_get( 'disable_functions' ), 'phpinfo' ) ) {
  6128 	}
  5894 			ob_start();
  6129 
  5895 			phpinfo( 8 );
  6130 	if ( empty( $loaded_mods )
  5896 			$phpinfo = ob_get_clean();
  6131 		&& function_exists( 'phpinfo' )
  5897 		if ( false !== strpos( $phpinfo, $mod ) ) {
  6132 		&& ! str_contains( ini_get( 'disable_functions' ), 'phpinfo' )
       
  6133 	) {
       
  6134 		ob_start();
       
  6135 		phpinfo( INFO_MODULES );
       
  6136 		$phpinfo = ob_get_clean();
       
  6137 
       
  6138 		if ( str_contains( $phpinfo, $mod ) ) {
  5898 			return true;
  6139 			return true;
  5899 		}
  6140 		}
  5900 	}
  6141 	}
  5901 
  6142 
  5902 	return $default;
  6143 	return $default_value;
  5903 }
  6144 }
  5904 
  6145 
  5905 /**
  6146 /**
  5906  * Check if IIS 7+ supports pretty permalinks.
  6147  * Checks if IIS 7+ supports pretty permalinks.
  5907  *
  6148  *
  5908  * @since 2.8.0
  6149  * @since 2.8.0
  5909  *
  6150  *
  5910  * @global bool $is_iis7
  6151  * @global bool $is_iis7
  5911  *
  6152  *
  5918 	if ( $is_iis7 ) {
  6159 	if ( $is_iis7 ) {
  5919 		/* First we check if the DOMDocument class exists. If it does not exist, then we cannot
  6160 		/* First we check if the DOMDocument class exists. If it does not exist, then we cannot
  5920 		 * easily update the xml configuration file, hence we just bail out and tell user that
  6161 		 * easily update the xml configuration file, hence we just bail out and tell user that
  5921 		 * pretty permalinks cannot be used.
  6162 		 * pretty permalinks cannot be used.
  5922 		 *
  6163 		 *
  5923 		 * Next we check if the URL Rewrite Module 1.1 is loaded and enabled for the web site. When
  6164 		 * Next we check if the URL Rewrite Module 1.1 is loaded and enabled for the website. When
  5924 		 * URL Rewrite 1.1 is loaded it always sets a server variable called 'IIS_UrlRewriteModule'.
  6165 		 * URL Rewrite 1.1 is loaded it always sets a server variable called 'IIS_UrlRewriteModule'.
  5925 		 * Lastly we make sure that PHP is running via FastCGI. This is important because if it runs
  6166 		 * Lastly we make sure that PHP is running via FastCGI. This is important because if it runs
  5926 		 * via ISAPI then pretty permalinks will not work.
  6167 		 * via ISAPI then pretty permalinks will not work.
  5927 		 */
  6168 		 */
  5928 		$supports_permalinks = class_exists( 'DOMDocument', false ) && isset( $_SERVER['IIS_UrlRewriteModule'] ) && ( 'cgi-fcgi' === PHP_SAPI );
  6169 		$supports_permalinks = class_exists( 'DOMDocument', false ) && isset( $_SERVER['IIS_UrlRewriteModule'] ) && ( 'cgi-fcgi' === PHP_SAPI );
  5948  * A return value of `3` means the file is not in the allowed files list.
  6189  * A return value of `3` means the file is not in the allowed files list.
  5949  *
  6190  *
  5950  * @since 1.2.0
  6191  * @since 1.2.0
  5951  *
  6192  *
  5952  * @param string   $file          File path.
  6193  * @param string   $file          File path.
  5953  * @param string[] $allowed_files Optional. Array of allowed files.
  6194  * @param string[] $allowed_files Optional. Array of allowed files. Default empty array.
  5954  * @return int 0 means nothing is wrong, greater than 0 means something was wrong.
  6195  * @return int 0 means nothing is wrong, greater than 0 means something was wrong.
  5955  */
  6196  */
  5956 function validate_file( $file, $allowed_files = array() ) {
  6197 function validate_file( $file, $allowed_files = array() ) {
  5957 	if ( ! is_scalar( $file ) || '' === $file ) {
  6198 	if ( ! is_scalar( $file ) || '' === $file ) {
  5958 		return 0;
  6199 		return 0;
  5959 	}
  6200 	}
  5960 
  6201 
       
  6202 	// Normalize path for Windows servers.
       
  6203 	$file = wp_normalize_path( $file );
       
  6204 	// Normalize path for $allowed_files as well so it's an apples to apples comparison.
       
  6205 	$allowed_files = array_map( 'wp_normalize_path', $allowed_files );
       
  6206 
  5961 	// `../` on its own is not allowed:
  6207 	// `../` on its own is not allowed:
  5962 	if ( '../' === $file ) {
  6208 	if ( '../' === $file ) {
  5963 		return 1;
  6209 		return 1;
  5964 	}
  6210 	}
  5965 
  6211 
  5967 	if ( preg_match_all( '#\.\./#', $file, $matches, PREG_SET_ORDER ) && ( count( $matches ) > 1 ) ) {
  6213 	if ( preg_match_all( '#\.\./#', $file, $matches, PREG_SET_ORDER ) && ( count( $matches ) > 1 ) ) {
  5968 		return 1;
  6214 		return 1;
  5969 	}
  6215 	}
  5970 
  6216 
  5971 	// `../` which does not occur at the end of the path is not allowed:
  6217 	// `../` which does not occur at the end of the path is not allowed:
  5972 	if ( false !== strpos( $file, '../' ) && '../' !== mb_substr( $file, -3, 3 ) ) {
  6218 	if ( str_contains( $file, '../' ) && '../' !== mb_substr( $file, -3, 3 ) ) {
  5973 		return 1;
  6219 		return 1;
  5974 	}
  6220 	}
  5975 
  6221 
  5976 	// Files not in the allowed file list are not allowed:
  6222 	// Files not in the allowed file list are not allowed:
  5977 	if ( ! empty( $allowed_files ) && ! in_array( $file, $allowed_files, true ) ) {
  6223 	if ( ! empty( $allowed_files ) && ! in_array( $file, $allowed_files, true ) ) {
  5985 
  6231 
  5986 	return 0;
  6232 	return 0;
  5987 }
  6233 }
  5988 
  6234 
  5989 /**
  6235 /**
  5990  * Whether to force SSL used for the Administration Screens.
  6236  * Determines whether to force SSL used for the Administration Screens.
  5991  *
  6237  *
  5992  * @since 2.6.0
  6238  * @since 2.6.0
  5993  *
  6239  *
  5994  * @param string|bool $force Optional. Whether to force SSL in admin screens. Default null.
  6240  * @param string|bool $force Optional. Whether to force SSL in admin screens. Default null.
  5995  * @return bool True if forced, false if not forced.
  6241  * @return bool True if forced, false if not forced.
  6005 
  6251 
  6006 	return $forced;
  6252 	return $forced;
  6007 }
  6253 }
  6008 
  6254 
  6009 /**
  6255 /**
  6010  * Guess the URL for the site.
  6256  * Guesses the URL for the site.
  6011  *
  6257  *
  6012  * Will remove wp-admin links to retrieve only return URLs not in the wp-admin
  6258  * Will remove wp-admin links to retrieve only return URLs not in the wp-admin
  6013  * directory.
  6259  * directory.
  6014  *
  6260  *
  6015  * @since 2.6.0
  6261  * @since 2.6.0
  6022 	} else {
  6268 	} else {
  6023 		$abspath_fix         = str_replace( '\\', '/', ABSPATH );
  6269 		$abspath_fix         = str_replace( '\\', '/', ABSPATH );
  6024 		$script_filename_dir = dirname( $_SERVER['SCRIPT_FILENAME'] );
  6270 		$script_filename_dir = dirname( $_SERVER['SCRIPT_FILENAME'] );
  6025 
  6271 
  6026 		// The request is for the admin.
  6272 		// The request is for the admin.
  6027 		if ( strpos( $_SERVER['REQUEST_URI'], 'wp-admin' ) !== false || strpos( $_SERVER['REQUEST_URI'], 'wp-login.php' ) !== false ) {
  6273 		if ( str_contains( $_SERVER['REQUEST_URI'], 'wp-admin' ) || str_contains( $_SERVER['REQUEST_URI'], 'wp-login.php' ) ) {
  6028 			$path = preg_replace( '#/(wp-admin/.*|wp-login.php)#i', '', $_SERVER['REQUEST_URI'] );
  6274 			$path = preg_replace( '#/(wp-admin/?.*|wp-login\.php.*)#i', '', $_SERVER['REQUEST_URI'] );
  6029 
  6275 
  6030 			// The request is for a file in ABSPATH.
  6276 			// The request is for a file in ABSPATH.
  6031 		} elseif ( $script_filename_dir . '/' === $abspath_fix ) {
  6277 		} elseif ( $script_filename_dir . '/' === $abspath_fix ) {
  6032 			// Strip off any file/query params in the path.
  6278 			// Strip off any file/query params in the path.
  6033 			$path = preg_replace( '#/[^/]*$#i', '', $_SERVER['PHP_SELF'] );
  6279 			$path = preg_replace( '#/[^/]*$#i', '', $_SERVER['PHP_SELF'] );
  6034 
  6280 
  6035 		} else {
  6281 		} else {
  6036 			if ( false !== strpos( $_SERVER['SCRIPT_FILENAME'], $abspath_fix ) ) {
  6282 			if ( str_contains( $_SERVER['SCRIPT_FILENAME'], $abspath_fix ) ) {
  6037 				// Request is hitting a file inside ABSPATH.
  6283 				// Request is hitting a file inside ABSPATH.
  6038 				$directory = str_replace( ABSPATH, '', $script_filename_dir );
  6284 				$directory = str_replace( ABSPATH, '', $script_filename_dir );
  6039 				// Strip off the subdirectory, and any file/query params.
  6285 				// Strip off the subdirectory, and any file/query params.
  6040 				$path = preg_replace( '#/' . preg_quote( $directory, '#' ) . '/[^/]*$#i', '', $_SERVER['REQUEST_URI'] );
  6286 				$path = preg_replace( '#/' . preg_quote( $directory, '#' ) . '/[^/]*$#i', '', $_SERVER['REQUEST_URI'] );
  6041 			} elseif ( false !== strpos( $abspath_fix, $script_filename_dir ) ) {
  6287 			} elseif ( str_contains( $abspath_fix, $script_filename_dir ) ) {
  6042 				// Request is hitting a file above ABSPATH.
  6288 				// Request is hitting a file above ABSPATH.
  6043 				$subdirectory = substr( $abspath_fix, strpos( $abspath_fix, $script_filename_dir ) + strlen( $script_filename_dir ) );
  6289 				$subdirectory = substr( $abspath_fix, strpos( $abspath_fix, $script_filename_dir ) + strlen( $script_filename_dir ) );
  6044 				// Strip off any file/query params from the path, appending the subdirectory to the installation.
  6290 				// Strip off any file/query params from the path, appending the subdirectory to the installation.
  6045 				$path = preg_replace( '#/[^/]*$#i', '', $_SERVER['REQUEST_URI'] ) . $subdirectory;
  6291 				$path = preg_replace( '#/[^/]*$#i', '', $_SERVER['REQUEST_URI'] ) . $subdirectory;
  6046 			} else {
  6292 			} else {
  6054 
  6300 
  6055 	return rtrim( $url, '/' );
  6301 	return rtrim( $url, '/' );
  6056 }
  6302 }
  6057 
  6303 
  6058 /**
  6304 /**
  6059  * Temporarily suspend cache additions.
  6305  * Temporarily suspends cache additions.
  6060  *
  6306  *
  6061  * Stops more data being added to the cache, but still allows cache retrieval.
  6307  * Stops more data being added to the cache, but still allows cache retrieval.
  6062  * This is useful for actions, such as imports, when a lot of data would otherwise
  6308  * This is useful for actions, such as imports, when a lot of data would otherwise
  6063  * be almost uselessly added to the cache.
  6309  * be almost uselessly added to the cache.
  6064  *
  6310  *
  6066  * function again if you wish to re-enable cache adds earlier.
  6312  * function again if you wish to re-enable cache adds earlier.
  6067  *
  6313  *
  6068  * @since 3.3.0
  6314  * @since 3.3.0
  6069  *
  6315  *
  6070  * @param bool $suspend Optional. Suspends additions if true, re-enables them if false.
  6316  * @param bool $suspend Optional. Suspends additions if true, re-enables them if false.
  6071  * @return bool The current suspend setting
  6317  *                      Defaults to not changing the current setting.
       
  6318  * @return bool The current suspend setting.
  6072  */
  6319  */
  6073 function wp_suspend_cache_addition( $suspend = null ) {
  6320 function wp_suspend_cache_addition( $suspend = null ) {
  6074 	static $_suspend = false;
  6321 	static $_suspend = false;
  6075 
  6322 
  6076 	if ( is_bool( $suspend ) ) {
  6323 	if ( is_bool( $suspend ) ) {
  6079 
  6326 
  6080 	return $_suspend;
  6327 	return $_suspend;
  6081 }
  6328 }
  6082 
  6329 
  6083 /**
  6330 /**
  6084  * Suspend cache invalidation.
  6331  * Suspends cache invalidation.
  6085  *
  6332  *
  6086  * Turns cache invalidation on and off. Useful during imports where you don't want to do
  6333  * Turns cache invalidation on and off. Useful during imports where you don't want to do
  6087  * invalidations every time a post is inserted. Callers must be sure that what they are
  6334  * invalidations every time a post is inserted. Callers must be sure that what they are
  6088  * doing won't lead to an inconsistent cache when invalidation is suspended.
  6335  * doing won't lead to an inconsistent cache when invalidation is suspended.
  6089  *
  6336  *
  6101 	$_wp_suspend_cache_invalidation = $suspend;
  6348 	$_wp_suspend_cache_invalidation = $suspend;
  6102 	return $current_suspend;
  6349 	return $current_suspend;
  6103 }
  6350 }
  6104 
  6351 
  6105 /**
  6352 /**
  6106  * Determine whether a site is the main site of the current network.
  6353  * Determines whether a site is the main site of the current network.
  6107  *
  6354  *
  6108  * @since 3.0.0
  6355  * @since 3.0.0
  6109  * @since 4.9.0 The `$network_id` parameter was added.
  6356  * @since 4.9.0 The `$network_id` parameter was added.
  6110  *
  6357  *
  6111  * @param int $site_id    Optional. Site ID to test. Defaults to current site.
  6358  * @param int $site_id    Optional. Site ID to test. Defaults to current site.
  6149 
  6396 
  6150 	return $network->site_id;
  6397 	return $network->site_id;
  6151 }
  6398 }
  6152 
  6399 
  6153 /**
  6400 /**
  6154  * Determine whether a network is the main network of the Multisite installation.
  6401  * Determines whether a network is the main network of the Multisite installation.
  6155  *
  6402  *
  6156  * @since 3.7.0
  6403  * @since 3.7.0
  6157  *
  6404  *
  6158  * @param int $network_id Optional. Network ID to test. Defaults to current network.
  6405  * @param int $network_id Optional. Network ID to test. Defaults to current network.
  6159  * @return bool True if $network_id is the main network, or if not running Multisite.
  6406  * @return bool True if $network_id is the main network, or if not running Multisite.
  6171 
  6418 
  6172 	return ( get_main_network_id() === $network_id );
  6419 	return ( get_main_network_id() === $network_id );
  6173 }
  6420 }
  6174 
  6421 
  6175 /**
  6422 /**
  6176  * Get the main network ID.
  6423  * Gets the main network ID.
  6177  *
  6424  *
  6178  * @since 4.3.0
  6425  * @since 4.3.0
  6179  *
  6426  *
  6180  * @return int The ID of the main network.
  6427  * @return int The ID of the main network.
  6181  */
  6428  */
  6210 	 */
  6457 	 */
  6211 	return (int) apply_filters( 'get_main_network_id', $main_network_id );
  6458 	return (int) apply_filters( 'get_main_network_id', $main_network_id );
  6212 }
  6459 }
  6213 
  6460 
  6214 /**
  6461 /**
  6215  * Determine whether global terms are enabled.
       
  6216  *
       
  6217  * @since 3.0.0
       
  6218  *
       
  6219  * @return bool True if multisite and global terms enabled.
       
  6220  */
       
  6221 function global_terms_enabled() {
       
  6222 	if ( ! is_multisite() ) {
       
  6223 		return false;
       
  6224 	}
       
  6225 
       
  6226 	static $global_terms = null;
       
  6227 	if ( is_null( $global_terms ) ) {
       
  6228 
       
  6229 		/**
       
  6230 		 * Filters whether global terms are enabled.
       
  6231 		 *
       
  6232 		 * Returning a non-null value from the filter will effectively short-circuit the function
       
  6233 		 * and return the value of the 'global_terms_enabled' site option instead.
       
  6234 		 *
       
  6235 		 * @since 3.0.0
       
  6236 		 *
       
  6237 		 * @param null $enabled Whether global terms are enabled.
       
  6238 		 */
       
  6239 		$filter = apply_filters( 'global_terms_enabled', null );
       
  6240 		if ( ! is_null( $filter ) ) {
       
  6241 			$global_terms = (bool) $filter;
       
  6242 		} else {
       
  6243 			$global_terms = (bool) get_site_option( 'global_terms_enabled', false );
       
  6244 		}
       
  6245 	}
       
  6246 	return $global_terms;
       
  6247 }
       
  6248 
       
  6249 /**
       
  6250  * Determines whether site meta is enabled.
  6462  * Determines whether site meta is enabled.
  6251  *
  6463  *
  6252  * This function checks whether the 'blogmeta' database table exists. The result is saved as
  6464  * This function checks whether the 'blogmeta' database table exists. The result is saved as
  6253  * a setting for the main network, making it essentially a global setting. Subsequent requests
  6465  * a setting for the main network, making it essentially a global setting. Subsequent requests
  6254  * will refer to this setting instead of running the query.
  6466  * will refer to this setting instead of running the query.
  6277 
  6489 
  6278 	return (bool) $supported;
  6490 	return (bool) $supported;
  6279 }
  6491 }
  6280 
  6492 
  6281 /**
  6493 /**
  6282  * gmt_offset modification for smart timezone handling.
  6494  * Modifies gmt_offset for smart timezone handling.
  6283  *
  6495  *
  6284  * Overrides the gmt_offset option if we have a timezone_string available.
  6496  * Overrides the gmt_offset option if we have a timezone_string available.
  6285  *
  6497  *
  6286  * @since 2.8.0
  6498  * @since 2.8.0
  6287  *
  6499  *
  6296 	$timezone_object = timezone_open( $timezone_string );
  6508 	$timezone_object = timezone_open( $timezone_string );
  6297 	$datetime_object = date_create();
  6509 	$datetime_object = date_create();
  6298 	if ( false === $timezone_object || false === $datetime_object ) {
  6510 	if ( false === $timezone_object || false === $datetime_object ) {
  6299 		return false;
  6511 		return false;
  6300 	}
  6512 	}
       
  6513 
  6301 	return round( timezone_offset_get( $timezone_object, $datetime_object ) / HOUR_IN_SECONDS, 2 );
  6514 	return round( timezone_offset_get( $timezone_object, $datetime_object ) / HOUR_IN_SECONDS, 2 );
  6302 }
  6515 }
  6303 
  6516 
  6304 /**
  6517 /**
  6305  * Sort-helper for timezones.
  6518  * Sort-helper for timezones.
  6313  */
  6526  */
  6314 function _wp_timezone_choice_usort_callback( $a, $b ) {
  6527 function _wp_timezone_choice_usort_callback( $a, $b ) {
  6315 	// Don't use translated versions of Etc.
  6528 	// Don't use translated versions of Etc.
  6316 	if ( 'Etc' === $a['continent'] && 'Etc' === $b['continent'] ) {
  6529 	if ( 'Etc' === $a['continent'] && 'Etc' === $b['continent'] ) {
  6317 		// Make the order of these more like the old dropdown.
  6530 		// Make the order of these more like the old dropdown.
  6318 		if ( 'GMT+' === substr( $a['city'], 0, 4 ) && 'GMT+' === substr( $b['city'], 0, 4 ) ) {
  6531 		if ( str_starts_with( $a['city'], 'GMT+' ) && str_starts_with( $b['city'], 'GMT+' ) ) {
  6319 			return -1 * ( strnatcasecmp( $a['city'], $b['city'] ) );
  6532 			return -1 * ( strnatcasecmp( $a['city'], $b['city'] ) );
  6320 		}
  6533 		}
       
  6534 
  6321 		if ( 'UTC' === $a['city'] ) {
  6535 		if ( 'UTC' === $a['city'] ) {
  6322 			if ( 'GMT+' === substr( $b['city'], 0, 4 ) ) {
  6536 			if ( str_starts_with( $b['city'], 'GMT+' ) ) {
  6323 				return 1;
  6537 				return 1;
  6324 			}
  6538 			}
       
  6539 
  6325 			return -1;
  6540 			return -1;
  6326 		}
  6541 		}
       
  6542 
  6327 		if ( 'UTC' === $b['city'] ) {
  6543 		if ( 'UTC' === $b['city'] ) {
  6328 			if ( 'GMT+' === substr( $a['city'], 0, 4 ) ) {
  6544 			if ( str_starts_with( $a['city'], 'GMT+' ) ) {
  6329 				return -1;
  6545 				return -1;
  6330 			}
  6546 			}
       
  6547 
  6331 			return 1;
  6548 			return 1;
  6332 		}
  6549 		}
       
  6550 
  6333 		return strnatcasecmp( $a['city'], $b['city'] );
  6551 		return strnatcasecmp( $a['city'], $b['city'] );
  6334 	}
  6552 	}
  6335 	if ( $a['t_continent'] == $b['t_continent'] ) {
  6553 
  6336 		if ( $a['t_city'] == $b['t_city'] ) {
  6554 	if ( $a['t_continent'] === $b['t_continent'] ) {
       
  6555 		if ( $a['t_city'] === $b['t_city'] ) {
  6337 			return strnatcasecmp( $a['t_subcity'], $b['t_subcity'] );
  6556 			return strnatcasecmp( $a['t_subcity'], $b['t_subcity'] );
  6338 		}
  6557 		}
       
  6558 
  6339 		return strnatcasecmp( $a['t_city'], $b['t_city'] );
  6559 		return strnatcasecmp( $a['t_city'], $b['t_city'] );
  6340 	} else {
  6560 	} else {
  6341 		// Force Etc to the bottom of the list.
  6561 		// Force Etc to the bottom of the list.
  6342 		if ( 'Etc' === $a['continent'] ) {
  6562 		if ( 'Etc' === $a['continent'] ) {
  6343 			return 1;
  6563 			return 1;
  6344 		}
  6564 		}
       
  6565 
  6345 		if ( 'Etc' === $b['continent'] ) {
  6566 		if ( 'Etc' === $b['continent'] ) {
  6346 			return -1;
  6567 			return -1;
  6347 		}
  6568 		}
       
  6569 
  6348 		return strnatcasecmp( $a['t_continent'], $b['t_continent'] );
  6570 		return strnatcasecmp( $a['t_continent'], $b['t_continent'] );
  6349 	}
  6571 	}
  6350 }
  6572 }
  6351 
  6573 
  6352 /**
  6574 /**
  6366 
  6588 
  6367 	// Load translations for continents and cities.
  6589 	// Load translations for continents and cities.
  6368 	if ( ! $mo_loaded || $locale !== $locale_loaded ) {
  6590 	if ( ! $mo_loaded || $locale !== $locale_loaded ) {
  6369 		$locale_loaded = $locale ? $locale : get_locale();
  6591 		$locale_loaded = $locale ? $locale : get_locale();
  6370 		$mofile        = WP_LANG_DIR . '/continents-cities-' . $locale_loaded . '.mo';
  6592 		$mofile        = WP_LANG_DIR . '/continents-cities-' . $locale_loaded . '.mo';
  6371 		unload_textdomain( 'continents-cities' );
  6593 		unload_textdomain( 'continents-cities', true );
  6372 		load_textdomain( 'continents-cities', $mofile );
  6594 		load_textdomain( 'continents-cities', $mofile, $locale_loaded );
  6373 		$mo_loaded = true;
  6595 		$mo_loaded = true;
  6374 	}
  6596 	}
  6375 
  6597 
  6376 	$zonen = array();
  6598 	$tz_identifiers = timezone_identifiers_list();
  6377 	foreach ( timezone_identifiers_list() as $zone ) {
  6599 	$zonen          = array();
       
  6600 
       
  6601 	foreach ( $tz_identifiers as $zone ) {
  6378 		$zone = explode( '/', $zone );
  6602 		$zone = explode( '/', $zone );
  6379 		if ( ! in_array( $zone[0], $continents, true ) ) {
  6603 		if ( ! in_array( $zone[0], $continents, true ) ) {
  6380 			continue;
  6604 			continue;
  6381 		}
  6605 		}
  6382 
  6606 
  6405 
  6629 
  6406 	$structure = array();
  6630 	$structure = array();
  6407 
  6631 
  6408 	if ( empty( $selected_zone ) ) {
  6632 	if ( empty( $selected_zone ) ) {
  6409 		$structure[] = '<option selected="selected" value="">' . __( 'Select a city' ) . '</option>';
  6633 		$structure[] = '<option selected="selected" value="">' . __( 'Select a city' ) . '</option>';
       
  6634 	}
       
  6635 
       
  6636 	// If this is a deprecated, but valid, timezone string, display it at the top of the list as-is.
       
  6637 	if ( in_array( $selected_zone, $tz_identifiers, true ) === false
       
  6638 		&& in_array( $selected_zone, timezone_identifiers_list( DateTimeZone::ALL_WITH_BC ), true )
       
  6639 	) {
       
  6640 		$structure[] = '<option selected="selected" value="' . esc_attr( $selected_zone ) . '">' . esc_html( $selected_zone ) . '</option>';
  6410 	}
  6641 	}
  6411 
  6642 
  6412 	foreach ( $zonen as $key => $zone ) {
  6643 	foreach ( $zonen as $key => $zone ) {
  6413 		// Build value in an array to join later.
  6644 		// Build value in an array to join later.
  6414 		$value = array( $zone['continent'] );
  6645 		$value = array( $zone['continent'] );
  6540 
  6771 
  6541 	return implode( "\n", $structure );
  6772 	return implode( "\n", $structure );
  6542 }
  6773 }
  6543 
  6774 
  6544 /**
  6775 /**
  6545  * Strip close comment and close php tags from file headers used by WP.
  6776  * Strips close comment and close php tags from file headers used by WP.
  6546  *
  6777  *
  6547  * @since 2.8.0
  6778  * @since 2.8.0
  6548  * @access private
  6779  * @access private
  6549  *
  6780  *
  6550  * @see https://core.trac.wordpress.org/ticket/8497
  6781  * @see https://core.trac.wordpress.org/ticket/8497
  6555 function _cleanup_header_comment( $str ) {
  6786 function _cleanup_header_comment( $str ) {
  6556 	return trim( preg_replace( '/\s*(?:\*\/|\?>).*/', '', $str ) );
  6787 	return trim( preg_replace( '/\s*(?:\*\/|\?>).*/', '', $str ) );
  6557 }
  6788 }
  6558 
  6789 
  6559 /**
  6790 /**
  6560  * Permanently delete comments or posts of any type that have held a status
  6791  * Permanently deletes comments or posts of any type that have held a status
  6561  * of 'trash' for the number of days defined in EMPTY_TRASH_DAYS.
  6792  * of 'trash' for the number of days defined in EMPTY_TRASH_DAYS.
  6562  *
  6793  *
  6563  * The default value of `EMPTY_TRASH_DAYS` is 30 (days).
  6794  * The default value of `EMPTY_TRASH_DAYS` is 30 (days).
  6564  *
  6795  *
  6565  * @since 2.9.0
  6796  * @since 2.9.0
  6607 		}
  6838 		}
  6608 	}
  6839 	}
  6609 }
  6840 }
  6610 
  6841 
  6611 /**
  6842 /**
  6612  * Retrieve metadata from a file.
  6843  * Retrieves metadata from a file.
  6613  *
  6844  *
  6614  * Searches for metadata in the first 8 KB of a file, such as a plugin or theme.
  6845  * Searches for metadata in the first 8 KB of a file, such as a plugin or theme.
  6615  * Each piece of metadata must be on its own line. Fields can not span multiple
  6846  * Each piece of metadata must be on its own line. Fields can not span multiple
  6616  * lines, the value will get cut at the end of the first line.
  6847  * lines, the value will get cut at the end of the first line.
  6617  *
  6848  *
  6623  * @since 2.9.0
  6854  * @since 2.9.0
  6624  *
  6855  *
  6625  * @param string $file            Absolute path to the file.
  6856  * @param string $file            Absolute path to the file.
  6626  * @param array  $default_headers List of headers, in the format `array( 'HeaderKey' => 'Header Name' )`.
  6857  * @param array  $default_headers List of headers, in the format `array( 'HeaderKey' => 'Header Name' )`.
  6627  * @param string $context         Optional. If specified adds filter hook {@see 'extra_$context_headers'}.
  6858  * @param string $context         Optional. If specified adds filter hook {@see 'extra_$context_headers'}.
  6628  *                                Default empty.
  6859  *                                Default empty string.
  6629  * @return string[] Array of file header values keyed by header name.
  6860  * @return string[] Array of file header values keyed by header name.
  6630  */
  6861  */
  6631 function get_file_data( $file, $default_headers, $context = '' ) {
  6862 function get_file_data( $file, $default_headers, $context = '' ) {
  6632 	// Pull only the first 8 KB of the file in.
  6863 	// Pull only the first 8 KB of the file in.
  6633 	$file_data = file_get_contents( $file, false, null, 0, 8 * KB_IN_BYTES );
  6864 	$file_data = file_get_contents( $file, false, null, 0, 8 * KB_IN_BYTES );
  6751 function __return_empty_string() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionDoubleUnderscore,PHPCompatibility.FunctionNameRestrictions.ReservedFunctionNames.FunctionDoubleUnderscore
  6982 function __return_empty_string() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionDoubleUnderscore,PHPCompatibility.FunctionNameRestrictions.ReservedFunctionNames.FunctionDoubleUnderscore
  6752 	return '';
  6983 	return '';
  6753 }
  6984 }
  6754 
  6985 
  6755 /**
  6986 /**
  6756  * Send a HTTP header to disable content type sniffing in browsers which support it.
  6987  * Sends a HTTP header to disable content type sniffing in browsers which support it.
  6757  *
  6988  *
  6758  * @since 3.0.0
  6989  * @since 3.0.0
  6759  *
  6990  *
  6760  * @see https://blogs.msdn.com/ie/archive/2008/07/02/ie8-security-part-v-comprehensive-protection.aspx
  6991  * @see https://blogs.msdn.com/ie/archive/2008/07/02/ie8-security-part-v-comprehensive-protection.aspx
  6761  * @see https://src.chromium.org/viewvc/chrome?view=rev&revision=6985
  6992  * @see https://src.chromium.org/viewvc/chrome?view=rev&revision=6985
  6763 function send_nosniff_header() {
  6994 function send_nosniff_header() {
  6764 	header( 'X-Content-Type-Options: nosniff' );
  6995 	header( 'X-Content-Type-Options: nosniff' );
  6765 }
  6996 }
  6766 
  6997 
  6767 /**
  6998 /**
  6768  * Return a MySQL expression for selecting the week number based on the start_of_week option.
  6999  * Returns a MySQL expression for selecting the week number based on the start_of_week option.
  6769  *
  7000  *
  6770  * @ignore
  7001  * @ignore
  6771  * @since 3.0.0
  7002  * @since 3.0.0
  6772  *
  7003  *
  6773  * @param string $column Database column.
  7004  * @param string $column Database column.
  6789 			return "WEEK( $column, 0 )";
  7020 			return "WEEK( $column, 0 )";
  6790 	}
  7021 	}
  6791 }
  7022 }
  6792 
  7023 
  6793 /**
  7024 /**
  6794  * Find hierarchy loops using a callback function that maps object IDs to parent IDs.
  7025  * Finds hierarchy loops using a callback function that maps object IDs to parent IDs.
  6795  *
  7026  *
  6796  * @since 3.1.0
  7027  * @since 3.1.0
  6797  * @access private
  7028  * @access private
  6798  *
  7029  *
  6799  * @param callable $callback      Function that accepts ( ID, $callback_args ) and outputs parent_ID.
  7030  * @param callable $callback      Function that accepts ( ID, $callback_args ) and outputs parent_ID.
  6800  * @param int      $start         The ID to start the loop check at.
  7031  * @param int      $start         The ID to start the loop check at.
  6801  * @param int      $start_parent  The parent_ID of $start to use instead of calling $callback( $start ).
  7032  * @param int      $start_parent  The parent_ID of $start to use instead of calling $callback( $start ).
  6802  *                                Use null to always use $callback
  7033  *                                Use null to always use $callback.
  6803  * @param array    $callback_args Optional. Additional arguments to send to $callback.
  7034  * @param array    $callback_args Optional. Additional arguments to send to $callback. Default empty array.
  6804  * @return array IDs of all members of loop.
  7035  * @return array IDs of all members of loop.
  6805  */
  7036  */
  6806 function wp_find_hierarchy_loop( $callback, $start, $start_parent, $callback_args = array() ) {
  7037 function wp_find_hierarchy_loop( $callback, $start, $start_parent, $callback_args = array() ) {
  6807 	$override = is_null( $start_parent ) ? array() : array( $start => $start_parent );
  7038 	$override = is_null( $start_parent ) ? array() : array( $start => $start_parent );
  6808 
  7039 
  6813 
  7044 
  6814 	return wp_find_hierarchy_loop_tortoise_hare( $callback, $arbitrary_loop_member, $override, $callback_args, true );
  7045 	return wp_find_hierarchy_loop_tortoise_hare( $callback, $arbitrary_loop_member, $override, $callback_args, true );
  6815 }
  7046 }
  6816 
  7047 
  6817 /**
  7048 /**
  6818  * Use the "The Tortoise and the Hare" algorithm to detect loops.
  7049  * Uses the "The Tortoise and the Hare" algorithm to detect loops.
  6819  *
  7050  *
  6820  * For every step of the algorithm, the hare takes two steps and the tortoise one.
  7051  * For every step of the algorithm, the hare takes two steps and the tortoise one.
  6821  * If the hare ever laps the tortoise, there must be a loop.
  7052  * If the hare ever laps the tortoise, there must be a loop.
  6822  *
  7053  *
  6823  * @since 3.1.0
  7054  * @since 3.1.0
  6838 	$tortoise        = $start;
  7069 	$tortoise        = $start;
  6839 	$hare            = $start;
  7070 	$hare            = $start;
  6840 	$evanescent_hare = $start;
  7071 	$evanescent_hare = $start;
  6841 	$return          = array();
  7072 	$return          = array();
  6842 
  7073 
  6843 	// Set evanescent_hare to one past hare.
  7074 	// Set evanescent_hare to one past hare. Increment hare two steps.
  6844 	// Increment hare two steps.
       
  6845 	while (
  7075 	while (
  6846 		$tortoise
  7076 		$tortoise
  6847 	&&
  7077 	&&
  6848 		( $evanescent_hare = isset( $override[ $hare ] ) ? $override[ $hare ] : call_user_func_array( $callback, array_merge( array( $hare ), $callback_args ) ) )
  7078 		( $evanescent_hare = isset( $override[ $hare ] ) ? $override[ $hare ] : call_user_func_array( $callback, array_merge( array( $hare ), $callback_args ) ) )
  6849 	&&
  7079 	&&
  6854 			$return[ $evanescent_hare ] = true;
  7084 			$return[ $evanescent_hare ] = true;
  6855 			$return[ $hare ]            = true;
  7085 			$return[ $hare ]            = true;
  6856 		}
  7086 		}
  6857 
  7087 
  6858 		// Tortoise got lapped - must be a loop.
  7088 		// Tortoise got lapped - must be a loop.
  6859 		if ( $tortoise == $evanescent_hare || $tortoise == $hare ) {
  7089 		if ( $tortoise === $evanescent_hare || $tortoise === $hare ) {
  6860 			return $_return_loop ? $return : $tortoise;
  7090 			return $_return_loop ? $return : $tortoise;
  6861 		}
  7091 		}
  6862 
  7092 
  6863 		// Increment tortoise by one step.
  7093 		// Increment tortoise by one step.
  6864 		$tortoise = isset( $override[ $tortoise ] ) ? $override[ $tortoise ] : call_user_func_array( $callback, array_merge( array( $tortoise ), $callback_args ) );
  7094 		$tortoise = isset( $override[ $tortoise ] ) ? $override[ $tortoise ] : call_user_func_array( $callback, array_merge( array( $tortoise ), $callback_args ) );
  6866 
  7096 
  6867 	return false;
  7097 	return false;
  6868 }
  7098 }
  6869 
  7099 
  6870 /**
  7100 /**
  6871  * Send a HTTP header to limit rendering of pages to same origin iframes.
  7101  * Sends a HTTP header to limit rendering of pages to same origin iframes.
  6872  *
  7102  *
  6873  * @since 3.1.3
  7103  * @since 3.1.3
  6874  *
  7104  *
  6875  * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
  7105  * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
  6876  */
  7106  */
  6877 function send_frame_options_header() {
  7107 function send_frame_options_header() {
  6878 	header( 'X-Frame-Options: SAMEORIGIN' );
  7108 	header( 'X-Frame-Options: SAMEORIGIN' );
  6879 }
  7109 }
  6880 
  7110 
  6881 /**
  7111 /**
  6882  * Retrieve a list of protocols to allow in HTML attributes.
  7112  * Retrieves a list of protocols to allow in HTML attributes.
  6883  *
  7113  *
  6884  * @since 3.3.0
  7114  * @since 3.3.0
  6885  * @since 4.3.0 Added 'webcal' to the protocols array.
  7115  * @since 4.3.0 Added 'webcal' to the protocols array.
  6886  * @since 4.7.0 Added 'urn' to the protocols array.
  7116  * @since 4.7.0 Added 'urn' to the protocols array.
  6887  * @since 5.3.0 Added 'sms' to the protocols array.
  7117  * @since 5.3.0 Added 'sms' to the protocols array.
  6938 	static $truncate_paths;
  7168 	static $truncate_paths;
  6939 
  7169 
  6940 	$trace       = debug_backtrace( false );
  7170 	$trace       = debug_backtrace( false );
  6941 	$caller      = array();
  7171 	$caller      = array();
  6942 	$check_class = ! is_null( $ignore_class );
  7172 	$check_class = ! is_null( $ignore_class );
  6943 	$skip_frames++; // Skip this function.
  7173 	++$skip_frames; // Skip this function.
  6944 
  7174 
  6945 	if ( ! isset( $truncate_paths ) ) {
  7175 	if ( ! isset( $truncate_paths ) ) {
  6946 		$truncate_paths = array(
  7176 		$truncate_paths = array(
  6947 			wp_normalize_path( WP_CONTENT_DIR ),
  7177 			wp_normalize_path( WP_CONTENT_DIR ),
  6948 			wp_normalize_path( ABSPATH ),
  7178 			wp_normalize_path( ABSPATH ),
  6949 		);
  7179 		);
  6950 	}
  7180 	}
  6951 
  7181 
  6952 	foreach ( $trace as $call ) {
  7182 	foreach ( $trace as $call ) {
  6953 		if ( $skip_frames > 0 ) {
  7183 		if ( $skip_frames > 0 ) {
  6954 			$skip_frames--;
  7184 			--$skip_frames;
  6955 		} elseif ( isset( $call['class'] ) ) {
  7185 		} elseif ( isset( $call['class'] ) ) {
  6956 			if ( $check_class && $ignore_class == $call['class'] ) {
  7186 			if ( $check_class && $ignore_class === $call['class'] ) {
  6957 				continue; // Filter out calls.
  7187 				continue; // Filter out calls.
  6958 			}
  7188 			}
  6959 
  7189 
  6960 			$caller[] = "{$call['class']}{$call['type']}{$call['function']}";
  7190 			$caller[] = "{$call['class']}{$call['type']}{$call['function']}";
  6961 		} else {
  7191 		} else {
  6975 		return $caller;
  7205 		return $caller;
  6976 	}
  7206 	}
  6977 }
  7207 }
  6978 
  7208 
  6979 /**
  7209 /**
  6980  * Retrieve IDs that are not already present in the cache.
  7210  * Retrieves IDs that are not already present in the cache.
  6981  *
  7211  *
  6982  * @since 3.4.0
  7212  * @since 3.4.0
  6983  * @access private
  7213  * @since 6.1.0 This function is no longer marked as "private".
  6984  *
  7214  *
  6985  * @param int[]  $object_ids Array of IDs.
  7215  * @param int[]  $object_ids  Array of IDs.
  6986  * @param string $cache_key  The cache bucket to check against.
  7216  * @param string $cache_group The cache group to check against.
  6987  * @return int[] Array of IDs not present in the cache.
  7217  * @return int[] Array of IDs not present in the cache.
  6988  */
  7218  */
  6989 function _get_non_cached_ids( $object_ids, $cache_key ) {
  7219 function _get_non_cached_ids( $object_ids, $cache_group ) {
       
  7220 	$object_ids = array_filter( $object_ids, '_validate_cache_id' );
       
  7221 	$object_ids = array_unique( array_map( 'intval', $object_ids ), SORT_NUMERIC );
       
  7222 
       
  7223 	if ( empty( $object_ids ) ) {
       
  7224 		return array();
       
  7225 	}
       
  7226 
  6990 	$non_cached_ids = array();
  7227 	$non_cached_ids = array();
  6991 	$cache_values   = wp_cache_get_multiple( $object_ids, $cache_key );
  7228 	$cache_values   = wp_cache_get_multiple( $object_ids, $cache_group );
  6992 
  7229 
  6993 	foreach ( $cache_values as $id => $value ) {
  7230 	foreach ( $cache_values as $id => $value ) {
  6994 		if ( ! $value ) {
  7231 		if ( false === $value ) {
  6995 			$non_cached_ids[] = (int) $id;
  7232 			$non_cached_ids[] = (int) $id;
  6996 		}
  7233 		}
  6997 	}
  7234 	}
  6998 
  7235 
  6999 	return $non_cached_ids;
  7236 	return $non_cached_ids;
  7000 }
  7237 }
  7001 
  7238 
  7002 /**
  7239 /**
  7003  * Test if the current device has the capability to upload files.
  7240  * Checks whether the given cache ID is either an integer or an integer-like string.
       
  7241  *
       
  7242  * Both `16` and `"16"` are considered valid, other numeric types and numeric strings
       
  7243  * (`16.3` and `"16.3"`) are considered invalid.
       
  7244  *
       
  7245  * @since 6.3.0
       
  7246  *
       
  7247  * @param mixed $object_id The cache ID to validate.
       
  7248  * @return bool Whether the given $object_id is a valid cache ID.
       
  7249  */
       
  7250 function _validate_cache_id( $object_id ) {
       
  7251 	/*
       
  7252 	 * filter_var() could be used here, but the `filter` PHP extension
       
  7253 	 * is considered optional and may not be available.
       
  7254 	 */
       
  7255 	if ( is_int( $object_id )
       
  7256 		|| ( is_string( $object_id ) && (string) (int) $object_id === $object_id ) ) {
       
  7257 		return true;
       
  7258 	}
       
  7259 
       
  7260 	/* translators: %s: The type of the given object ID. */
       
  7261 	$message = sprintf( __( 'Object ID must be an integer, %s given.' ), gettype( $object_id ) );
       
  7262 	_doing_it_wrong( '_get_non_cached_ids', $message, '6.3.0' );
       
  7263 
       
  7264 	return false;
       
  7265 }
       
  7266 
       
  7267 /**
       
  7268  * Tests if the current device has the capability to upload files.
  7004  *
  7269  *
  7005  * @since 3.4.0
  7270  * @since 3.4.0
  7006  * @access private
  7271  * @access private
  7007  *
  7272  *
  7008  * @return bool Whether the device is able to upload files.
  7273  * @return bool Whether the device is able to upload files.
  7012 		return true;
  7277 		return true;
  7013 	}
  7278 	}
  7014 
  7279 
  7015 	$ua = $_SERVER['HTTP_USER_AGENT'];
  7280 	$ua = $_SERVER['HTTP_USER_AGENT'];
  7016 
  7281 
  7017 	if ( strpos( $ua, 'iPhone' ) !== false
  7282 	if ( str_contains( $ua, 'iPhone' )
  7018 		|| strpos( $ua, 'iPad' ) !== false
  7283 		|| str_contains( $ua, 'iPad' )
  7019 		|| strpos( $ua, 'iPod' ) !== false ) {
  7284 		|| str_contains( $ua, 'iPod' ) ) {
  7020 			return preg_match( '#OS ([\d_]+) like Mac OS X#', $ua, $version ) && version_compare( $version[1], '6', '>=' );
  7285 			return preg_match( '#OS ([\d_]+) like Mac OS X#', $ua, $version ) && version_compare( $version[1], '6', '>=' );
  7021 	}
  7286 	}
  7022 
  7287 
  7023 	return true;
  7288 	return true;
  7024 }
  7289 }
  7025 
  7290 
  7026 /**
  7291 /**
  7027  * Test if a given path is a stream URL
  7292  * Tests if a given path is a stream URL
  7028  *
  7293  *
  7029  * @since 3.5.0
  7294  * @since 3.5.0
  7030  *
  7295  *
  7031  * @param string $path The resource path or URL.
  7296  * @param string $path The resource path or URL.
  7032  * @return bool True if the path is a stream URL.
  7297  * @return bool True if the path is a stream URL.
  7043 
  7308 
  7044 	return in_array( $stream, stream_get_wrappers(), true );
  7309 	return in_array( $stream, stream_get_wrappers(), true );
  7045 }
  7310 }
  7046 
  7311 
  7047 /**
  7312 /**
  7048  * Test if the supplied date is valid for the Gregorian calendar.
  7313  * Tests if the supplied date is valid for the Gregorian calendar.
  7049  *
  7314  *
  7050  * @since 3.5.0
  7315  * @since 3.5.0
  7051  *
  7316  *
  7052  * @link https://www.php.net/manual/en/function.checkdate.php
  7317  * @link https://www.php.net/manual/en/function.checkdate.php
  7053  *
  7318  *
  7068 	 */
  7333 	 */
  7069 	return apply_filters( 'wp_checkdate', checkdate( $month, $day, $year ), $source_date );
  7334 	return apply_filters( 'wp_checkdate', checkdate( $month, $day, $year ), $source_date );
  7070 }
  7335 }
  7071 
  7336 
  7072 /**
  7337 /**
  7073  * Load the auth check for monitoring whether the user is still logged in.
  7338  * Loads the auth check for monitoring whether the user is still logged in.
  7074  *
  7339  *
  7075  * Can be disabled with remove_action( 'admin_enqueue_scripts', 'wp_auth_check_load' );
  7340  * Can be disabled with remove_action( 'admin_enqueue_scripts', 'wp_auth_check_load' );
  7076  *
  7341  *
  7077  * This is disabled for certain screens where a login screen could cause an
  7342  * This is disabled for certain screens where a login screen could cause an
  7078  * inconvenient interruption. A filter called {@see 'wp_auth_check_load'} can be used
  7343  * inconvenient interruption. A filter called {@see 'wp_auth_check_load'} can be used
  7112 		add_action( 'wp_print_footer_scripts', 'wp_auth_check_html', 5 );
  7377 		add_action( 'wp_print_footer_scripts', 'wp_auth_check_html', 5 );
  7113 	}
  7378 	}
  7114 }
  7379 }
  7115 
  7380 
  7116 /**
  7381 /**
  7117  * Output the HTML that shows the wp-login dialog when the user is no longer logged in.
  7382  * Outputs the HTML that shows the wp-login dialog when the user is no longer logged in.
  7118  *
  7383  *
  7119  * @since 3.6.0
  7384  * @since 3.6.0
  7120  */
  7385  */
  7121 function wp_auth_check_html() {
  7386 function wp_auth_check_html() {
  7122 	$login_url      = wp_login_url();
  7387 	$login_url      = wp_login_url();
  7123 	$current_domain = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'];
  7388 	$current_domain = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'];
  7124 	$same_domain    = ( strpos( $login_url, $current_domain ) === 0 );
  7389 	$same_domain    = str_starts_with( $login_url, $current_domain );
  7125 
  7390 
  7126 	/**
  7391 	/**
  7127 	 * Filters whether the authentication check originated at the same domain.
  7392 	 * Filters whether the authentication check originated at the same domain.
  7128 	 *
  7393 	 *
  7129 	 * @since 3.6.0
  7394 	 * @since 3.6.0
  7135 
  7400 
  7136 	?>
  7401 	?>
  7137 	<div id="wp-auth-check-wrap" class="<?php echo $wrap_class; ?>">
  7402 	<div id="wp-auth-check-wrap" class="<?php echo $wrap_class; ?>">
  7138 	<div id="wp-auth-check-bg"></div>
  7403 	<div id="wp-auth-check-bg"></div>
  7139 	<div id="wp-auth-check">
  7404 	<div id="wp-auth-check">
  7140 	<button type="button" class="wp-auth-check-close button-link"><span class="screen-reader-text"><?php _e( 'Close dialog' ); ?></span></button>
  7405 	<button type="button" class="wp-auth-check-close button-link"><span class="screen-reader-text">
       
  7406 		<?php
       
  7407 		/* translators: Hidden accessibility text. */
       
  7408 		_e( 'Close dialog' );
       
  7409 		?>
       
  7410 	</span></button>
  7141 	<?php
  7411 	<?php
  7142 
  7412 
  7143 	if ( $same_domain ) {
  7413 	if ( $same_domain ) {
  7144 		$login_src = add_query_arg(
  7414 		$login_src = add_query_arg(
  7145 			array(
  7415 			array(
  7163 	</div>
  7433 	</div>
  7164 	<?php
  7434 	<?php
  7165 }
  7435 }
  7166 
  7436 
  7167 /**
  7437 /**
  7168  * Check whether a user is still logged in, for the heartbeat.
  7438  * Checks whether a user is still logged in, for the heartbeat.
  7169  *
  7439  *
  7170  * Send a result that shows a log-in box if the user is no longer logged in,
  7440  * Send a result that shows a log-in box if the user is no longer logged in,
  7171  * or if their cookie is within the grace period.
  7441  * or if their cookie is within the grace period.
  7172  *
  7442  *
  7173  * @since 3.6.0
  7443  * @since 3.6.0
  7181 	$response['wp-auth-check'] = is_user_logged_in() && empty( $GLOBALS['login_grace_period'] );
  7451 	$response['wp-auth-check'] = is_user_logged_in() && empty( $GLOBALS['login_grace_period'] );
  7182 	return $response;
  7452 	return $response;
  7183 }
  7453 }
  7184 
  7454 
  7185 /**
  7455 /**
  7186  * Return RegEx body to liberally match an opening HTML tag.
  7456  * Returns RegEx body to liberally match an opening HTML tag.
  7187  *
  7457  *
  7188  * Matches an opening HTML tag that:
  7458  * Matches an opening HTML tag that:
  7189  * 1. Is self-closing or
  7459  * 1. Is self-closing or
  7190  * 2. Has no body but has a closing tag of the same name or
  7460  * 2. Has no body but has a closing tag of the same name or
  7191  * 3. Contains a body and a closing tag of the same name
  7461  * 3. Contains a body and a closing tag of the same name
  7204 	}
  7474 	}
  7205 	return sprintf( '<%1$s[^<]*(?:>[\s\S]*<\/%1$s>|\s*\/>)', tag_escape( $tag ) );
  7475 	return sprintf( '<%1$s[^<]*(?:>[\s\S]*<\/%1$s>|\s*\/>)', tag_escape( $tag ) );
  7206 }
  7476 }
  7207 
  7477 
  7208 /**
  7478 /**
  7209  * Retrieve a canonical form of the provided charset appropriate for passing to PHP
  7479  * Indicates if a given slug for a character set represents the UTF-8
       
  7480  * text encoding. If not provided, examines the current blog's charset.
       
  7481  *
       
  7482  * A charset is considered to represent UTF-8 if it is a case-insensitive
       
  7483  * match of "UTF-8" with or without the hyphen.
       
  7484  *
       
  7485  * Example:
       
  7486  *
       
  7487  *     true  === is_utf8_charset( 'UTF-8' );
       
  7488  *     true  === is_utf8_charset( 'utf8' );
       
  7489  *     false === is_utf8_charset( 'latin1' );
       
  7490  *     false === is_utf8_charset( 'UTF 8' );
       
  7491  *
       
  7492  *     // Only strings match.
       
  7493  *     false === is_utf8_charset( [ 'charset' => 'utf-8' ] );
       
  7494  *
       
  7495  *     // Without a given charset, it depends on the site option "blog_charset".
       
  7496  *     $is_utf8 = is_utf8_charset();
       
  7497  *
       
  7498  * @since 6.6.0
       
  7499  * @since 6.6.1 A wrapper for _is_utf8_charset
       
  7500  *
       
  7501  * @see _is_utf8_charset
       
  7502  *
       
  7503  * @param string|null $blog_charset Optional. Slug representing a text character encoding, or "charset".
       
  7504  *                                  E.g. "UTF-8", "Windows-1252", "ISO-8859-1", "SJIS".
       
  7505  *                                  Default value is to infer from "blog_charset" option.
       
  7506  * @return bool Whether the slug represents the UTF-8 encoding.
       
  7507  */
       
  7508 function is_utf8_charset( $blog_charset = null ) {
       
  7509 	return _is_utf8_charset( $blog_charset ?? get_option( 'blog_charset' ) );
       
  7510 }
       
  7511 
       
  7512 /**
       
  7513  * Retrieves a canonical form of the provided charset appropriate for passing to PHP
  7210  * functions such as htmlspecialchars() and charset HTML attributes.
  7514  * functions such as htmlspecialchars() and charset HTML attributes.
  7211  *
  7515  *
  7212  * @since 3.6.0
  7516  * @since 3.6.0
  7213  * @access private
  7517  * @access private
  7214  *
  7518  *
  7215  * @see https://core.trac.wordpress.org/ticket/23688
  7519  * @see https://core.trac.wordpress.org/ticket/23688
  7216  *
  7520  *
  7217  * @param string $charset A charset name.
  7521  * @param string $charset A charset name, e.g. "UTF-8", "Windows-1252", "SJIS".
  7218  * @return string The canonical form of the charset.
  7522  * @return string The canonical form of the charset.
  7219  */
  7523  */
  7220 function _canonical_charset( $charset ) {
  7524 function _canonical_charset( $charset ) {
  7221 	if ( 'utf-8' === strtolower( $charset ) || 'utf8' === strtolower( $charset ) ) {
  7525 	if ( is_utf8_charset( $charset ) ) {
  7222 
       
  7223 		return 'UTF-8';
  7526 		return 'UTF-8';
  7224 	}
  7527 	}
  7225 
  7528 
  7226 	if ( 'iso-8859-1' === strtolower( $charset ) || 'iso8859-1' === strtolower( $charset ) ) {
  7529 	/*
  7227 
  7530 	 * Normalize the ISO-8859-1 family of languages.
       
  7531 	 *
       
  7532 	 * This is not required for htmlspecialchars(), as it properly recognizes all of
       
  7533 	 * the input character sets that here are transformed into "ISO-8859-1".
       
  7534 	 *
       
  7535 	 * @todo Should this entire check be removed since it's not required for the stated purpose?
       
  7536 	 * @todo Should WordPress transform other potential charset equivalents, such as "latin1"?
       
  7537 	 */
       
  7538 	if (
       
  7539 		( 0 === strcasecmp( 'iso-8859-1', $charset ) ) ||
       
  7540 		( 0 === strcasecmp( 'iso8859-1', $charset ) )
       
  7541 	) {
  7228 		return 'ISO-8859-1';
  7542 		return 'ISO-8859-1';
  7229 	}
  7543 	}
  7230 
  7544 
  7231 	return $charset;
  7545 	return $charset;
  7232 }
  7546 }
  7233 
  7547 
  7234 /**
  7548 /**
  7235  * Set the mbstring internal encoding to a binary safe encoding when func_overload
  7549  * Sets the mbstring internal encoding to a binary safe encoding when func_overload
  7236  * is enabled.
  7550  * is enabled.
  7237  *
  7551  *
  7238  * When mbstring.func_overload is in use for multi-byte encodings, the results from
  7552  * When mbstring.func_overload is in use for multi-byte encodings, the results from
  7239  * strlen() and similar functions respect the utf8 characters, causing binary data
  7553  * strlen() and similar functions respect the utf8 characters, causing binary data
  7240  * to return incorrect lengths.
  7554  * to return incorrect lengths.
  7283 		mb_internal_encoding( $encoding );
  7597 		mb_internal_encoding( $encoding );
  7284 	}
  7598 	}
  7285 }
  7599 }
  7286 
  7600 
  7287 /**
  7601 /**
  7288  * Reset the mbstring internal encoding to a users previously set encoding.
  7602  * Resets the mbstring internal encoding to a users previously set encoding.
  7289  *
  7603  *
  7290  * @see mbstring_binary_safe_encoding()
  7604  * @see mbstring_binary_safe_encoding()
  7291  *
  7605  *
  7292  * @since 3.7.0
  7606  * @since 3.7.0
  7293  */
  7607  */
  7294 function reset_mbstring_encoding() {
  7608 function reset_mbstring_encoding() {
  7295 	mbstring_binary_safe_encoding( true );
  7609 	mbstring_binary_safe_encoding( true );
  7296 }
  7610 }
  7297 
  7611 
  7298 /**
  7612 /**
  7299  * Filter/validate a variable as a boolean.
  7613  * Filters/validates a variable as a boolean.
  7300  *
  7614  *
  7301  * Alternative to `filter_var( $var, FILTER_VALIDATE_BOOLEAN )`.
  7615  * Alternative to `filter_var( $value, FILTER_VALIDATE_BOOLEAN )`.
  7302  *
  7616  *
  7303  * @since 4.0.0
  7617  * @since 4.0.0
  7304  *
  7618  *
  7305  * @param mixed $var Boolean value to validate.
  7619  * @param mixed $value Boolean value to validate.
  7306  * @return bool Whether the value is validated.
  7620  * @return bool Whether the value is validated.
  7307  */
  7621  */
  7308 function wp_validate_boolean( $var ) {
  7622 function wp_validate_boolean( $value ) {
  7309 	if ( is_bool( $var ) ) {
  7623 	if ( is_bool( $value ) ) {
  7310 		return $var;
  7624 		return $value;
  7311 	}
  7625 	}
  7312 
  7626 
  7313 	if ( is_string( $var ) && 'false' === strtolower( $var ) ) {
  7627 	if ( is_string( $value ) && 'false' === strtolower( $value ) ) {
  7314 		return false;
  7628 		return false;
  7315 	}
  7629 	}
  7316 
  7630 
  7317 	return (bool) $var;
  7631 	return (bool) $value;
  7318 }
  7632 }
  7319 
  7633 
  7320 /**
  7634 /**
  7321  * Delete a file
  7635  * Deletes a file.
  7322  *
  7636  *
  7323  * @since 4.2.0
  7637  * @since 4.2.0
  7324  *
  7638  *
  7325  * @param string $file The path to the file to delete.
  7639  * @param string $file The path to the file to delete.
  7326  */
  7640  */
  7362 
  7676 
  7363 	if ( false !== $real_directory ) {
  7677 	if ( false !== $real_directory ) {
  7364 		$real_directory = wp_normalize_path( $real_directory );
  7678 		$real_directory = wp_normalize_path( $real_directory );
  7365 	}
  7679 	}
  7366 
  7680 
  7367 	if ( false === $real_file || false === $real_directory || strpos( $real_file, trailingslashit( $real_directory ) ) !== 0 ) {
  7681 	if ( false === $real_file || false === $real_directory || ! str_starts_with( $real_file, trailingslashit( $real_directory ) ) ) {
  7368 		return false;
  7682 		return false;
  7369 	}
  7683 	}
  7370 
  7684 
  7371 	wp_delete_file( $file );
  7685 	wp_delete_file( $file );
  7372 
  7686 
  7373 	return true;
  7687 	return true;
  7374 }
  7688 }
  7375 
  7689 
  7376 /**
  7690 /**
  7377  * Outputs a small JS snippet on preview tabs/windows to remove `window.name` on unload.
  7691  * Outputs a small JS snippet on preview tabs/windows to remove `window.name` when a user is navigating to another page.
  7378  *
  7692  *
  7379  * This prevents reusing the same tab for a preview when the user has navigated away.
  7693  * This prevents reusing the same tab for a preview when the user has navigated away.
  7380  *
  7694  *
  7381  * @since 4.3.0
  7695  * @since 4.3.0
  7382  *
  7696  *
  7390 	}
  7704 	}
  7391 
  7705 
  7392 	// Has to match the window name used in post_submit_meta_box().
  7706 	// Has to match the window name used in post_submit_meta_box().
  7393 	$name = 'wp-preview-' . (int) $post->ID;
  7707 	$name = 'wp-preview-' . (int) $post->ID;
  7394 
  7708 
       
  7709 	ob_start();
  7395 	?>
  7710 	?>
  7396 	<script>
  7711 	<script>
  7397 	( function() {
  7712 	( function() {
  7398 		var query = document.location.search;
  7713 		var query = document.location.search;
  7399 
  7714 
  7400 		if ( query && query.indexOf( 'preview=true' ) !== -1 ) {
  7715 		if ( query && query.indexOf( 'preview=true' ) !== -1 ) {
  7401 			window.name = '<?php echo $name; ?>';
  7716 			window.name = '<?php echo $name; ?>';
  7402 		}
  7717 		}
  7403 
  7718 
  7404 		if ( window.addEventListener ) {
  7719 		if ( window.addEventListener ) {
  7405 			window.addEventListener( 'unload', function() { window.name = ''; }, false );
  7720 			window.addEventListener( 'pagehide', function() { window.name = ''; } );
  7406 		}
  7721 		}
  7407 	}());
  7722 	}());
  7408 	</script>
  7723 	</script>
  7409 	<?php
  7724 	<?php
       
  7725 	wp_print_inline_script_tag( wp_remove_surrounding_empty_script_tags( ob_get_clean() ) );
  7410 }
  7726 }
  7411 
  7727 
  7412 /**
  7728 /**
  7413  * Parses and formats a MySQL datetime (Y-m-d H:i:s) for ISO8601 (Y-m-d\TH:i:s).
  7729  * Parses and formats a MySQL datetime (Y-m-d H:i:s) for ISO8601 (Y-m-d\TH:i:s).
  7414  *
  7730  *
  7433  * Only allows raising the existing limit and prevents lowering it.
  7749  * Only allows raising the existing limit and prevents lowering it.
  7434  *
  7750  *
  7435  * @since 4.6.0
  7751  * @since 4.6.0
  7436  *
  7752  *
  7437  * @param string $context Optional. Context in which the function is called. Accepts either 'admin',
  7753  * @param string $context Optional. Context in which the function is called. Accepts either 'admin',
  7438  *                        'image', or an arbitrary other context. If an arbitrary context is passed,
  7754  *                        'image', 'cron', or an arbitrary other context. If an arbitrary context is passed,
  7439  *                        the similarly arbitrary {@see '$context_memory_limit'} filter will be
  7755  *                        the similarly arbitrary {@see '$context_memory_limit'} filter will be
  7440  *                        invoked. Default 'admin'.
  7756  *                        invoked. Default 'admin'.
  7441  * @return int|string|false The limit that was set or false on failure.
  7757  * @return int|string|false The limit that was set or false on failure.
  7442  */
  7758  */
  7443 function wp_raise_memory_limit( $context = 'admin' ) {
  7759 function wp_raise_memory_limit( $context = 'admin' ) {
  7485 			 * Filters the memory limit allocated for image manipulation.
  7801 			 * Filters the memory limit allocated for image manipulation.
  7486 			 *
  7802 			 *
  7487 			 * @since 3.5.0
  7803 			 * @since 3.5.0
  7488 			 * @since 4.6.0 The default now takes the original `memory_limit` into account.
  7804 			 * @since 4.6.0 The default now takes the original `memory_limit` into account.
  7489 			 *
  7805 			 *
  7490 			 * @param int|string $filtered_limit Maximum memory limit to allocate for images.
  7806 			 * @param int|string $filtered_limit Maximum memory limit to allocate for image processing.
  7491 			 *                                   Default `WP_MAX_MEMORY_LIMIT` or the original
  7807 			 *                                   Default `WP_MAX_MEMORY_LIMIT` or the original
  7492 			 *                                   php.ini `memory_limit`, whichever is higher.
  7808 			 *                                   php.ini `memory_limit`, whichever is higher.
  7493 			 *                                   Accepts an integer (bytes), or a shorthand string
  7809 			 *                                   Accepts an integer (bytes), or a shorthand string
  7494 			 *                                   notation, such as '256M'.
  7810 			 *                                   notation, such as '256M'.
  7495 			 */
  7811 			 */
  7496 			$filtered_limit = apply_filters( 'image_memory_limit', $filtered_limit );
  7812 			$filtered_limit = apply_filters( 'image_memory_limit', $filtered_limit );
  7497 			break;
  7813 			break;
  7498 
  7814 
       
  7815 		case 'cron':
       
  7816 			/**
       
  7817 			 * Filters the memory limit allocated for WP-Cron event processing.
       
  7818 			 *
       
  7819 			 * @since 6.3.0
       
  7820 			 *
       
  7821 			 * @param int|string $filtered_limit Maximum memory limit to allocate for WP-Cron.
       
  7822 			 *                                   Default `WP_MAX_MEMORY_LIMIT` or the original
       
  7823 			 *                                   php.ini `memory_limit`, whichever is higher.
       
  7824 			 *                                   Accepts an integer (bytes), or a shorthand string
       
  7825 			 *                                   notation, such as '256M'.
       
  7826 			 */
       
  7827 			$filtered_limit = apply_filters( 'cron_memory_limit', $filtered_limit );
       
  7828 			break;
       
  7829 
  7499 		default:
  7830 		default:
  7500 			/**
  7831 			/**
  7501 			 * Filters the memory limit allocated for arbitrary contexts.
  7832 			 * Filters the memory limit allocated for an arbitrary context.
  7502 			 *
  7833 			 *
  7503 			 * The dynamic portion of the hook name, `$context`, refers to an arbitrary
  7834 			 * The dynamic portion of the hook name, `$context`, refers to an arbitrary
  7504 			 * context passed on calling the function. This allows for plugins to define
  7835 			 * context passed on calling the function. This allows for plugins to define
  7505 			 * their own contexts for raising the memory limit.
  7836 			 * their own contexts for raising the memory limit.
  7506 			 *
  7837 			 *
  7507 			 * @since 4.6.0
  7838 			 * @since 4.6.0
  7508 			 *
  7839 			 *
  7509 			 * @param int|string $filtered_limit Maximum memory limit to allocate for images.
  7840 			 * @param int|string $filtered_limit Maximum memory limit to allocate for this context.
  7510 			 *                                   Default '256M' or the original php.ini `memory_limit`,
  7841 			 *                                   Default WP_MAX_MEMORY_LIMIT` or the original php.ini `memory_limit`,
  7511 			 *                                   whichever is higher. Accepts an integer (bytes), or a
  7842 			 *                                   whichever is higher. Accepts an integer (bytes), or a
  7512 			 *                                   shorthand string notation, such as '256M'.
  7843 			 *                                   shorthand string notation, such as '256M'.
  7513 			 */
  7844 			 */
  7514 			$filtered_limit = apply_filters( "{$context}_memory_limit", $filtered_limit );
  7845 			$filtered_limit = apply_filters( "{$context}_memory_limit", $filtered_limit );
  7515 			break;
  7846 			break;
  7533 
  7864 
  7534 	return false;
  7865 	return false;
  7535 }
  7866 }
  7536 
  7867 
  7537 /**
  7868 /**
  7538  * Generate a random UUID (version 4).
  7869  * Generates a random UUID (version 4).
  7539  *
  7870  *
  7540  * @since 4.7.0
  7871  * @since 4.7.0
  7541  *
  7872  *
  7542  * @return string UUID.
  7873  * @return string UUID.
  7543  */
  7874  */
  7601 	static $id_counter = 0;
  7932 	static $id_counter = 0;
  7602 	return $prefix . (string) ++$id_counter;
  7933 	return $prefix . (string) ++$id_counter;
  7603 }
  7934 }
  7604 
  7935 
  7605 /**
  7936 /**
       
  7937  * Generates an incremental ID that is independent per each different prefix.
       
  7938  *
       
  7939  * It is similar to `wp_unique_id`, but each prefix has its own internal ID
       
  7940  * counter to make each prefix independent from each other. The ID starts at 1
       
  7941  * and increments on each call. The returned value is not universally unique,
       
  7942  * but it is unique across the life of the PHP process and it's stable per
       
  7943  * prefix.
       
  7944  *
       
  7945  * @since 6.4.0
       
  7946  *
       
  7947  * @param string $prefix Optional. Prefix for the returned ID. Default empty string.
       
  7948  * @return string Incremental ID per prefix.
       
  7949  */
       
  7950 function wp_unique_prefixed_id( $prefix = '' ) {
       
  7951 	static $id_counters = array();
       
  7952 
       
  7953 	if ( ! is_string( $prefix ) ) {
       
  7954 		wp_trigger_error(
       
  7955 			__FUNCTION__,
       
  7956 			sprintf( 'The prefix must be a string. "%s" data type given.', gettype( $prefix ) )
       
  7957 		);
       
  7958 		$prefix = '';
       
  7959 	}
       
  7960 
       
  7961 	if ( ! isset( $id_counters[ $prefix ] ) ) {
       
  7962 		$id_counters[ $prefix ] = 0;
       
  7963 	}
       
  7964 
       
  7965 	$id = ++$id_counters[ $prefix ];
       
  7966 
       
  7967 	return $prefix . (string) $id;
       
  7968 }
       
  7969 
       
  7970 /**
  7606  * Gets last changed date for the specified cache group.
  7971  * Gets last changed date for the specified cache group.
  7607  *
  7972  *
  7608  * @since 4.7.0
  7973  * @since 4.7.0
  7609  *
  7974  *
  7610  * @param string $group Where the cache contents are grouped.
  7975  * @param string $group Where the cache contents are grouped.
  7611  * @return string UNIX timestamp with microseconds representing when the group was last changed.
  7976  * @return string UNIX timestamp with microseconds representing when the group was last changed.
  7612  */
  7977  */
  7613 function wp_cache_get_last_changed( $group ) {
  7978 function wp_cache_get_last_changed( $group ) {
  7614 	$last_changed = wp_cache_get( 'last_changed', $group );
  7979 	$last_changed = wp_cache_get( 'last_changed', $group );
  7615 
  7980 
  7616 	if ( ! $last_changed ) {
  7981 	if ( $last_changed ) {
  7617 		$last_changed = microtime();
  7982 		return $last_changed;
  7618 		wp_cache_set( 'last_changed', $last_changed, $group );
  7983 	}
  7619 	}
  7984 
  7620 
  7985 	return wp_cache_set_last_changed( $group );
  7621 	return $last_changed;
  7986 }
  7622 }
  7987 
  7623 
  7988 /**
  7624 /**
  7989  * Sets last changed date for the specified cache group to now.
  7625  * Send an email to the old site admin email address when the site admin email address changes.
  7990  *
       
  7991  * @since 6.3.0
       
  7992  *
       
  7993  * @param string $group Where the cache contents are grouped.
       
  7994  * @return string UNIX timestamp when the group was last changed.
       
  7995  */
       
  7996 function wp_cache_set_last_changed( $group ) {
       
  7997 	$previous_time = wp_cache_get( 'last_changed', $group );
       
  7998 
       
  7999 	$time = microtime();
       
  8000 
       
  8001 	wp_cache_set( 'last_changed', $time, $group );
       
  8002 
       
  8003 	/**
       
  8004 	 * Fires after a cache group `last_changed` time is updated.
       
  8005 	 * This may occur multiple times per page load and registered
       
  8006 	 * actions must be performant.
       
  8007 	 *
       
  8008 	 * @since 6.3.0
       
  8009 	 *
       
  8010 	 * @param string    $group         The cache group name.
       
  8011 	 * @param int       $time          The new last changed time.
       
  8012 	 * @param int|false $previous_time The previous last changed time. False if not previously set.
       
  8013 	 */
       
  8014 	do_action( 'wp_cache_set_last_changed', $group, $time, $previous_time );
       
  8015 
       
  8016 	return $time;
       
  8017 }
       
  8018 
       
  8019 /**
       
  8020  * Sends an email to the old site admin email address when the site admin email address changes.
  7626  *
  8021  *
  7627  * @since 4.9.0
  8022  * @since 4.9.0
  7628  *
  8023  *
  7629  * @param string $old_email   The old site admin email address.
  8024  * @param string $old_email   The old site admin email address.
  7630  * @param string $new_email   The new site admin email address.
  8025  * @param string $new_email   The new site admin email address.
  7717 		$email_change_email['headers']
  8112 		$email_change_email['headers']
  7718 	);
  8113 	);
  7719 }
  8114 }
  7720 
  8115 
  7721 /**
  8116 /**
  7722  * Return an anonymized IPv4 or IPv6 address.
  8117  * Returns an anonymized IPv4 or IPv6 address.
  7723  *
  8118  *
  7724  * @since 4.9.6 Abstracted from `WP_Community_Events::get_unsafe_client_ip()`.
  8119  * @since 4.9.6 Abstracted from `WP_Community_Events::get_unsafe_client_ip()`.
  7725  *
  8120  *
  7726  * @param string $ip_addr       The IPv4 or IPv6 address to be anonymized.
  8121  * @param string $ip_addr       The IPv4 or IPv6 address to be anonymized.
  7727  * @param bool   $ipv6_fallback Optional. Whether to return the original IPv6 address if the needed functions
  8122  * @param bool   $ipv6_fallback Optional. Whether to return the original IPv6 address if the needed functions
  7791 	// Restore the IPv6 prefix to compatibility mode addresses.
  8186 	// Restore the IPv6 prefix to compatibility mode addresses.
  7792 	return $ip_prefix . $ip_addr;
  8187 	return $ip_prefix . $ip_addr;
  7793 }
  8188 }
  7794 
  8189 
  7795 /**
  8190 /**
  7796  * Return uniform "anonymous" data by type.
  8191  * Returns uniform "anonymous" data by type.
  7797  *
  8192  *
  7798  * @since 4.9.6
  8193  * @since 4.9.6
  7799  *
  8194  *
  7800  * @param string $type The type of data to be anonymized.
  8195  * @param string $type The type of data to be anonymized.
  7801  * @param string $data Optional The data to be anonymized.
  8196  * @param string $data Optional. The data to be anonymized. Default empty string.
  7802  * @return string The anonymous data for the requested type.
  8197  * @return string The anonymous data for the requested type.
  7803  */
  8198  */
  7804 function wp_privacy_anonymize_data( $type, $data = '' ) {
  8199 function wp_privacy_anonymize_data( $type, $data = '' ) {
  7805 
  8200 
  7806 	switch ( $type ) {
  8201 	switch ( $type ) {
  7890 	 */
  8285 	 */
  7891 	return apply_filters( 'wp_privacy_exports_url', $exports_url );
  8286 	return apply_filters( 'wp_privacy_exports_url', $exports_url );
  7892 }
  8287 }
  7893 
  8288 
  7894 /**
  8289 /**
  7895  * Schedule a `WP_Cron` job to delete expired export files.
  8290  * Schedules a `WP_Cron` job to delete expired export files.
  7896  *
  8291  *
  7897  * @since 4.9.6
  8292  * @since 4.9.6
  7898  */
  8293  */
  7899 function wp_schedule_delete_old_privacy_export_files() {
  8294 function wp_schedule_delete_old_privacy_export_files() {
  7900 	if ( wp_installing() ) {
  8295 	if ( wp_installing() ) {
  8008  * This function is to be used after {@see wp_get_update_php_url()} to display a consistent
  8403  * This function is to be used after {@see wp_get_update_php_url()} to display a consistent
  8009  * annotation if the web host has altered the default "Update PHP" page URL.
  8404  * annotation if the web host has altered the default "Update PHP" page URL.
  8010  *
  8405  *
  8011  * @since 5.1.0
  8406  * @since 5.1.0
  8012  * @since 5.2.0 Added the `$before` and `$after` parameters.
  8407  * @since 5.2.0 Added the `$before` and `$after` parameters.
  8013  *
  8408  * @since 6.4.0 Added the `$display` parameter.
  8014  * @param string $before Markup to output before the annotation. Default `<p class="description">`.
  8409  *
  8015  * @param string $after  Markup to output after the annotation. Default `</p>`.
  8410  * @param string $before  Markup to output before the annotation. Default `<p class="description">`.
  8016  */
  8411  * @param string $after   Markup to output after the annotation. Default `</p>`.
  8017 function wp_update_php_annotation( $before = '<p class="description">', $after = '</p>' ) {
  8412  * @param bool   $display Whether to echo or return the markup. Default `true` for echo.
       
  8413  *
       
  8414  * @return string|void
       
  8415  */
       
  8416 function wp_update_php_annotation( $before = '<p class="description">', $after = '</p>', $display = true ) {
  8018 	$annotation = wp_get_update_php_annotation();
  8417 	$annotation = wp_get_update_php_annotation();
  8019 
  8418 
  8020 	if ( $annotation ) {
  8419 	if ( $annotation ) {
  8021 		echo $before . $annotation . $after;
  8420 		if ( $display ) {
       
  8421 			echo $before . $annotation . $after;
       
  8422 		} else {
       
  8423 			return $before . $annotation . $after;
       
  8424 		}
  8022 	}
  8425 	}
  8023 }
  8426 }
  8024 
  8427 
  8025 /**
  8428 /**
  8026  * Returns the default annotation for the web hosting altering the "Update PHP" page URL.
  8429  * Returns the default annotation for the web hosting altering the "Update PHP" page URL.
  8078 
  8481 
  8079 	return $direct_update_url;
  8482 	return $direct_update_url;
  8080 }
  8483 }
  8081 
  8484 
  8082 /**
  8485 /**
  8083  * Display a button directly linking to a PHP update process.
  8486  * Displays a button directly linking to a PHP update process.
  8084  *
  8487  *
  8085  * This provides hosts with a way for users to be sent directly to their PHP update process.
  8488  * This provides hosts with a way for users to be sent directly to their PHP update process.
  8086  *
  8489  *
  8087  * The button is only displayed if a URL is returned by `wp_get_direct_php_update_url()`.
  8490  * The button is only displayed if a URL is returned by `wp_get_direct_php_update_url()`.
  8088  *
  8491  *
  8095 		return;
  8498 		return;
  8096 	}
  8499 	}
  8097 
  8500 
  8098 	echo '<p class="button-container">';
  8501 	echo '<p class="button-container">';
  8099 	printf(
  8502 	printf(
  8100 		'<a class="button button-primary" href="%1$s" target="_blank" rel="noopener">%2$s <span class="screen-reader-text">%3$s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a>',
  8503 		'<a class="button button-primary" href="%1$s" target="_blank" rel="noopener">%2$s<span class="screen-reader-text"> %3$s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a>',
  8101 		esc_url( $direct_update_url ),
  8504 		esc_url( $direct_update_url ),
  8102 		__( 'Update PHP' ),
  8505 		__( 'Update PHP' ),
  8103 		/* translators: Accessibility text. */
  8506 		/* translators: Hidden accessibility text. */
  8104 		__( '(opens in a new tab)' )
  8507 		__( '(opens in a new tab)' )
  8105 	);
  8508 	);
  8106 	echo '</p>';
  8509 	echo '</p>';
  8107 }
  8510 }
  8108 
  8511 
  8156  *
  8559  *
  8157  * @return string Default URL to learn more about updating to HTTPS.
  8560  * @return string Default URL to learn more about updating to HTTPS.
  8158  */
  8561  */
  8159 function wp_get_default_update_https_url() {
  8562 function wp_get_default_update_https_url() {
  8160 	/* translators: Documentation explaining HTTPS and why it should be used. */
  8563 	/* translators: Documentation explaining HTTPS and why it should be used. */
  8161 	return __( 'https://wordpress.org/support/article/why-should-i-use-https/' );
  8564 	return __( 'https://developer.wordpress.org/advanced-administration/security/https/' );
  8162 }
  8565 }
  8163 
  8566 
  8164 /**
  8567 /**
  8165  * Gets the URL for directly updating the site to use HTTPS.
  8568  * Gets the URL for directly updating the site to use HTTPS.
  8166  *
  8569  *
  8190 
  8593 
  8191 	return $direct_update_url;
  8594 	return $direct_update_url;
  8192 }
  8595 }
  8193 
  8596 
  8194 /**
  8597 /**
  8195  * Get the size of a directory.
  8598  * Gets the size of a directory.
  8196  *
  8599  *
  8197  * A helper function that is used primarily to check whether
  8600  * A helper function that is used primarily to check whether
  8198  * a blog has exceeded its allowed upload space.
  8601  * a blog has exceeded its allowed upload space.
  8199  *
  8602  *
  8200  * @since MU (3.0.0)
  8603  * @since MU (3.0.0)
  8205  *                                   The timeout is global and is measured from the moment WordPress started to load.
  8608  *                                   The timeout is global and is measured from the moment WordPress started to load.
  8206  * @return int|false|null Size in bytes if a valid directory. False if not. Null if timeout.
  8609  * @return int|false|null Size in bytes if a valid directory. False if not. Null if timeout.
  8207  */
  8610  */
  8208 function get_dirsize( $directory, $max_execution_time = null ) {
  8611 function get_dirsize( $directory, $max_execution_time = null ) {
  8209 
  8612 
  8210 	// Exclude individual site directories from the total when checking the main site of a network,
  8613 	/*
  8211 	// as they are subdirectories and should not be counted.
  8614 	 * Exclude individual site directories from the total when checking the main site of a network,
       
  8615 	 * as they are subdirectories and should not be counted.
       
  8616 	 */
  8212 	if ( is_multisite() && is_main_site() ) {
  8617 	if ( is_multisite() && is_main_site() ) {
  8213 		$size = recurse_dirsize( $directory, $directory . '/sites', $max_execution_time );
  8618 		$size = recurse_dirsize( $directory, $directory . '/sites', $max_execution_time );
  8214 	} else {
  8619 	} else {
  8215 		$size = recurse_dirsize( $directory, null, $max_execution_time );
  8620 		$size = recurse_dirsize( $directory, null, $max_execution_time );
  8216 	}
  8621 	}
  8217 
  8622 
  8218 	return $size;
  8623 	return $size;
  8219 }
  8624 }
  8220 
  8625 
  8221 /**
  8626 /**
  8222  * Get the size of a directory recursively.
  8627  * Gets the size of a directory recursively.
  8223  *
  8628  *
  8224  * Used by get_dirsize() to get a directory size when it contains other directories.
  8629  * Used by get_dirsize() to get a directory size when it contains other directories.
  8225  *
  8630  *
  8226  * @since MU (3.0.0)
  8631  * @since MU (3.0.0)
  8227  * @since 4.3.0 The `$exclude` parameter was added.
  8632  * @since 4.3.0 The `$exclude` parameter was added.
  8229  * @since 5.6.0 The `$directory_cache` parameter was added.
  8634  * @since 5.6.0 The `$directory_cache` parameter was added.
  8230  *
  8635  *
  8231  * @param string          $directory          Full path of a directory.
  8636  * @param string          $directory          Full path of a directory.
  8232  * @param string|string[] $exclude            Optional. Full path of a subdirectory to exclude from the total,
  8637  * @param string|string[] $exclude            Optional. Full path of a subdirectory to exclude from the total,
  8233  *                                            or array of paths. Expected without trailing slash(es).
  8638  *                                            or array of paths. Expected without trailing slash(es).
       
  8639  *                                            Default null.
  8234  * @param int             $max_execution_time Optional. Maximum time to run before giving up. In seconds.
  8640  * @param int             $max_execution_time Optional. Maximum time to run before giving up. In seconds.
  8235  *                                            The timeout is global and is measured from the moment
  8641  *                                            The timeout is global and is measured from the moment
  8236  *                                            WordPress started to load.
  8642  *                                            WordPress started to load. Defaults to the value of
       
  8643  *                                            `max_execution_time` PHP setting.
  8237  * @param array           $directory_cache    Optional. Array of cached directory paths.
  8644  * @param array           $directory_cache    Optional. Array of cached directory paths.
  8238  *
  8645  *                                            Defaults to the value of `dirsize_cache` transient.
  8239  * @return int|false|null Size in bytes if a valid directory. False if not. Null if timeout.
  8646  * @return int|false|null Size in bytes if a valid directory. False if not. Null if timeout.
  8240  */
  8647  */
  8241 function recurse_dirsize( $directory, $exclude = null, $max_execution_time = null, &$directory_cache = null ) {
  8648 function recurse_dirsize( $directory, $exclude = null, $max_execution_time = null, &$directory_cache = null ) {
  8242 	$directory  = untrailingslashit( $directory );
  8649 	$directory  = untrailingslashit( $directory );
  8243 	$save_cache = false;
  8650 	$save_cache = false;
  8330 
  8737 
  8331 	$directory_cache[ $directory ] = $size;
  8738 	$directory_cache[ $directory ] = $size;
  8332 
  8739 
  8333 	// Only write the transient on the top level call and not on recursive calls.
  8740 	// Only write the transient on the top level call and not on recursive calls.
  8334 	if ( $save_cache ) {
  8741 	if ( $save_cache ) {
  8335 		set_transient( 'dirsize_cache', $directory_cache );
  8742 		$expiration = ( wp_using_ext_object_cache() ) ? 0 : 10 * YEAR_IN_SECONDS;
       
  8743 		set_transient( 'dirsize_cache', $directory_cache, $expiration );
  8336 	}
  8744 	}
  8337 
  8745 
  8338 	return $size;
  8746 	return $size;
  8339 }
  8747 }
  8340 
  8748 
  8348  *
  8756  *
  8349  * @param string $path Full path of a directory or file.
  8757  * @param string $path Full path of a directory or file.
  8350  */
  8758  */
  8351 function clean_dirsize_cache( $path ) {
  8759 function clean_dirsize_cache( $path ) {
  8352 	if ( ! is_string( $path ) || empty( $path ) ) {
  8760 	if ( ! is_string( $path ) || empty( $path ) ) {
  8353 		trigger_error(
  8761 		wp_trigger_error(
       
  8762 			'',
  8354 			sprintf(
  8763 			sprintf(
  8355 				/* translators: 1: Function name, 2: A variable type, like "boolean" or "integer". */
  8764 				/* translators: 1: Function name, 2: A variable type, like "boolean" or "integer". */
  8356 				__( '%1$s only accepts a non-empty path string, received %2$s.' ),
  8765 				__( '%1$s only accepts a non-empty path string, received %2$s.' ),
  8357 				'<code>clean_dirsize_cache()</code>',
  8766 				'<code>clean_dirsize_cache()</code>',
  8358 				'<code>' . gettype( $path ) . '</code>'
  8767 				'<code>' . gettype( $path ) . '</code>'
  8365 
  8774 
  8366 	if ( empty( $directory_cache ) ) {
  8775 	if ( empty( $directory_cache ) ) {
  8367 		return;
  8776 		return;
  8368 	}
  8777 	}
  8369 
  8778 
       
  8779 	$expiration = ( wp_using_ext_object_cache() ) ? 0 : 10 * YEAR_IN_SECONDS;
  8370 	if (
  8780 	if (
  8371 		strpos( $path, '/' ) === false &&
  8781 		! str_contains( $path, '/' ) &&
  8372 		strpos( $path, '\\' ) === false
  8782 		! str_contains( $path, '\\' )
  8373 	) {
  8783 	) {
  8374 		unset( $directory_cache[ $path ] );
  8784 		unset( $directory_cache[ $path ] );
  8375 		set_transient( 'dirsize_cache', $directory_cache );
  8785 		set_transient( 'dirsize_cache', $directory_cache, $expiration );
  8376 		return;
  8786 		return;
  8377 	}
  8787 	}
  8378 
  8788 
  8379 	$last_path = null;
  8789 	$last_path = null;
  8380 	$path      = untrailingslashit( $path );
  8790 	$path      = untrailingslashit( $path );
  8389 		$last_path = $path;
  8799 		$last_path = $path;
  8390 		$path      = dirname( $path );
  8800 		$path      = dirname( $path );
  8391 		unset( $directory_cache[ $path ] );
  8801 		unset( $directory_cache[ $path ] );
  8392 	}
  8802 	}
  8393 
  8803 
  8394 	set_transient( 'dirsize_cache', $directory_cache );
  8804 	set_transient( 'dirsize_cache', $directory_cache, $expiration );
  8395 }
  8805 }
  8396 
  8806 
  8397 /**
  8807 /**
  8398  * Checks compatibility with the current WordPress version.
  8808  * Checks compatibility with the current WordPress version.
  8399  *
  8809  *
  8408 	global $wp_version;
  8818 	global $wp_version;
  8409 
  8819 
  8410 	// Strip off any -alpha, -RC, -beta, -src suffixes.
  8820 	// Strip off any -alpha, -RC, -beta, -src suffixes.
  8411 	list( $version ) = explode( '-', $wp_version );
  8821 	list( $version ) = explode( '-', $wp_version );
  8412 
  8822 
       
  8823 	if ( is_string( $required ) ) {
       
  8824 		$trimmed = trim( $required );
       
  8825 
       
  8826 		if ( substr_count( $trimmed, '.' ) > 1 && str_ends_with( $trimmed, '.0' ) ) {
       
  8827 			$required = substr( $trimmed, 0, -2 );
       
  8828 		}
       
  8829 	}
       
  8830 
  8413 	return empty( $required ) || version_compare( $version, $required, '>=' );
  8831 	return empty( $required ) || version_compare( $version, $required, '>=' );
  8414 }
  8832 }
  8415 
  8833 
  8416 /**
  8834 /**
  8417  * Checks compatibility with the current PHP version.
  8835  * Checks compatibility with the current PHP version.
  8420  *
  8838  *
  8421  * @param string $required Minimum required PHP version.
  8839  * @param string $required Minimum required PHP version.
  8422  * @return bool True if required version is compatible or empty, false if not.
  8840  * @return bool True if required version is compatible or empty, false if not.
  8423  */
  8841  */
  8424 function is_php_version_compatible( $required ) {
  8842 function is_php_version_compatible( $required ) {
  8425 	return empty( $required ) || version_compare( phpversion(), $required, '>=' );
  8843 	return empty( $required ) || version_compare( PHP_VERSION, $required, '>=' );
  8426 }
  8844 }
  8427 
  8845 
  8428 /**
  8846 /**
  8429  * Checks if two numbers are nearly the same.
  8847  * Checks if two numbers are nearly the same.
  8430  *
  8848  *
  8432  *
  8850  *
  8433  * @since 5.3.0
  8851  * @since 5.3.0
  8434  *
  8852  *
  8435  * @param int|float $expected  The expected value.
  8853  * @param int|float $expected  The expected value.
  8436  * @param int|float $actual    The actual number.
  8854  * @param int|float $actual    The actual number.
  8437  * @param int|float $precision The allowed variation.
  8855  * @param int|float $precision Optional. The allowed variation. Default 1.
  8438  * @return bool Whether the numbers match within the specified precision.
  8856  * @return bool Whether the numbers match within the specified precision.
  8439  */
  8857  */
  8440 function wp_fuzzy_number_match( $expected, $actual, $precision = 1 ) {
  8858 function wp_fuzzy_number_match( $expected, $actual, $precision = 1 ) {
  8441 	return abs( (float) $expected - (float) $actual ) <= $precision;
  8859 	return abs( (float) $expected - (float) $actual ) <= $precision;
  8442 }
  8860 }
  8443 
  8861 
  8444 /**
  8862 /**
  8445  * Sorts the keys of an array alphabetically.
  8863  * Creates and returns the markup for an admin notice.
  8446  * The array is passed by reference so it doesn't get returned
  8864  *
  8447  * which mimics the behaviour of ksort.
  8865  * @since 6.4.0
  8448  *
  8866  *
  8449  * @since 6.0.0
  8867  * @param string $message The message.
  8450  *
  8868  * @param array  $args {
  8451  * @param array $array The array to sort, passed by reference.
  8869  *     Optional. An array of arguments for the admin notice. Default empty array.
  8452  */
  8870  *
  8453 function wp_recursive_ksort( &$array ) {
  8871  *     @type string   $type               Optional. The type of admin notice.
  8454 	foreach ( $array as &$value ) {
  8872  *                                        For example, 'error', 'success', 'warning', 'info'.
  8455 		if ( is_array( $value ) ) {
  8873  *                                        Default empty string.
  8456 			wp_recursive_ksort( $value );
  8874  *     @type bool     $dismissible        Optional. Whether the admin notice is dismissible. Default false.
  8457 		}
  8875  *     @type string   $id                 Optional. The value of the admin notice's ID attribute. Default empty string.
  8458 	}
  8876  *     @type string[] $additional_classes Optional. A string array of class names. Default empty array.
  8459 	ksort( $array );
  8877  *     @type string[] $attributes         Optional. Additional attributes for the notice div. Default empty array.
  8460 }
  8878  *     @type bool     $paragraph_wrap     Optional. Whether to wrap the message in paragraph tags. Default true.
       
  8879  * }
       
  8880  * @return string The markup for an admin notice.
       
  8881  */
       
  8882 function wp_get_admin_notice( $message, $args = array() ) {
       
  8883 	$defaults = array(
       
  8884 		'type'               => '',
       
  8885 		'dismissible'        => false,
       
  8886 		'id'                 => '',
       
  8887 		'additional_classes' => array(),
       
  8888 		'attributes'         => array(),
       
  8889 		'paragraph_wrap'     => true,
       
  8890 	);
       
  8891 
       
  8892 	$args = wp_parse_args( $args, $defaults );
       
  8893 
       
  8894 	/**
       
  8895 	 * Filters the arguments for an admin notice.
       
  8896 	 *
       
  8897 	 * @since 6.4.0
       
  8898 	 *
       
  8899 	 * @param array  $args    The arguments for the admin notice.
       
  8900 	 * @param string $message The message for the admin notice.
       
  8901 	 */
       
  8902 	$args       = apply_filters( 'wp_admin_notice_args', $args, $message );
       
  8903 	$id         = '';
       
  8904 	$classes    = 'notice';
       
  8905 	$attributes = '';
       
  8906 
       
  8907 	if ( is_string( $args['id'] ) ) {
       
  8908 		$trimmed_id = trim( $args['id'] );
       
  8909 
       
  8910 		if ( '' !== $trimmed_id ) {
       
  8911 			$id = 'id="' . $trimmed_id . '" ';
       
  8912 		}
       
  8913 	}
       
  8914 
       
  8915 	if ( is_string( $args['type'] ) ) {
       
  8916 		$type = trim( $args['type'] );
       
  8917 
       
  8918 		if ( str_contains( $type, ' ' ) ) {
       
  8919 			_doing_it_wrong(
       
  8920 				__FUNCTION__,
       
  8921 				sprintf(
       
  8922 					/* translators: %s: The "type" key. */
       
  8923 					__( 'The %s key must be a string without spaces.' ),
       
  8924 					'<code>type</code>'
       
  8925 				),
       
  8926 				'6.4.0'
       
  8927 			);
       
  8928 		}
       
  8929 
       
  8930 		if ( '' !== $type ) {
       
  8931 			$classes .= ' notice-' . $type;
       
  8932 		}
       
  8933 	}
       
  8934 
       
  8935 	if ( true === $args['dismissible'] ) {
       
  8936 		$classes .= ' is-dismissible';
       
  8937 	}
       
  8938 
       
  8939 	if ( is_array( $args['additional_classes'] ) && ! empty( $args['additional_classes'] ) ) {
       
  8940 		$classes .= ' ' . implode( ' ', $args['additional_classes'] );
       
  8941 	}
       
  8942 
       
  8943 	if ( is_array( $args['attributes'] ) && ! empty( $args['attributes'] ) ) {
       
  8944 		$attributes = '';
       
  8945 		foreach ( $args['attributes'] as $attr => $val ) {
       
  8946 			if ( is_bool( $val ) ) {
       
  8947 				$attributes .= $val ? ' ' . $attr : '';
       
  8948 			} elseif ( is_int( $attr ) ) {
       
  8949 				$attributes .= ' ' . esc_attr( trim( $val ) );
       
  8950 			} elseif ( $val ) {
       
  8951 				$attributes .= ' ' . $attr . '="' . esc_attr( trim( $val ) ) . '"';
       
  8952 			}
       
  8953 		}
       
  8954 	}
       
  8955 
       
  8956 	if ( false !== $args['paragraph_wrap'] ) {
       
  8957 		$message = "<p>$message</p>";
       
  8958 	}
       
  8959 
       
  8960 	$markup = sprintf( '<div %1$sclass="%2$s"%3$s>%4$s</div>', $id, $classes, $attributes, $message );
       
  8961 
       
  8962 	/**
       
  8963 	 * Filters the markup for an admin notice.
       
  8964 	 *
       
  8965 	 * @since 6.4.0
       
  8966 	 *
       
  8967 	 * @param string $markup  The HTML markup for the admin notice.
       
  8968 	 * @param string $message The message for the admin notice.
       
  8969 	 * @param array  $args    The arguments for the admin notice.
       
  8970 	 */
       
  8971 	return apply_filters( 'wp_admin_notice_markup', $markup, $message, $args );
       
  8972 }
       
  8973 
       
  8974 /**
       
  8975  * Outputs an admin notice.
       
  8976  *
       
  8977  * @since 6.4.0
       
  8978  *
       
  8979  * @param string $message The message to output.
       
  8980  * @param array  $args {
       
  8981  *     Optional. An array of arguments for the admin notice. Default empty array.
       
  8982  *
       
  8983  *     @type string   $type               Optional. The type of admin notice.
       
  8984  *                                        For example, 'error', 'success', 'warning', 'info'.
       
  8985  *                                        Default empty string.
       
  8986  *     @type bool     $dismissible        Optional. Whether the admin notice is dismissible. Default false.
       
  8987  *     @type string   $id                 Optional. The value of the admin notice's ID attribute. Default empty string.
       
  8988  *     @type string[] $additional_classes Optional. A string array of class names. Default empty array.
       
  8989  *     @type string[] $attributes         Optional. Additional attributes for the notice div. Default empty array.
       
  8990  *     @type bool     $paragraph_wrap     Optional. Whether to wrap the message in paragraph tags. Default true.
       
  8991  * }
       
  8992  */
       
  8993 function wp_admin_notice( $message, $args = array() ) {
       
  8994 	/**
       
  8995 	 * Fires before an admin notice is output.
       
  8996 	 *
       
  8997 	 * @since 6.4.0
       
  8998 	 *
       
  8999 	 * @param string $message The message for the admin notice.
       
  9000 	 * @param array  $args    The arguments for the admin notice.
       
  9001 	 */
       
  9002 	do_action( 'wp_admin_notice', $message, $args );
       
  9003 
       
  9004 	echo wp_kses_post( wp_get_admin_notice( $message, $args ) );
       
  9005 }