wp/wp-includes/functions.php
changeset 16 a86126ab1dd4
parent 13 d255fe9cd479
child 18 be944660c56a
equal deleted inserted replaced
15:3d4e9c994f10 16:a86126ab1dd4
     3  * Main WordPress API
     3  * Main WordPress API
     4  *
     4  *
     5  * @package WordPress
     5  * @package WordPress
     6  */
     6  */
     7 
     7 
     8 require( ABSPATH . WPINC . '/option.php' );
     8 require ABSPATH . WPINC . '/option.php';
     9 
     9 
    10 /**
    10 /**
    11  * Convert given date string into a different format.
    11  * Convert given MySQL date string into a different format.
    12  *
    12  *
    13  * $format should be either a PHP date format string, e.g. 'U' for a Unix
    13  * `$format` should be a PHP date format string.
    14  * timestamp, or 'G' for a Unix timestamp assuming that $date is GMT.
    14  * 'U' and 'G' formats will return a sum of timestamp with timezone offset.
    15  *
    15  * `$date` is expected to be local time in MySQL format (`Y-m-d H:i:s`).
    16  * If $translate is true then the given date and format string will
    16  *
    17  * be passed to date_i18n() for translation.
    17  * Historically UTC time could be passed to the function to produce Unix timestamp.
       
    18  *
       
    19  * If `$translate` is true then the given date and format string will
       
    20  * be passed to `wp_date()` for translation.
    18  *
    21  *
    19  * @since 0.71
    22  * @since 0.71
    20  *
    23  *
    21  * @param string $format    Format of the date to return.
    24  * @param string $format    Format of the date to return.
    22  * @param string $date      Date string to convert.
    25  * @param string $date      Date string to convert.
    23  * @param bool   $translate Whether the return date should be translated. Default true.
    26  * @param bool   $translate Whether the return date should be translated. Default true.
    24  * @return string|int|bool Formatted date string or Unix timestamp. False if $date is empty.
    27  * @return string|int|false Formatted date string or sum of Unix timestamp and timezone offset.
       
    28  *                          False on failure.
    25  */
    29  */
    26 function mysql2date( $format, $date, $translate = true ) {
    30 function mysql2date( $format, $date, $translate = true ) {
    27 	if ( empty( $date ) ) {
    31 	if ( empty( $date ) ) {
    28 		return false;
    32 		return false;
    29 	}
    33 	}
    30 
    34 
    31 	if ( 'G' == $format ) {
    35 	$datetime = date_create( $date, wp_timezone() );
    32 		return strtotime( $date . ' +0000' );
    36 
    33 	}
    37 	if ( false === $datetime ) {
    34 
    38 		return false;
    35 	$i = strtotime( $date );
    39 	}
    36 
    40 
    37 	if ( 'U' == $format ) {
    41 	// Returns a sum of timestamp with timezone offset. Ideally should never be used.
    38 		return $i;
    42 	if ( 'G' === $format || 'U' === $format ) {
       
    43 		return $datetime->getTimestamp() + $datetime->getOffset();
    39 	}
    44 	}
    40 
    45 
    41 	if ( $translate ) {
    46 	if ( $translate ) {
    42 		return date_i18n( $format, $i );
    47 		return wp_date( $format, $datetime->getTimestamp() );
    43 	} else {
    48 	}
    44 		return date( $format, $i );
    49 
    45 	}
    50 	return $datetime->format( $format );
    46 }
    51 }
    47 
    52 
    48 /**
    53 /**
    49  * Retrieve the current time based on specified type.
    54  * Retrieves the current time based on specified type.
    50  *
    55  *
    51  * The 'mysql' type will return the time in the format for MySQL DATETIME field.
    56  * The 'mysql' type will return the time in the format for MySQL DATETIME field.
    52  * The 'timestamp' type will return the current timestamp.
    57  * The 'timestamp' type will return the current timestamp or a sum of timestamp
       
    58  * and timezone offset, depending on `$gmt`.
    53  * Other strings will be interpreted as PHP date formats (e.g. 'Y-m-d').
    59  * Other strings will be interpreted as PHP date formats (e.g. 'Y-m-d').
    54  *
    60  *
    55  * If $gmt is set to either '1' or 'true', then both types will use GMT time.
    61  * If $gmt is set to either '1' or 'true', then both types will use GMT time.
    56  * if $gmt is false, the output is adjusted with the GMT offset in the WordPress option.
    62  * if $gmt is false, the output is adjusted with the GMT offset in the WordPress option.
    57  *
    63  *
    58  * @since 1.0.0
    64  * @since 1.0.0
    59  *
    65  *
    60  * @param string   $type Type of time to retrieve. Accepts 'mysql', 'timestamp', or PHP date
    66  * @param string   $type Type of time to retrieve. Accepts 'mysql', 'timestamp',
    61  *                       format string (e.g. 'Y-m-d').
    67  *                       or PHP date format string (e.g. 'Y-m-d').
    62  * @param int|bool $gmt  Optional. Whether to use GMT timezone. Default false.
    68  * @param int|bool $gmt  Optional. Whether to use GMT timezone. Default false.
    63  * @return int|string Integer if $type is 'timestamp', string otherwise.
    69  * @return int|string Integer if $type is 'timestamp', string otherwise.
    64  */
    70  */
    65 function current_time( $type, $gmt = 0 ) {
    71 function current_time( $type, $gmt = 0 ) {
    66 	switch ( $type ) {
    72 	// Don't use non-GMT timestamp, unless you know the difference and really need to.
    67 		case 'mysql':
    73 	if ( 'timestamp' === $type || 'U' === $type ) {
    68 			return ( $gmt ) ? gmdate( 'Y-m-d H:i:s' ) : gmdate( 'Y-m-d H:i:s', ( time() + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ) ) );
    74 		return $gmt ? time() : time() + (int) ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS );
    69 		case 'timestamp':
    75 	}
    70 			return ( $gmt ) ? time() : time() + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS );
    76 
    71 		default:
    77 	if ( 'mysql' === $type ) {
    72 			return ( $gmt ) ? gmdate( $type ) : gmdate( $type, time() + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ) );
    78 		$type = 'Y-m-d H:i:s';
    73 	}
    79 	}
    74 }
    80 
    75 
    81 	$timezone = $gmt ? new DateTimeZone( 'UTC' ) : wp_timezone();
    76 /**
    82 	$datetime = new DateTime( 'now', $timezone );
    77  * Retrieve the date in localized format, based on a sum of Unix timestamp and
    83 
       
    84 	return $datetime->format( $type );
       
    85 }
       
    86 
       
    87 /**
       
    88  * Retrieves the current time as an object with the timezone from settings.
       
    89  *
       
    90  * @since 5.3.0
       
    91  *
       
    92  * @return DateTimeImmutable Date and time object.
       
    93  */
       
    94 function current_datetime() {
       
    95 	return new DateTimeImmutable( 'now', wp_timezone() );
       
    96 }
       
    97 
       
    98 /**
       
    99  * Retrieves the timezone from site settings as a string.
       
   100  *
       
   101  * Uses the `timezone_string` option to get a proper timezone if available,
       
   102  * otherwise falls back to an offset.
       
   103  *
       
   104  * @since 5.3.0
       
   105  *
       
   106  * @return string PHP timezone string or a ±HH:MM offset.
       
   107  */
       
   108 function wp_timezone_string() {
       
   109 	$timezone_string = get_option( 'timezone_string' );
       
   110 
       
   111 	if ( $timezone_string ) {
       
   112 		return $timezone_string;
       
   113 	}
       
   114 
       
   115 	$offset  = (float) get_option( 'gmt_offset' );
       
   116 	$hours   = (int) $offset;
       
   117 	$minutes = ( $offset - $hours );
       
   118 
       
   119 	$sign      = ( $offset < 0 ) ? '-' : '+';
       
   120 	$abs_hour  = abs( $hours );
       
   121 	$abs_mins  = abs( $minutes * 60 );
       
   122 	$tz_offset = sprintf( '%s%02d:%02d', $sign, $abs_hour, $abs_mins );
       
   123 
       
   124 	return $tz_offset;
       
   125 }
       
   126 
       
   127 /**
       
   128  * Retrieves the timezone from site settings as a `DateTimeZone` object.
       
   129  *
       
   130  * Timezone can be based on a PHP timezone string or a ±HH:MM offset.
       
   131  *
       
   132  * @since 5.3.0
       
   133  *
       
   134  * @return DateTimeZone Timezone object.
       
   135  */
       
   136 function wp_timezone() {
       
   137 	return new DateTimeZone( wp_timezone_string() );
       
   138 }
       
   139 
       
   140 /**
       
   141  * Retrieves the date in localized format, based on a sum of Unix timestamp and
    78  * timezone offset in seconds.
   142  * timezone offset in seconds.
    79  *
   143  *
    80  * If the locale specifies the locale month and weekday, then the locale will
   144  * If the locale specifies the locale month and weekday, then the locale will
    81  * take over the format for the date. If it isn't, then the date format string
   145  * take over the format for the date. If it isn't, then the date format string
    82  * will be used instead.
   146  * will be used instead.
    83  *
   147  *
       
   148  * Note that due to the way WP typically generates a sum of timestamp and offset
       
   149  * with `strtotime()`, it implies offset added at a _current_ time, not at the time
       
   150  * the timestamp represents. Storing such timestamps or calculating them differently
       
   151  * will lead to invalid output.
       
   152  *
    84  * @since 0.71
   153  * @since 0.71
    85  *
   154  * @since 5.3.0 Converted into a wrapper for wp_date().
    86  * @global WP_Locale $wp_locale
   155  *
    87  *
   156  * @global WP_Locale $wp_locale WordPress date and time locale object.
    88  * @param string   $dateformatstring      Format to display the date.
   157  *
    89  * @param int|bool $timestamp_with_offset Optional. A sum of Unix timestamp and timezone offset in seconds.
   158  * @param string   $format                Format to display the date.
    90  *                                        Default false.
   159  * @param int|bool $timestamp_with_offset Optional. A sum of Unix timestamp and timezone offset
    91  * @param bool     $gmt                   Optional. Whether to use GMT timezone. Only applies if timestamp is
   160  *                                        in seconds. Default false.
    92  *                                        not provided. Default false.
   161  * @param bool     $gmt                   Optional. Whether to use GMT timezone. Only applies
    93  *
   162  *                                        if timestamp is not provided. Default false.
    94  * @return string The date, translated if locale specifies it.
   163  * @return string The date, translated if locale specifies it.
    95  */
   164  */
    96 function date_i18n( $dateformatstring, $timestamp_with_offset = false, $gmt = false ) {
   165 function date_i18n( $format, $timestamp_with_offset = false, $gmt = false ) {
    97 	global $wp_locale;
   166 	$timestamp = $timestamp_with_offset;
    98 	$i = $timestamp_with_offset;
   167 
    99 
   168 	// If timestamp is omitted it should be current time (summed with offset, unless `$gmt` is true).
   100 	if ( false === $i ) {
   169 	if ( ! is_numeric( $timestamp ) ) {
   101 		$i = current_time( 'timestamp', $gmt );
   170 		$timestamp = current_time( 'timestamp', $gmt );
   102 	}
   171 	}
   103 
   172 
   104 	/*
   173 	/*
   105 	 * Store original value for language with untypical grammars.
   174 	 * This is a legacy implementation quirk that the returned timestamp is also with offset.
   106 	 * See https://core.trac.wordpress.org/ticket/9396
   175 	 * Ideally this function should never be used to produce a timestamp.
   107 	 */
   176 	 */
   108 	$req_format = $dateformatstring;
   177 	if ( 'U' === $format ) {
   109 
   178 		$date = $timestamp;
   110 	$dateformatstring = preg_replace( '/(?<!\\\\)c/', DATE_W3C, $dateformatstring );
   179 	} elseif ( $gmt && false === $timestamp_with_offset ) { // Current time in UTC.
   111 	$dateformatstring = preg_replace( '/(?<!\\\\)r/', DATE_RFC2822, $dateformatstring );
   180 		$date = wp_date( $format, null, new DateTimeZone( 'UTC' ) );
   112 
   181 	} elseif ( false === $timestamp_with_offset ) { // Current time in site's timezone.
   113 	if ( ( ! empty( $wp_locale->month ) ) && ( ! empty( $wp_locale->weekday ) ) ) {
   182 		$date = wp_date( $format );
   114 		$datemonth            = $wp_locale->get_month( date( 'm', $i ) );
   183 	} else {
   115 		$datemonth_abbrev     = $wp_locale->get_month_abbrev( $datemonth );
   184 		/*
   116 		$dateweekday          = $wp_locale->get_weekday( date( 'w', $i ) );
   185 		 * Timestamp with offset is typically produced by a UTC `strtotime()` call on an input without timezone.
   117 		$dateweekday_abbrev   = $wp_locale->get_weekday_abbrev( $dateweekday );
   186 		 * This is the best attempt to reverse that operation into a local time to use.
   118 		$datemeridiem         = $wp_locale->get_meridiem( date( 'a', $i ) );
   187 		 */
   119 		$datemeridiem_capital = $wp_locale->get_meridiem( date( 'A', $i ) );
   188 		$local_time = gmdate( 'Y-m-d H:i:s', $timestamp );
   120 		$dateformatstring     = ' ' . $dateformatstring;
   189 		$timezone   = wp_timezone();
   121 		$dateformatstring     = preg_replace( '/([^\\\])D/', "\\1" . backslashit( $dateweekday_abbrev ), $dateformatstring );
   190 		$datetime   = date_create( $local_time, $timezone );
   122 		$dateformatstring     = preg_replace( '/([^\\\])F/', "\\1" . backslashit( $datemonth ), $dateformatstring );
   191 		$date       = wp_date( $format, $datetime->getTimestamp(), $timezone );
   123 		$dateformatstring     = preg_replace( '/([^\\\])l/', "\\1" . backslashit( $dateweekday ), $dateformatstring );
   192 	}
   124 		$dateformatstring     = preg_replace( '/([^\\\])M/', "\\1" . backslashit( $datemonth_abbrev ), $dateformatstring );
       
   125 		$dateformatstring     = preg_replace( '/([^\\\])a/', "\\1" . backslashit( $datemeridiem ), $dateformatstring );
       
   126 		$dateformatstring     = preg_replace( '/([^\\\])A/', "\\1" . backslashit( $datemeridiem_capital ), $dateformatstring );
       
   127 
       
   128 		$dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) - 1 );
       
   129 	}
       
   130 	$timezone_formats    = array( 'P', 'I', 'O', 'T', 'Z', 'e' );
       
   131 	$timezone_formats_re = implode( '|', $timezone_formats );
       
   132 	if ( preg_match( "/$timezone_formats_re/", $dateformatstring ) ) {
       
   133 		$timezone_string = get_option( 'timezone_string' );
       
   134 		if ( false === $timestamp_with_offset && $gmt ) {
       
   135 			$timezone_string = 'UTC';
       
   136 		}
       
   137 		if ( $timezone_string ) {
       
   138 			$timezone_object = timezone_open( $timezone_string );
       
   139 			$date_object     = date_create( null, $timezone_object );
       
   140 			foreach ( $timezone_formats as $timezone_format ) {
       
   141 				if ( false !== strpos( $dateformatstring, $timezone_format ) ) {
       
   142 					$formatted        = date_format( $date_object, $timezone_format );
       
   143 					$dateformatstring = ' ' . $dateformatstring;
       
   144 					$dateformatstring = preg_replace( "/([^\\\])$timezone_format/", "\\1" . backslashit( $formatted ), $dateformatstring );
       
   145 					$dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) - 1 );
       
   146 				}
       
   147 			}
       
   148 		} else {
       
   149 			$offset = get_option( 'gmt_offset' );
       
   150 			foreach ( $timezone_formats as $timezone_format ) {
       
   151 				if ( 'I' === $timezone_format ) {
       
   152 					continue;
       
   153 				}
       
   154 
       
   155 				if ( false !== strpos( $dateformatstring, $timezone_format ) ) {
       
   156 					if ( 'Z' === $timezone_format ) {
       
   157 						$formatted = (string) ( $offset * HOUR_IN_SECONDS );
       
   158 					} else {
       
   159 						$prefix    = '';
       
   160 						$hours     = (int) $offset;
       
   161 						$separator = '';
       
   162 						$minutes   = abs( ( $offset - $hours ) * 60 );
       
   163 
       
   164 						if ( 'T' === $timezone_format ) {
       
   165 							$prefix = 'GMT';
       
   166 						} elseif ( 'e' === $timezone_format || 'P' === $timezone_format ) {
       
   167 							$separator = ':';
       
   168 						}
       
   169 
       
   170 						$formatted = sprintf( '%s%+03d%s%02d', $prefix, $hours, $separator, $minutes );
       
   171 					}
       
   172 
       
   173 					$dateformatstring = ' ' . $dateformatstring;
       
   174 					$dateformatstring = preg_replace( "/([^\\\])$timezone_format/", "\\1" . backslashit( $formatted ), $dateformatstring );
       
   175 					$dateformatstring = substr( $dateformatstring, 1 );
       
   176 				}
       
   177 			}
       
   178 		}
       
   179 	}
       
   180 	$j = @date( $dateformatstring, $i );
       
   181 
   193 
   182 	/**
   194 	/**
   183 	 * Filters the date formatted based on the locale.
   195 	 * Filters the date formatted based on the locale.
   184 	 *
   196 	 *
   185 	 * @since 2.8.0
   197 	 * @since 2.8.0
   186 	 *
   198 	 *
   187 	 * @param string $j          Formatted date string.
   199 	 * @param string $date      Formatted date string.
   188 	 * @param string $req_format Format to display the date.
   200 	 * @param string $format    Format to display the date.
   189 	 * @param int    $i          A sum of Unix timestamp and timezone offset in seconds.
   201 	 * @param int    $timestamp A sum of Unix timestamp and timezone offset in seconds.
   190 	 * @param bool   $gmt        Whether to use GMT timezone. Only applies if timestamp was
   202 	 *                          Might be without offset if input omitted timestamp but requested GMT.
   191 	 *                           not provided. Default false.
   203 	 * @param bool   $gmt       Whether to use GMT timezone. Only applies if timestamp was not provided.
       
   204 	 *                          Default false.
   192 	 */
   205 	 */
   193 	$j = apply_filters( 'date_i18n', $j, $req_format, $i, $gmt );
   206 	$date = apply_filters( 'date_i18n', $date, $format, $timestamp, $gmt );
   194 	return $j;
   207 
       
   208 	return $date;
       
   209 }
       
   210 
       
   211 /**
       
   212  * Retrieves the date, in localized format.
       
   213  *
       
   214  * This is a newer function, intended to replace `date_i18n()` without legacy quirks in it.
       
   215  *
       
   216  * Note that, unlike `date_i18n()`, this function accepts a true Unix timestamp, not summed
       
   217  * with timezone offset.
       
   218  *
       
   219  * @since 5.3.0
       
   220  *
       
   221  * @param string       $format    PHP date format.
       
   222  * @param int          $timestamp Optional. Unix timestamp. Defaults to current time.
       
   223  * @param DateTimeZone $timezone  Optional. Timezone to output result in. Defaults to timezone
       
   224  *                                from site settings.
       
   225  * @return string|false The date, translated if locale specifies it. False on invalid timestamp input.
       
   226  */
       
   227 function wp_date( $format, $timestamp = null, $timezone = null ) {
       
   228 	global $wp_locale;
       
   229 
       
   230 	if ( null === $timestamp ) {
       
   231 		$timestamp = time();
       
   232 	} elseif ( ! is_numeric( $timestamp ) ) {
       
   233 		return false;
       
   234 	}
       
   235 
       
   236 	if ( ! $timezone ) {
       
   237 		$timezone = wp_timezone();
       
   238 	}
       
   239 
       
   240 	$datetime = date_create( '@' . $timestamp );
       
   241 	$datetime->setTimezone( $timezone );
       
   242 
       
   243 	if ( empty( $wp_locale->month ) || empty( $wp_locale->weekday ) ) {
       
   244 		$date = $datetime->format( $format );
       
   245 	} else {
       
   246 		// We need to unpack shorthand `r` format because it has parts that might be localized.
       
   247 		$format = preg_replace( '/(?<!\\\\)r/', DATE_RFC2822, $format );
       
   248 
       
   249 		$new_format    = '';
       
   250 		$format_length = strlen( $format );
       
   251 		$month         = $wp_locale->get_month( $datetime->format( 'm' ) );
       
   252 		$weekday       = $wp_locale->get_weekday( $datetime->format( 'w' ) );
       
   253 
       
   254 		for ( $i = 0; $i < $format_length; $i ++ ) {
       
   255 			switch ( $format[ $i ] ) {
       
   256 				case 'D':
       
   257 					$new_format .= addcslashes( $wp_locale->get_weekday_abbrev( $weekday ), '\\A..Za..z' );
       
   258 					break;
       
   259 				case 'F':
       
   260 					$new_format .= addcslashes( $month, '\\A..Za..z' );
       
   261 					break;
       
   262 				case 'l':
       
   263 					$new_format .= addcslashes( $weekday, '\\A..Za..z' );
       
   264 					break;
       
   265 				case 'M':
       
   266 					$new_format .= addcslashes( $wp_locale->get_month_abbrev( $month ), '\\A..Za..z' );
       
   267 					break;
       
   268 				case 'a':
       
   269 					$new_format .= addcslashes( $wp_locale->get_meridiem( $datetime->format( 'a' ) ), '\\A..Za..z' );
       
   270 					break;
       
   271 				case 'A':
       
   272 					$new_format .= addcslashes( $wp_locale->get_meridiem( $datetime->format( 'A' ) ), '\\A..Za..z' );
       
   273 					break;
       
   274 				case '\\':
       
   275 					$new_format .= $format[ $i ];
       
   276 
       
   277 					// If character follows a slash, we add it without translating.
       
   278 					if ( $i < $format_length ) {
       
   279 						$new_format .= $format[ ++$i ];
       
   280 					}
       
   281 					break;
       
   282 				default:
       
   283 					$new_format .= $format[ $i ];
       
   284 					break;
       
   285 			}
       
   286 		}
       
   287 
       
   288 		$date = $datetime->format( $new_format );
       
   289 		$date = wp_maybe_decline_date( $date, $format );
       
   290 	}
       
   291 
       
   292 	/**
       
   293 	 * Filters the date formatted based on the locale.
       
   294 	 *
       
   295 	 * @since 5.3.0
       
   296 	 *
       
   297 	 * @param string       $date      Formatted date string.
       
   298 	 * @param string       $format    Format to display the date.
       
   299 	 * @param int          $timestamp Unix timestamp.
       
   300 	 * @param DateTimeZone $timezone  Timezone.
       
   301 	 */
       
   302 	$date = apply_filters( 'wp_date', $date, $format, $timestamp, $timezone );
       
   303 
       
   304 	return $date;
   195 }
   305 }
   196 
   306 
   197 /**
   307 /**
   198  * Determines if the date should be declined.
   308  * Determines if the date should be declined.
   199  *
   309  *
   200  * If the locale specifies that month names require a genitive case in certain
   310  * If the locale specifies that month names require a genitive case in certain
   201  * formats (like 'j F Y'), the month name will be replaced with a correct form.
   311  * formats (like 'j F Y'), the month name will be replaced with a correct form.
   202  *
   312  *
   203  * @since 4.4.0
   313  * @since 4.4.0
   204  *
   314  * @since 5.4.0 The `$format` parameter was added.
   205  * @global WP_Locale $wp_locale
   315  *
   206  *
   316  * @global WP_Locale $wp_locale WordPress date and time locale object.
   207  * @param string $date Formatted date string.
   317  *
       
   318  * @param string $date   Formatted date string.
       
   319  * @param string $format Optional. Date format to check. Default empty string.
   208  * @return string The date, declined if locale specifies it.
   320  * @return string The date, declined if locale specifies it.
   209  */
   321  */
   210 function wp_maybe_decline_date( $date ) {
   322 function wp_maybe_decline_date( $date, $format = '' ) {
   211 	global $wp_locale;
   323 	global $wp_locale;
   212 
   324 
   213 	// i18n functions are not available in SHORTINIT mode
   325 	// i18n functions are not available in SHORTINIT mode.
   214 	if ( ! function_exists( '_x' ) ) {
   326 	if ( ! function_exists( '_x' ) ) {
   215 		return $date;
   327 		return $date;
   216 	}
   328 	}
   217 
   329 
   218 	/* translators: If months in your language require a genitive case,
   330 	/*
       
   331 	 * translators: If months in your language require a genitive case,
   219 	 * translate this to 'on'. Do not translate into your own language.
   332 	 * translate this to 'on'. Do not translate into your own language.
   220 	 */
   333 	 */
   221 	if ( 'on' === _x( 'off', 'decline months names: on or off' ) ) {
   334 	if ( 'on' === _x( 'off', 'decline months names: on or off' ) ) {
   222 		// Match a format like 'j F Y' or 'j. F'
   335 
   223 		if ( @preg_match( '#^\d{1,2}\.? [^\d ]+#u', $date ) ) {
   336 		$months          = $wp_locale->month;
   224 			$months          = $wp_locale->month;
   337 		$months_genitive = $wp_locale->month_genitive;
   225 			$months_genitive = $wp_locale->month_genitive;
   338 
   226 
   339 		/*
       
   340 		 * Match a format like 'j F Y' or 'j. F' (day of the month, followed by month name)
       
   341 		 * and decline the month.
       
   342 		 */
       
   343 		if ( $format ) {
       
   344 			$decline = preg_match( '#[dj]\.? F#', $format );
       
   345 		} else {
       
   346 			// If the format is not passed, try to guess it from the date string.
       
   347 			$decline = preg_match( '#\b\d{1,2}\.? [^\d ]+\b#u', $date );
       
   348 		}
       
   349 
       
   350 		if ( $decline ) {
   227 			foreach ( $months as $key => $month ) {
   351 			foreach ( $months as $key => $month ) {
   228 				$months[ $key ] = '# ' . $month . '( |$)#u';
   352 				$months[ $key ] = '# ' . preg_quote( $month, '#' ) . '\b#u';
   229 			}
   353 			}
   230 
   354 
   231 			foreach ( $months_genitive as $key => $month ) {
   355 			foreach ( $months_genitive as $key => $month ) {
   232 				$months_genitive[ $key ] = ' ' . $month . '$1';
   356 				$months_genitive[ $key ] = ' ' . $month;
   233 			}
   357 			}
   234 
   358 
   235 			$date = preg_replace( $months, $months_genitive, $date );
   359 			$date = preg_replace( $months, $months_genitive, $date );
   236 		}
   360 		}
   237 	}
   361 
   238 
   362 		/*
   239 	// Used for locale-specific rules
   363 		 * Match a format like 'F jS' or 'F j' (month name, followed by day with an optional ordinal suffix)
       
   364 		 * and change it to declined 'j F'.
       
   365 		 */
       
   366 		if ( $format ) {
       
   367 			$decline = preg_match( '#F [dj]#', $format );
       
   368 		} else {
       
   369 			// If the format is not passed, try to guess it from the date string.
       
   370 			$decline = preg_match( '#\b[^\d ]+ \d{1,2}(st|nd|rd|th)?\b#u', trim( $date ) );
       
   371 		}
       
   372 
       
   373 		if ( $decline ) {
       
   374 			foreach ( $months as $key => $month ) {
       
   375 				$months[ $key ] = '#\b' . preg_quote( $month, '#' ) . ' (\d{1,2})(st|nd|rd|th)?([-–]\d{1,2})?(st|nd|rd|th)?\b#u';
       
   376 			}
       
   377 
       
   378 			foreach ( $months_genitive as $key => $month ) {
       
   379 				$months_genitive[ $key ] = '$1$3 ' . $month;
       
   380 			}
       
   381 
       
   382 			$date = preg_replace( $months, $months_genitive, $date );
       
   383 		}
       
   384 	}
       
   385 
       
   386 	// Used for locale-specific rules.
   240 	$locale = get_locale();
   387 	$locale = get_locale();
   241 
   388 
   242 	if ( 'ca' === $locale ) {
   389 	if ( 'ca' === $locale ) {
   243 		// " de abril| de agost| de octubre..." -> " d'abril| d'agost| d'octubre..."
   390 		// " de abril| de agost| de octubre..." -> " d'abril| d'agost| d'octubre..."
   244 		$date = preg_replace( '# de ([ao])#i', " d'\\1", $date );
   391 		$date = preg_replace( '# de ([ao])#i', " d'\\1", $date );
   250 /**
   397 /**
   251  * Convert float number to format based on the locale.
   398  * Convert float number to format based on the locale.
   252  *
   399  *
   253  * @since 2.3.0
   400  * @since 2.3.0
   254  *
   401  *
   255  * @global WP_Locale $wp_locale
   402  * @global WP_Locale $wp_locale WordPress date and time locale object.
   256  *
   403  *
   257  * @param float $number   The number to convert based on locale.
   404  * @param float $number   The number to convert based on locale.
   258  * @param int   $decimals Optional. Precision of the number of decimal places. Default 0.
   405  * @param int   $decimals Optional. Precision of the number of decimal places. Default 0.
   259  * @return string Converted number in string format.
   406  * @return string Converted number in string format.
   260  */
   407  */
   296  *
   443  *
   297  * @since 2.3.0
   444  * @since 2.3.0
   298  *
   445  *
   299  * @param int|string $bytes    Number of bytes. Note max integer size for integers.
   446  * @param int|string $bytes    Number of bytes. Note max integer size for integers.
   300  * @param int        $decimals Optional. Precision of number of decimal places. Default 0.
   447  * @param int        $decimals Optional. Precision of number of decimal places. Default 0.
   301  * @return string|false False on failure. Number string on success.
   448  * @return string|false Number string on success, false on failure.
   302  */
   449  */
   303 function size_format( $bytes, $decimals = 0 ) {
   450 function size_format( $bytes, $decimals = 0 ) {
   304 	$quant = array(
   451 	$quant = array(
   305 		'TB' => TB_IN_BYTES,
   452 		/* translators: Unit symbol for terabyte. */
   306 		'GB' => GB_IN_BYTES,
   453 		_x( 'TB', 'unit symbol' ) => TB_IN_BYTES,
   307 		'MB' => MB_IN_BYTES,
   454 		/* translators: Unit symbol for gigabyte. */
   308 		'KB' => KB_IN_BYTES,
   455 		_x( 'GB', 'unit symbol' ) => GB_IN_BYTES,
   309 		'B'  => 1,
   456 		/* translators: Unit symbol for megabyte. */
       
   457 		_x( 'MB', 'unit symbol' ) => MB_IN_BYTES,
       
   458 		/* translators: Unit symbol for kilobyte. */
       
   459 		_x( 'KB', 'unit symbol' ) => KB_IN_BYTES,
       
   460 		/* translators: Unit symbol for byte. */
       
   461 		_x( 'B', 'unit symbol' )  => 1,
   310 	);
   462 	);
   311 
   463 
   312 	if ( 0 === $bytes ) {
   464 	if ( 0 === $bytes ) {
   313 		return number_format_i18n( 0, $decimals ) . ' B';
   465 		/* translators: Unit symbol for byte. */
       
   466 		return number_format_i18n( 0, $decimals ) . ' ' . _x( 'B', 'unit symbol' );
   314 	}
   467 	}
   315 
   468 
   316 	foreach ( $quant as $unit => $mag ) {
   469 	foreach ( $quant as $unit => $mag ) {
   317 		if ( doubleval( $bytes ) >= $mag ) {
   470 		if ( doubleval( $bytes ) >= $mag ) {
   318 			return number_format_i18n( $bytes / $mag, $decimals ) . ' ' . $unit;
   471 			return number_format_i18n( $bytes / $mag, $decimals ) . ' ' . $unit;
   371 
   524 
   372 	$human_readable_duration = array();
   525 	$human_readable_duration = array();
   373 
   526 
   374 	// Add the hour part to the string.
   527 	// Add the hour part to the string.
   375 	if ( is_numeric( $hour ) ) {
   528 	if ( is_numeric( $hour ) ) {
   376 		/* translators: Time duration in hour or hours. */
   529 		/* translators: %s: Time duration in hour or hours. */
   377 		$human_readable_duration[] = sprintf( _n( '%s hour', '%s hours', $hour ), (int) $hour );
   530 		$human_readable_duration[] = sprintf( _n( '%s hour', '%s hours', $hour ), (int) $hour );
   378 	}
   531 	}
   379 
   532 
   380 	// Add the minute part to the string.
   533 	// Add the minute part to the string.
   381 	if ( is_numeric( $minute ) ) {
   534 	if ( is_numeric( $minute ) ) {
   382 		/* translators: Time duration in minute or minutes. */
   535 		/* translators: %s: Time duration in minute or minutes. */
   383 		$human_readable_duration[] = sprintf( _n( '%s minute', '%s minutes', $minute ), (int) $minute );
   536 		$human_readable_duration[] = sprintf( _n( '%s minute', '%s minutes', $minute ), (int) $minute );
   384 	}
   537 	}
   385 
   538 
   386 	// Add the second part to the string.
   539 	// Add the second part to the string.
   387 	if ( is_numeric( $second ) ) {
   540 	if ( is_numeric( $second ) ) {
   388 		/* translators: Time duration in second or seconds. */
   541 		/* translators: %s: Time duration in second or seconds. */
   389 		$human_readable_duration[] = sprintf( _n( '%s second', '%s seconds', $second ), (int) $second );
   542 		$human_readable_duration[] = sprintf( _n( '%s second', '%s seconds', $second ), (int) $second );
   390 	}
   543 	}
   391 
   544 
   392 	return implode( ', ', $human_readable_duration );
   545 	return implode( ', ', $human_readable_duration );
   393 }
   546 }
   413 
   566 
   414 	// The timestamp for MySQL string day.
   567 	// The timestamp for MySQL string day.
   415 	$day = mktime( 0, 0, 0, $md, $mm, $my );
   568 	$day = mktime( 0, 0, 0, $md, $mm, $my );
   416 
   569 
   417 	// The day of the week from the timestamp.
   570 	// The day of the week from the timestamp.
   418 	$weekday = date( 'w', $day );
   571 	$weekday = gmdate( 'w', $day );
   419 
   572 
   420 	if ( ! is_numeric( $start_of_week ) ) {
   573 	if ( ! is_numeric( $start_of_week ) ) {
   421 		$start_of_week = get_option( 'start_of_week' );
   574 		$start_of_week = get_option( 'start_of_week' );
   422 	}
   575 	}
   423 
   576 
   432 	$end = $start + WEEK_IN_SECONDS - 1;
   585 	$end = $start + WEEK_IN_SECONDS - 1;
   433 	return compact( 'start', 'end' );
   586 	return compact( 'start', 'end' );
   434 }
   587 }
   435 
   588 
   436 /**
   589 /**
   437  * Unserialize value only if it was serialized.
   590  * Serialize data, if needed.
       
   591  *
       
   592  * @since 2.0.5
       
   593  *
       
   594  * @param string|array|object $data Data that might be serialized.
       
   595  * @return mixed A scalar data.
       
   596  */
       
   597 function maybe_serialize( $data ) {
       
   598 	if ( is_array( $data ) || is_object( $data ) ) {
       
   599 		return serialize( $data );
       
   600 	}
       
   601 
       
   602 	/*
       
   603 	 * Double serialization is required for backward compatibility.
       
   604 	 * See https://core.trac.wordpress.org/ticket/12930
       
   605 	 * Also the world will end. See WP 3.6.1.
       
   606 	 */
       
   607 	if ( is_serialized( $data, false ) ) {
       
   608 		return serialize( $data );
       
   609 	}
       
   610 
       
   611 	return $data;
       
   612 }
       
   613 
       
   614 /**
       
   615  * Unserialize data only if it was serialized.
   438  *
   616  *
   439  * @since 2.0.0
   617  * @since 2.0.0
   440  *
   618  *
   441  * @param string $original Maybe unserialized original, if is needed.
   619  * @param string $data Data that might be unserialized.
   442  * @return mixed Unserialized data can be any type.
   620  * @return mixed Unserialized data can be any type.
   443  */
   621  */
   444 function maybe_unserialize( $original ) {
   622 function maybe_unserialize( $data ) {
   445 	if ( is_serialized( $original ) ) { // don't attempt to unserialize data that wasn't serialized going in
   623 	if ( is_serialized( $data ) ) { // Don't attempt to unserialize data that wasn't serialized going in.
   446 		return @unserialize( $original );
   624 		return @unserialize( trim( $data ) );
   447 	}
   625 	}
   448 	return $original;
   626 
       
   627 	return $data;
   449 }
   628 }
   450 
   629 
   451 /**
   630 /**
   452  * Check value to find if it was serialized.
   631  * Check value to find if it was serialized.
   453  *
   632  *
   459  * @param string $data   Value to check to see if was serialized.
   638  * @param string $data   Value to check to see if was serialized.
   460  * @param bool   $strict Optional. Whether to be strict about the end of the string. Default true.
   639  * @param bool   $strict Optional. Whether to be strict about the end of the string. Default true.
   461  * @return bool False if not serialized and true if it was.
   640  * @return bool False if not serialized and true if it was.
   462  */
   641  */
   463 function is_serialized( $data, $strict = true ) {
   642 function is_serialized( $data, $strict = true ) {
   464 	// if it isn't a string, it isn't serialized.
   643 	// If it isn't a string, it isn't serialized.
   465 	if ( ! is_string( $data ) ) {
   644 	if ( ! is_string( $data ) ) {
   466 		return false;
   645 		return false;
   467 	}
   646 	}
   468 	$data = trim( $data );
   647 	$data = trim( $data );
   469 	if ( 'N;' == $data ) {
   648 	if ( 'N;' === $data ) {
   470 		return true;
   649 		return true;
   471 	}
   650 	}
   472 	if ( strlen( $data ) < 4 ) {
   651 	if ( strlen( $data ) < 4 ) {
   473 		return false;
   652 		return false;
   474 	}
   653 	}
   503 					return false;
   682 					return false;
   504 				}
   683 				}
   505 			} elseif ( false === strpos( $data, '"' ) ) {
   684 			} elseif ( false === strpos( $data, '"' ) ) {
   506 				return false;
   685 				return false;
   507 			}
   686 			}
   508 			// or else fall through
   687 			// Or else fall through.
   509 		case 'a':
   688 		case 'a':
   510 		case 'O':
   689 		case 'O':
   511 			return (bool) preg_match( "/^{$token}:[0-9]+:/s", $data );
   690 			return (bool) preg_match( "/^{$token}:[0-9]+:/s", $data );
   512 		case 'b':
   691 		case 'b':
   513 		case 'i':
   692 		case 'i':
   514 		case 'd':
   693 		case 'd':
   515 			$end = $strict ? '$' : '';
   694 			$end = $strict ? '$' : '';
   516 			return (bool) preg_match( "/^{$token}:[0-9.E-]+;$end/", $data );
   695 			return (bool) preg_match( "/^{$token}:[0-9.E+-]+;$end/", $data );
   517 	}
   696 	}
   518 	return false;
   697 	return false;
   519 }
   698 }
   520 
   699 
   521 /**
   700 /**
   536 		return false;
   715 		return false;
   537 	} elseif ( ':' !== $data[1] ) {
   716 	} elseif ( ':' !== $data[1] ) {
   538 		return false;
   717 		return false;
   539 	} elseif ( ';' !== substr( $data, -1 ) ) {
   718 	} elseif ( ';' !== substr( $data, -1 ) ) {
   540 		return false;
   719 		return false;
   541 	} elseif ( $data[0] !== 's' ) {
   720 	} elseif ( 's' !== $data[0] ) {
   542 		return false;
   721 		return false;
   543 	} elseif ( '"' !== substr( $data, -2, 1 ) ) {
   722 	} elseif ( '"' !== substr( $data, -2, 1 ) ) {
   544 		return false;
   723 		return false;
   545 	} else {
   724 	} else {
   546 		return true;
   725 		return true;
   547 	}
   726 	}
   548 }
       
   549 
       
   550 /**
       
   551  * Serialize data, if needed.
       
   552  *
       
   553  * @since 2.0.5
       
   554  *
       
   555  * @param string|array|object $data Data that might be serialized.
       
   556  * @return mixed A scalar data
       
   557  */
       
   558 function maybe_serialize( $data ) {
       
   559 	if ( is_array( $data ) || is_object( $data ) ) {
       
   560 		return serialize( $data );
       
   561 	}
       
   562 
       
   563 	// Double serialization is required for backward compatibility.
       
   564 	// See https://core.trac.wordpress.org/ticket/12930
       
   565 	// Also the world will end. See WP 3.6.1.
       
   566 	if ( is_serialized( $data, false ) ) {
       
   567 		return serialize( $data );
       
   568 	}
       
   569 
       
   570 	return $data;
       
   571 }
   727 }
   572 
   728 
   573 /**
   729 /**
   574  * Retrieve post title from XMLRPC XML.
   730  * Retrieve post title from XMLRPC XML.
   575  *
   731  *
   637  * Use RegEx to extract URLs from arbitrary content.
   793  * Use RegEx to extract URLs from arbitrary content.
   638  *
   794  *
   639  * @since 3.7.0
   795  * @since 3.7.0
   640  *
   796  *
   641  * @param string $content Content to extract URLs from.
   797  * @param string $content Content to extract URLs from.
   642  * @return array URLs found in passed string.
   798  * @return string[] Array of URLs found in passed string.
   643  */
   799  */
   644 function wp_extract_urls( $content ) {
   800 function wp_extract_urls( $content ) {
   645 	preg_match_all(
   801 	preg_match_all(
   646 		"#([\"']?)("
   802 		"#([\"']?)("
   647 			. '(?:([\w-]+:)?//?)'
   803 			. '(?:([\w-]+:)?//?)'
   670  * Will not add enclosures that have already been added and will
   826  * Will not add enclosures that have already been added and will
   671  * remove enclosures that are no longer in the post. This is called as
   827  * remove enclosures that are no longer in the post. This is called as
   672  * pingbacks and trackbacks.
   828  * pingbacks and trackbacks.
   673  *
   829  *
   674  * @since 1.5.0
   830  * @since 1.5.0
       
   831  * @since 5.3.0 The `$content` parameter was made optional, and the `$post` parameter was
       
   832  *              updated to accept a post ID or a WP_Post object.
   675  *
   833  *
   676  * @global wpdb $wpdb WordPress database abstraction object.
   834  * @global wpdb $wpdb WordPress database abstraction object.
   677  *
   835  *
   678  * @param string $content Post Content.
   836  * @param string      $content Post content. If `null`, the `post_content` field from `$post` is used.
   679  * @param int    $post_ID Post ID.
   837  * @param int|WP_Post $post    Post ID or post object.
   680  */
   838  * @return null|bool Returns false if post is not found.
   681 function do_enclose( $content, $post_ID ) {
   839  */
       
   840 function do_enclose( $content = null, $post ) {
   682 	global $wpdb;
   841 	global $wpdb;
   683 
   842 
   684 	//TODO: Tidy this ghetto code up and make the debug code optional
   843 	// @todo Tidy this code and make the debug code optional.
   685 	include_once( ABSPATH . WPINC . '/class-IXR.php' );
   844 	include_once ABSPATH . WPINC . '/class-IXR.php';
       
   845 
       
   846 	$post = get_post( $post );
       
   847 	if ( ! $post ) {
       
   848 		return false;
       
   849 	}
       
   850 
       
   851 	if ( null === $content ) {
       
   852 		$content = $post->post_content;
       
   853 	}
   686 
   854 
   687 	$post_links = array();
   855 	$post_links = array();
   688 
   856 
   689 	$pung = get_enclosed( $post_ID );
   857 	$pung = get_enclosed( $post->ID );
   690 
   858 
   691 	$post_links_temp = wp_extract_urls( $content );
   859 	$post_links_temp = wp_extract_urls( $content );
   692 
   860 
   693 	foreach ( $pung as $link_test ) {
   861 	foreach ( $pung as $link_test ) {
   694 		if ( ! in_array( $link_test, $post_links_temp ) ) { // link no longer in post
   862 		// Link is no longer in post.
   695 			$mids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE %s", $post_ID, $wpdb->esc_like( $link_test ) . '%' ) );
   863 		if ( ! in_array( $link_test, $post_links_temp, true ) ) {
       
   864 			$mids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE %s", $post->ID, $wpdb->esc_like( $link_test ) . '%' ) );
   696 			foreach ( $mids as $mid ) {
   865 			foreach ( $mids as $mid ) {
   697 				delete_metadata_by_mid( 'post', $mid );
   866 				delete_metadata_by_mid( 'post', $mid );
   698 			}
   867 			}
   699 		}
   868 		}
   700 	}
   869 	}
   701 
   870 
   702 	foreach ( (array) $post_links_temp as $link_test ) {
   871 	foreach ( (array) $post_links_temp as $link_test ) {
   703 		if ( ! in_array( $link_test, $pung ) ) { // If we haven't pung it already
   872 		// If we haven't pung it already.
   704 			$test = @parse_url( $link_test );
   873 		if ( ! in_array( $link_test, $pung, true ) ) {
       
   874 			$test = parse_url( $link_test );
   705 			if ( false === $test ) {
   875 			if ( false === $test ) {
   706 				continue;
   876 				continue;
   707 			}
   877 			}
   708 			if ( isset( $test['query'] ) ) {
   878 			if ( isset( $test['query'] ) ) {
   709 				$post_links[] = $link_test;
   879 				$post_links[] = $link_test;
   710 			} elseif ( isset( $test['path'] ) && ( $test['path'] != '/' ) && ( $test['path'] != '' ) ) {
   880 			} elseif ( isset( $test['path'] ) && ( '/' !== $test['path'] ) && ( '' !== $test['path'] ) ) {
   711 				$post_links[] = $link_test;
   881 				$post_links[] = $link_test;
   712 			}
   882 			}
   713 		}
   883 		}
   714 	}
   884 	}
   715 
   885 
   719 	 * Allows for the addition and/or removal of potential enclosures to save
   889 	 * Allows for the addition and/or removal of potential enclosures to save
   720 	 * to postmeta before checking the database for existing enclosures.
   890 	 * to postmeta before checking the database for existing enclosures.
   721 	 *
   891 	 *
   722 	 * @since 4.4.0
   892 	 * @since 4.4.0
   723 	 *
   893 	 *
   724 	 * @param array $post_links An array of enclosure links.
   894 	 * @param string[] $post_links An array of enclosure links.
   725 	 * @param int   $post_ID    Post ID.
   895 	 * @param int      $post_ID    Post ID.
   726 	 */
   896 	 */
   727 	$post_links = apply_filters( 'enclosure_links', $post_links, $post_ID );
   897 	$post_links = apply_filters( 'enclosure_links', $post_links, $post->ID );
   728 
   898 
   729 	foreach ( (array) $post_links as $url ) {
   899 	foreach ( (array) $post_links as $url ) {
   730 		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 ) . '%' ) ) ) {
   900 		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 ) . '%' ) ) ) {
   731 
   901 
   732 			if ( $headers = wp_get_http_headers( $url ) ) {
   902 			$headers = wp_get_http_headers( $url );
       
   903 			if ( $headers ) {
   733 				$len           = isset( $headers['content-length'] ) ? (int) $headers['content-length'] : 0;
   904 				$len           = isset( $headers['content-length'] ) ? (int) $headers['content-length'] : 0;
   734 				$type          = isset( $headers['content-type'] ) ? $headers['content-type'] : '';
   905 				$type          = isset( $headers['content-type'] ) ? $headers['content-type'] : '';
   735 				$allowed_types = array( 'video', 'audio' );
   906 				$allowed_types = array( 'video', 'audio' );
   736 
   907 
   737 				// Check to see if we can figure out the mime type from
   908 				// Check to see if we can figure out the mime type from the extension.
   738 				// the extension
   909 				$url_parts = parse_url( $url );
   739 				$url_parts = @parse_url( $url );
   910 				if ( false !== $url_parts && ! empty( $url_parts['path'] ) ) {
   740 				if ( false !== $url_parts ) {
       
   741 					$extension = pathinfo( $url_parts['path'], PATHINFO_EXTENSION );
   911 					$extension = pathinfo( $url_parts['path'], PATHINFO_EXTENSION );
   742 					if ( ! empty( $extension ) ) {
   912 					if ( ! empty( $extension ) ) {
   743 						foreach ( wp_get_mime_types() as $exts => $mime ) {
   913 						foreach ( wp_get_mime_types() as $exts => $mime ) {
   744 							if ( preg_match( '!^(' . $exts . ')$!i', $extension ) ) {
   914 							if ( preg_match( '!^(' . $exts . ')$!i', $extension ) ) {
   745 								$type = $mime;
   915 								$type = $mime;
   747 							}
   917 							}
   748 						}
   918 						}
   749 					}
   919 					}
   750 				}
   920 				}
   751 
   921 
   752 				if ( in_array( substr( $type, 0, strpos( $type, '/' ) ), $allowed_types ) ) {
   922 				if ( in_array( substr( $type, 0, strpos( $type, '/' ) ), $allowed_types, true ) ) {
   753 					add_post_meta( $post_ID, 'enclosure', "$url\n$len\n$mime\n" );
   923 					add_post_meta( $post->ID, 'enclosure', "$url\n$len\n$mime\n" );
   754 				}
   924 				}
   755 			}
   925 			}
   756 		}
   926 		}
   757 	}
   927 	}
   758 }
   928 }
   795  *
   965  *
   796  * @return int 1 when new day, 0 if not a new day.
   966  * @return int 1 when new day, 0 if not a new day.
   797  */
   967  */
   798 function is_new_day() {
   968 function is_new_day() {
   799 	global $currentday, $previousday;
   969 	global $currentday, $previousday;
   800 	if ( $currentday != $previousday ) {
   970 
       
   971 	if ( $currentday !== $previousday ) {
   801 		return 1;
   972 		return 1;
   802 	} else {
   973 	} else {
   803 		return 0;
   974 		return 0;
   804 	}
   975 	}
   805 }
   976 }
   811  * separator to '&' and uses _http_build_query() function.
   982  * separator to '&' and uses _http_build_query() function.
   812  *
   983  *
   813  * @since 2.3.0
   984  * @since 2.3.0
   814  *
   985  *
   815  * @see _http_build_query() Used to build the query
   986  * @see _http_build_query() Used to build the query
   816  * @link https://secure.php.net/manual/en/function.http-build-query.php for more on what
   987  * @link https://www.php.net/manual/en/function.http-build-query.php for more on what
   817  *       http_build_query() does.
   988  *       http_build_query() does.
   818  *
   989  *
   819  * @param array $data URL-encode key/value pairs.
   990  * @param array $data URL-encode key/value pairs.
   820  * @return string URL-encoded string.
   991  * @return string URL-encoded string.
   821  */
   992  */
   827  * From php.net (modified by Mark Jaquith to behave like the native PHP5 function).
   998  * From php.net (modified by Mark Jaquith to behave like the native PHP5 function).
   828  *
   999  *
   829  * @since 3.2.0
  1000  * @since 3.2.0
   830  * @access private
  1001  * @access private
   831  *
  1002  *
   832  * @see https://secure.php.net/manual/en/function.http-build-query.php
  1003  * @see https://www.php.net/manual/en/function.http-build-query.php
   833  *
  1004  *
   834  * @param array|object  $data       An array or object of data. Converted to array.
  1005  * @param array|object $data      An array or object of data. Converted to array.
   835  * @param string        $prefix     Optional. Numeric index. If set, start parameter numbering with it.
  1006  * @param string       $prefix    Optional. Numeric index. If set, start parameter numbering with it.
   836  *                                  Default null.
  1007  *                                Default null.
   837  * @param string        $sep        Optional. Argument separator; defaults to 'arg_separator.output'.
  1008  * @param string       $sep       Optional. Argument separator; defaults to 'arg_separator.output'.
   838  *                                  Default null.
  1009  *                                Default null.
   839  * @param string        $key        Optional. Used to prefix key name. Default empty.
  1010  * @param string       $key       Optional. Used to prefix key name. Default empty.
   840  * @param bool          $urlencode  Optional. Whether to use urlencode() in the result. Default true.
  1011  * @param bool         $urlencode Optional. Whether to use urlencode() in the result. Default true.
   841  *
       
   842  * @return string The query string.
  1012  * @return string The query string.
   843  */
  1013  */
   844 function _http_build_query( $data, $prefix = null, $sep = null, $key = '', $urlencode = true ) {
  1014 function _http_build_query( $data, $prefix = null, $sep = null, $key = '', $urlencode = true ) {
   845 	$ret = array();
  1015 	$ret = array();
   846 
  1016 
   847 	foreach ( (array) $data as $k => $v ) {
  1017 	foreach ( (array) $data as $k => $v ) {
   848 		if ( $urlencode ) {
  1018 		if ( $urlencode ) {
   849 			$k = urlencode( $k );
  1019 			$k = urlencode( $k );
   850 		}
  1020 		}
   851 		if ( is_int( $k ) && $prefix != null ) {
  1021 		if ( is_int( $k ) && null != $prefix ) {
   852 			$k = $prefix . $k;
  1022 			$k = $prefix . $k;
   853 		}
  1023 		}
   854 		if ( ! empty( $key ) ) {
  1024 		if ( ! empty( $key ) ) {
   855 			$k = $key . '%5B' . $k . '%5D';
  1025 			$k = $key . '%5B' . $k . '%5D';
   856 		}
  1026 		}
   857 		if ( $v === null ) {
  1027 		if ( null === $v ) {
   858 			continue;
  1028 			continue;
   859 		} elseif ( $v === false ) {
  1029 		} elseif ( false === $v ) {
   860 			$v = '0';
  1030 			$v = '0';
   861 		}
  1031 		}
   862 
  1032 
   863 		if ( is_array( $v ) || is_object( $v ) ) {
  1033 		if ( is_array( $v ) || is_object( $v ) ) {
   864 			array_push( $ret, _http_build_query( $v, '', $sep, $k, $urlencode ) );
  1034 			array_push( $ret, _http_build_query( $v, '', $sep, $k, $urlencode ) );
   903  * Important: The return value of add_query_arg() is not escaped by default. Output should be
  1073  * Important: The return value of add_query_arg() is not escaped by default. Output should be
   904  * late-escaped with esc_url() or similar to help prevent vulnerability to cross-site scripting
  1074  * late-escaped with esc_url() or similar to help prevent vulnerability to cross-site scripting
   905  * (XSS) attacks.
  1075  * (XSS) attacks.
   906  *
  1076  *
   907  * @since 1.5.0
  1077  * @since 1.5.0
       
  1078  * @since 5.3.0 Formalized the existing and already documented parameters
       
  1079  *              by adding `...$args` to the function signature.
   908  *
  1080  *
   909  * @param string|array $key   Either a query variable key, or an associative array of query variables.
  1081  * @param string|array $key   Either a query variable key, or an associative array of query variables.
   910  * @param string       $value Optional. Either a query variable value, or a URL to act upon.
  1082  * @param string       $value Optional. Either a query variable value, or a URL to act upon.
   911  * @param string       $url   Optional. A URL to act upon.
  1083  * @param string       $url   Optional. A URL to act upon.
   912  * @return string New URL query string (unescaped).
  1084  * @return string New URL query string (unescaped).
   913  */
  1085  */
   914 function add_query_arg() {
  1086 function add_query_arg( ...$args ) {
   915 	$args = func_get_args();
       
   916 	if ( is_array( $args[0] ) ) {
  1087 	if ( is_array( $args[0] ) ) {
   917 		if ( count( $args ) < 2 || false === $args[1] ) {
  1088 		if ( count( $args ) < 2 || false === $args[1] ) {
   918 			$uri = $_SERVER['REQUEST_URI'];
  1089 			$uri = $_SERVER['REQUEST_URI'];
   919 		} else {
  1090 		} else {
   920 			$uri = $args[1];
  1091 			$uri = $args[1];
   925 		} else {
  1096 		} else {
   926 			$uri = $args[2];
  1097 			$uri = $args[2];
   927 		}
  1098 		}
   928 	}
  1099 	}
   929 
  1100 
   930 	if ( $frag = strstr( $uri, '#' ) ) {
  1101 	$frag = strstr( $uri, '#' );
       
  1102 	if ( $frag ) {
   931 		$uri = substr( $uri, 0, -strlen( $frag ) );
  1103 		$uri = substr( $uri, 0, -strlen( $frag ) );
   932 	} else {
  1104 	} else {
   933 		$frag = '';
  1105 		$frag = '';
   934 	}
  1106 	}
   935 
  1107 
   953 		$base  = '';
  1125 		$base  = '';
   954 		$query = $uri;
  1126 		$query = $uri;
   955 	}
  1127 	}
   956 
  1128 
   957 	wp_parse_str( $query, $qs );
  1129 	wp_parse_str( $query, $qs );
   958 	$qs = urlencode_deep( $qs ); // this re-URL-encodes things that were already in the query string
  1130 	$qs = urlencode_deep( $qs ); // This re-URL-encodes things that were already in the query string.
   959 	if ( is_array( $args[0] ) ) {
  1131 	if ( is_array( $args[0] ) ) {
   960 		foreach ( $args[0] as $k => $v ) {
  1132 		foreach ( $args[0] as $k => $v ) {
   961 			$qs[ $k ] = $v;
  1133 			$qs[ $k ] = $v;
   962 		}
  1134 		}
   963 	} else {
  1135 	} else {
   964 		$qs[ $args[0] ] = $args[1];
  1136 		$qs[ $args[0] ] = $args[1];
   965 	}
  1137 	}
   966 
  1138 
   967 	foreach ( $qs as $k => $v ) {
  1139 	foreach ( $qs as $k => $v ) {
   968 		if ( $v === false ) {
  1140 		if ( false === $v ) {
   969 			unset( $qs[ $k ] );
  1141 			unset( $qs[ $k ] );
   970 		}
  1142 		}
   971 	}
  1143 	}
   972 
  1144 
   973 	$ret = build_query( $qs );
  1145 	$ret = build_query( $qs );
   986  * @param string|array $key   Query key or keys to remove.
  1158  * @param string|array $key   Query key or keys to remove.
   987  * @param bool|string  $query Optional. When false uses the current URL. Default false.
  1159  * @param bool|string  $query Optional. When false uses the current URL. Default false.
   988  * @return string New URL query string.
  1160  * @return string New URL query string.
   989  */
  1161  */
   990 function remove_query_arg( $key, $query = false ) {
  1162 function remove_query_arg( $key, $query = false ) {
   991 	if ( is_array( $key ) ) { // removing multiple keys
  1163 	if ( is_array( $key ) ) { // Removing multiple keys.
   992 		foreach ( $key as $k ) {
  1164 		foreach ( $key as $k ) {
   993 			$query = add_query_arg( $k, false, $query );
  1165 			$query = add_query_arg( $k, false, $query );
   994 		}
  1166 		}
   995 		return $query;
  1167 		return $query;
   996 	}
  1168 	}
  1000 /**
  1172 /**
  1001  * Returns an array of single-use query variable names that can be removed from a URL.
  1173  * Returns an array of single-use query variable names that can be removed from a URL.
  1002  *
  1174  *
  1003  * @since 4.4.0
  1175  * @since 4.4.0
  1004  *
  1176  *
  1005  * @return array An array of parameters to remove from the URL.
  1177  * @return string[] An array of parameters to remove from the URL.
  1006  */
  1178  */
  1007 function wp_removable_query_args() {
  1179 function wp_removable_query_args() {
  1008 	$removable_query_args = array(
  1180 	$removable_query_args = array(
  1009 		'activate',
  1181 		'activate',
  1010 		'activated',
  1182 		'activated',
       
  1183 		'admin_email_remind_later',
  1011 		'approved',
  1184 		'approved',
  1012 		'deactivate',
  1185 		'deactivate',
       
  1186 		'delete_count',
  1013 		'deleted',
  1187 		'deleted',
  1014 		'disabled',
  1188 		'disabled',
       
  1189 		'doing_wp_cron',
  1015 		'enabled',
  1190 		'enabled',
  1016 		'error',
  1191 		'error',
  1017 		'hotkeys_highlight_first',
  1192 		'hotkeys_highlight_first',
  1018 		'hotkeys_highlight_last',
  1193 		'hotkeys_highlight_last',
  1019 		'locked',
  1194 		'locked',
  1034 	/**
  1209 	/**
  1035 	 * Filters the list of query variables to remove.
  1210 	 * Filters the list of query variables to remove.
  1036 	 *
  1211 	 *
  1037 	 * @since 4.2.0
  1212 	 * @since 4.2.0
  1038 	 *
  1213 	 *
  1039 	 * @param array $removable_query_args An array of query variables to remove from a URL.
  1214 	 * @param string[] $removable_query_args An array of query variables to remove from a URL.
  1040 	 */
  1215 	 */
  1041 	return apply_filters( 'removable_query_args', $removable_query_args );
  1216 	return apply_filters( 'removable_query_args', $removable_query_args );
  1042 }
  1217 }
  1043 
  1218 
  1044 /**
  1219 /**
  1045  * Walks the array while sanitizing the contents.
  1220  * Walks the array while sanitizing the contents.
  1046  *
  1221  *
  1047  * @since 0.71
  1222  * @since 0.71
       
  1223  * @since 5.5.0 Non-string values are left untouched.
  1048  *
  1224  *
  1049  * @param array $array Array to walk while sanitizing contents.
  1225  * @param array $array Array to walk while sanitizing contents.
  1050  * @return array Sanitized $array.
  1226  * @return array Sanitized $array.
  1051  */
  1227  */
  1052 function add_magic_quotes( $array ) {
  1228 function add_magic_quotes( $array ) {
  1053 	foreach ( (array) $array as $k => $v ) {
  1229 	foreach ( (array) $array as $k => $v ) {
  1054 		if ( is_array( $v ) ) {
  1230 		if ( is_array( $v ) ) {
  1055 			$array[ $k ] = add_magic_quotes( $v );
  1231 			$array[ $k ] = add_magic_quotes( $v );
       
  1232 		} elseif ( is_string( $v ) ) {
       
  1233 			$array[ $k ] = addslashes( $v );
  1056 		} else {
  1234 		} else {
  1057 			$array[ $k ] = addslashes( $v );
  1235 			continue;
  1058 		}
  1236 		}
  1059 	}
  1237 	}
       
  1238 
  1060 	return $array;
  1239 	return $array;
  1061 }
  1240 }
  1062 
  1241 
  1063 /**
  1242 /**
  1064  * HTTP request for URI to retrieve content.
  1243  * HTTP request for URI to retrieve content.
  1066  * @since 1.5.1
  1245  * @since 1.5.1
  1067  *
  1246  *
  1068  * @see wp_safe_remote_get()
  1247  * @see wp_safe_remote_get()
  1069  *
  1248  *
  1070  * @param string $uri URI/URL of web page to retrieve.
  1249  * @param string $uri URI/URL of web page to retrieve.
  1071  * @return false|string HTTP content. False on failure.
  1250  * @return string|false HTTP content. False on failure.
  1072  */
  1251  */
  1073 function wp_remote_fopen( $uri ) {
  1252 function wp_remote_fopen( $uri ) {
  1074 	$parsed_url = @parse_url( $uri );
  1253 	$parsed_url = parse_url( $uri );
  1075 
  1254 
  1076 	if ( ! $parsed_url || ! is_array( $parsed_url ) ) {
  1255 	if ( ! $parsed_url || ! is_array( $parsed_url ) ) {
  1077 		return false;
  1256 		return false;
  1078 	}
  1257 	}
  1079 
  1258 
  1092 /**
  1271 /**
  1093  * Set up the WordPress query.
  1272  * Set up the WordPress query.
  1094  *
  1273  *
  1095  * @since 2.0.0
  1274  * @since 2.0.0
  1096  *
  1275  *
  1097  * @global WP       $wp_locale
  1276  * @global WP       $wp           Current WordPress environment instance.
  1098  * @global WP_Query $wp_query
  1277  * @global WP_Query $wp_query     WordPress Query object.
  1099  * @global WP_Query $wp_the_query
  1278  * @global WP_Query $wp_the_query Copy of the WordPress Query object.
  1100  *
  1279  *
  1101  * @param string|array $query_vars Default WP_Query arguments.
  1280  * @param string|array $query_vars Default WP_Query arguments.
  1102  */
  1281  */
  1103 function wp( $query_vars = '' ) {
  1282 function wp( $query_vars = '' ) {
  1104 	global $wp, $wp_query, $wp_the_query;
  1283 	global $wp, $wp_query, $wp_the_query;
       
  1284 
  1105 	$wp->main( $query_vars );
  1285 	$wp->main( $query_vars );
  1106 
  1286 
  1107 	if ( ! isset( $wp_the_query ) ) {
  1287 	if ( ! isset( $wp_the_query ) ) {
  1108 		$wp_the_query = $wp_query;
  1288 		$wp_the_query = $wp_query;
  1109 	}
  1289 	}
  1118  * @since 5.1.0 Added status code 103.
  1298  * @since 5.1.0 Added status code 103.
  1119  *
  1299  *
  1120  * @global array $wp_header_to_desc
  1300  * @global array $wp_header_to_desc
  1121  *
  1301  *
  1122  * @param int $code HTTP status code.
  1302  * @param int $code HTTP status code.
  1123  * @return string Empty string if not found, or description if found.
  1303  * @return string Status description if found, an empty string otherwise.
  1124  */
  1304  */
  1125 function get_status_header_desc( $code ) {
  1305 function get_status_header_desc( $code ) {
  1126 	global $wp_header_to_desc;
  1306 	global $wp_header_to_desc;
  1127 
  1307 
  1128 	$code = absint( $code );
  1308 	$code = absint( $code );
  1238 		 * @param string $protocol      Server protocol.
  1418 		 * @param string $protocol      Server protocol.
  1239 		 */
  1419 		 */
  1240 		$status_header = apply_filters( 'status_header', $status_header, $code, $description, $protocol );
  1420 		$status_header = apply_filters( 'status_header', $status_header, $code, $description, $protocol );
  1241 	}
  1421 	}
  1242 
  1422 
  1243 	@header( $status_header, true, $code );
  1423 	if ( ! headers_sent() ) {
       
  1424 		header( $status_header, true, $code );
       
  1425 	}
  1244 }
  1426 }
  1245 
  1427 
  1246 /**
  1428 /**
  1247  * Get the header information to prevent caching.
  1429  * Get the header information to prevent caching.
  1248  *
  1430  *
  1290  * @since 2.0.0
  1472  * @since 2.0.0
  1291  *
  1473  *
  1292  * @see wp_get_nocache_headers()
  1474  * @see wp_get_nocache_headers()
  1293  */
  1475  */
  1294 function nocache_headers() {
  1476 function nocache_headers() {
       
  1477 	if ( headers_sent() ) {
       
  1478 		return;
       
  1479 	}
       
  1480 
  1295 	$headers = wp_get_nocache_headers();
  1481 	$headers = wp_get_nocache_headers();
  1296 
  1482 
  1297 	unset( $headers['Last-Modified'] );
  1483 	unset( $headers['Last-Modified'] );
  1298 
  1484 
  1299 	// In PHP 5.3+, make sure we are not sending a Last-Modified header.
  1485 	header_remove( 'Last-Modified' );
  1300 	if ( function_exists( 'header_remove' ) ) {
       
  1301 		@header_remove( 'Last-Modified' );
       
  1302 	} else {
       
  1303 		// In PHP 5.2, send an empty Last-Modified header, but only as a
       
  1304 		// last resort to override a header already sent. #WP23021
       
  1305 		foreach ( headers_list() as $header ) {
       
  1306 			if ( 0 === stripos( $header, 'Last-Modified' ) ) {
       
  1307 				$headers['Last-Modified'] = '';
       
  1308 				break;
       
  1309 			}
       
  1310 		}
       
  1311 	}
       
  1312 
  1486 
  1313 	foreach ( $headers as $name => $field_value ) {
  1487 	foreach ( $headers as $name => $field_value ) {
  1314 		@header( "{$name}: {$field_value}" );
  1488 		header( "{$name}: {$field_value}" );
  1315 	}
  1489 	}
  1316 }
  1490 }
  1317 
  1491 
  1318 /**
  1492 /**
  1319  * Set the headers for caching for 10 days with JavaScript content type.
  1493  * Set the headers for caching for 10 days with JavaScript content type.
  1322  */
  1496  */
  1323 function cache_javascript_headers() {
  1497 function cache_javascript_headers() {
  1324 	$expiresOffset = 10 * DAY_IN_SECONDS;
  1498 	$expiresOffset = 10 * DAY_IN_SECONDS;
  1325 
  1499 
  1326 	header( 'Content-Type: text/javascript; charset=' . get_bloginfo( 'charset' ) );
  1500 	header( 'Content-Type: text/javascript; charset=' . get_bloginfo( 'charset' ) );
  1327 	header( 'Vary: Accept-Encoding' ); // Handle proxies
  1501 	header( 'Vary: Accept-Encoding' ); // Handle proxies.
  1328 	header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', time() + $expiresOffset ) . ' GMT' );
  1502 	header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', time() + $expiresOffset ) . ' GMT' );
  1329 }
  1503 }
  1330 
  1504 
  1331 /**
  1505 /**
  1332  * Retrieve the number of database queries during the WordPress execution.
  1506  * Retrieve the number of database queries during the WordPress execution.
  1351  *
  1525  *
  1352  * @param string $yn Character string containing either 'y' (yes) or 'n' (no).
  1526  * @param string $yn Character string containing either 'y' (yes) or 'n' (no).
  1353  * @return bool True if yes, false on anything else.
  1527  * @return bool True if yes, false on anything else.
  1354  */
  1528  */
  1355 function bool_from_yn( $yn ) {
  1529 function bool_from_yn( $yn ) {
  1356 	return ( strtolower( $yn ) == 'y' );
  1530 	return ( 'y' === strtolower( $yn ) );
  1357 }
  1531 }
  1358 
  1532 
  1359 /**
  1533 /**
  1360  * Load the feed template from the use of an action hook.
  1534  * Load the feed template from the use of an action hook.
  1361  *
  1535  *
  1364  *
  1538  *
  1365  * It is better to only have one hook for each feed.
  1539  * It is better to only have one hook for each feed.
  1366  *
  1540  *
  1367  * @since 2.1.0
  1541  * @since 2.1.0
  1368  *
  1542  *
  1369  * @global WP_Query $wp_query Used to tell if the use a comment feed.
  1543  * @global WP_Query $wp_query WordPress Query object.
  1370  */
  1544  */
  1371 function do_feed() {
  1545 function do_feed() {
  1372 	global $wp_query;
  1546 	global $wp_query;
  1373 
  1547 
  1374 	$feed = get_query_var( 'feed' );
  1548 	$feed = get_query_var( 'feed' );
  1375 
  1549 
  1376 	// Remove the pad, if present.
  1550 	// Remove the pad, if present.
  1377 	$feed = preg_replace( '/^_+/', '', $feed );
  1551 	$feed = preg_replace( '/^_+/', '', $feed );
  1378 
  1552 
  1379 	if ( $feed == '' || $feed == 'feed' ) {
  1553 	if ( '' === $feed || 'feed' === $feed ) {
  1380 		$feed = get_default_feed();
  1554 		$feed = get_default_feed();
  1381 	}
  1555 	}
  1382 
  1556 
  1383 	if ( ! has_action( "do_feed_{$feed}" ) ) {
  1557 	if ( ! has_action( "do_feed_{$feed}" ) ) {
  1384 		wp_die( __( 'ERROR: This is not a valid feed template.' ), '', array( 'response' => 404 ) );
  1558 		wp_die( __( 'Error: This is not a valid feed template.' ), '', array( 'response' => 404 ) );
  1385 	}
  1559 	}
  1386 
  1560 
  1387 	/**
  1561 	/**
  1388 	 * Fires once the given feed is loaded.
  1562 	 * Fires once the given feed is loaded.
  1389 	 *
  1563 	 *
  1454 		load_template( ABSPATH . WPINC . '/feed-atom.php' );
  1628 		load_template( ABSPATH . WPINC . '/feed-atom.php' );
  1455 	}
  1629 	}
  1456 }
  1630 }
  1457 
  1631 
  1458 /**
  1632 /**
  1459  * Display the robots.txt file content.
  1633  * Displays the default robots.txt file content.
  1460  *
       
  1461  * The echo content should be with usage of the permalinks or for creating the
       
  1462  * robots.txt file.
       
  1463  *
  1634  *
  1464  * @since 2.1.0
  1635  * @since 2.1.0
       
  1636  * @since 5.3.0 Remove the "Disallow: /" output if search engine visiblity is
       
  1637  *              discouraged in favor of robots meta HTML tag in wp_no_robots().
  1465  */
  1638  */
  1466 function do_robots() {
  1639 function do_robots() {
  1467 	header( 'Content-Type: text/plain; charset=utf-8' );
  1640 	header( 'Content-Type: text/plain; charset=utf-8' );
  1468 
  1641 
  1469 	/**
  1642 	/**
  1473 	 */
  1646 	 */
  1474 	do_action( 'do_robotstxt' );
  1647 	do_action( 'do_robotstxt' );
  1475 
  1648 
  1476 	$output = "User-agent: *\n";
  1649 	$output = "User-agent: *\n";
  1477 	$public = get_option( 'blog_public' );
  1650 	$public = get_option( 'blog_public' );
  1478 	if ( '0' == $public ) {
  1651 
  1479 		$output .= "Disallow: /\n";
  1652 	$site_url = parse_url( site_url() );
  1480 	} else {
  1653 	$path     = ( ! empty( $site_url['path'] ) ) ? $site_url['path'] : '';
  1481 		$site_url = parse_url( site_url() );
  1654 	$output  .= "Disallow: $path/wp-admin/\n";
  1482 		$path     = ( ! empty( $site_url['path'] ) ) ? $site_url['path'] : '';
  1655 	$output  .= "Allow: $path/wp-admin/admin-ajax.php\n";
  1483 		$output  .= "Disallow: $path/wp-admin/\n";
       
  1484 		$output  .= "Allow: $path/wp-admin/admin-ajax.php\n";
       
  1485 	}
       
  1486 
  1656 
  1487 	/**
  1657 	/**
  1488 	 * Filters the robots.txt output.
  1658 	 * Filters the robots.txt output.
  1489 	 *
  1659 	 *
  1490 	 * @since 3.0.0
  1660 	 * @since 3.0.0
  1491 	 *
  1661 	 *
  1492 	 * @param string $output Robots.txt output.
  1662 	 * @param string $output The robots.txt output.
  1493 	 * @param bool   $public Whether the site is considered "public".
  1663 	 * @param bool   $public Whether the site is considered "public".
  1494 	 */
  1664 	 */
  1495 	echo apply_filters( 'robots_txt', $output, $public );
  1665 	echo apply_filters( 'robots_txt', $output, $public );
       
  1666 }
       
  1667 
       
  1668 /**
       
  1669  * Display the favicon.ico file content.
       
  1670  *
       
  1671  * @since 5.4.0
       
  1672  */
       
  1673 function do_favicon() {
       
  1674 	/**
       
  1675 	 * Fires when serving the favicon.ico file.
       
  1676 	 *
       
  1677 	 * @since 5.4.0
       
  1678 	 */
       
  1679 	do_action( 'do_faviconico' );
       
  1680 
       
  1681 	wp_redirect( get_site_icon_url( 32, includes_url( 'images/w-logo-blue-white-bg.png' ) ) );
       
  1682 	exit;
  1496 }
  1683 }
  1497 
  1684 
  1498 /**
  1685 /**
  1499  * Determines whether WordPress is already installed.
  1686  * Determines whether WordPress is already installed.
  1500  *
  1687  *
  1527 
  1714 
  1528 	$suppress = $wpdb->suppress_errors();
  1715 	$suppress = $wpdb->suppress_errors();
  1529 	if ( ! wp_installing() ) {
  1716 	if ( ! wp_installing() ) {
  1530 		$alloptions = wp_load_alloptions();
  1717 		$alloptions = wp_load_alloptions();
  1531 	}
  1718 	}
  1532 	// If siteurl is not set to autoload, check it specifically
  1719 	// If siteurl is not set to autoload, check it specifically.
  1533 	if ( ! isset( $alloptions['siteurl'] ) ) {
  1720 	if ( ! isset( $alloptions['siteurl'] ) ) {
  1534 		$installed = $wpdb->get_var( "SELECT option_value FROM $wpdb->options WHERE option_name = 'siteurl'" );
  1721 		$installed = $wpdb->get_var( "SELECT option_value FROM $wpdb->options WHERE option_name = 'siteurl'" );
  1535 	} else {
  1722 	} else {
  1536 		$installed = $alloptions['siteurl'];
  1723 		$installed = $alloptions['siteurl'];
  1537 	}
  1724 	}
  1574 
  1761 
  1575 		wp_load_translations_early();
  1762 		wp_load_translations_early();
  1576 
  1763 
  1577 		// Die with a DB error.
  1764 		// Die with a DB error.
  1578 		$wpdb->error = sprintf(
  1765 		$wpdb->error = sprintf(
  1579 			/* translators: %s: database repair URL */
  1766 			/* translators: %s: Database repair URL. */
  1580 			__( 'One or more database tables are unavailable. The database may need to be <a href="%s">repaired</a>.' ),
  1767 			__( 'One or more database tables are unavailable. The database may need to be <a href="%s">repaired</a>.' ),
  1581 			'maint/repair.php?referrer=is_blog_installed'
  1768 			'maint/repair.php?referrer=is_blog_installed'
  1582 		);
  1769 		);
  1583 
  1770 
  1584 		dead_db();
  1771 		dead_db();
  1662 	$referer_field = '<input type="hidden" name="_wp_http_referer" value="' . esc_attr( wp_unslash( $_SERVER['REQUEST_URI'] ) ) . '" />';
  1849 	$referer_field = '<input type="hidden" name="_wp_http_referer" value="' . esc_attr( wp_unslash( $_SERVER['REQUEST_URI'] ) ) . '" />';
  1663 
  1850 
  1664 	if ( $echo ) {
  1851 	if ( $echo ) {
  1665 		echo $referer_field;
  1852 		echo $referer_field;
  1666 	}
  1853 	}
       
  1854 
  1667 	return $referer_field;
  1855 	return $referer_field;
  1668 }
  1856 }
  1669 
  1857 
  1670 /**
  1858 /**
  1671  * Retrieve or display original referer hidden field for forms.
  1859  * Retrieve or display original referer hidden field for forms.
  1680  * @param string $jump_back_to Optional. Can be 'previous' or page you want to jump back to.
  1868  * @param string $jump_back_to Optional. Can be 'previous' or page you want to jump back to.
  1681  *                             Default 'current'.
  1869  *                             Default 'current'.
  1682  * @return string Original referer field.
  1870  * @return string Original referer field.
  1683  */
  1871  */
  1684 function wp_original_referer_field( $echo = true, $jump_back_to = 'current' ) {
  1872 function wp_original_referer_field( $echo = true, $jump_back_to = 'current' ) {
  1685 	if ( ! $ref = wp_get_original_referer() ) {
  1873 	$ref = wp_get_original_referer();
  1686 		$ref = 'previous' == $jump_back_to ? wp_get_referer() : wp_unslash( $_SERVER['REQUEST_URI'] );
  1874 
  1687 	}
  1875 	if ( ! $ref ) {
       
  1876 		$ref = ( 'previous' === $jump_back_to ) ? wp_get_referer() : wp_unslash( $_SERVER['REQUEST_URI'] );
       
  1877 	}
       
  1878 
  1688 	$orig_referer_field = '<input type="hidden" name="_wp_original_http_referer" value="' . esc_attr( $ref ) . '" />';
  1879 	$orig_referer_field = '<input type="hidden" name="_wp_original_http_referer" value="' . esc_attr( $ref ) . '" />';
       
  1880 
  1689 	if ( $echo ) {
  1881 	if ( $echo ) {
  1690 		echo $orig_referer_field;
  1882 		echo $orig_referer_field;
  1691 	}
  1883 	}
       
  1884 
  1692 	return $orig_referer_field;
  1885 	return $orig_referer_field;
  1693 }
  1886 }
  1694 
  1887 
  1695 /**
  1888 /**
  1696  * Retrieve referer from '_wp_http_referer' or HTTP referer.
  1889  * Retrieve referer from '_wp_http_referer' or HTTP referer.
  1697  *
  1890  *
  1698  * If it's the same as the current request URL, will return false.
  1891  * If it's the same as the current request URL, will return false.
  1699  *
  1892  *
  1700  * @since 2.0.4
  1893  * @since 2.0.4
  1701  *
  1894  *
  1702  * @return false|string False on failure. Referer URL on success.
  1895  * @return string|false Referer URL on success, false on failure.
  1703  */
  1896  */
  1704 function wp_get_referer() {
  1897 function wp_get_referer() {
  1705 	if ( ! function_exists( 'wp_validate_redirect' ) ) {
  1898 	if ( ! function_exists( 'wp_validate_redirect' ) ) {
  1706 		return false;
  1899 		return false;
  1707 	}
  1900 	}
  1708 
  1901 
  1709 	$ref = wp_get_raw_referer();
  1902 	$ref = wp_get_raw_referer();
  1710 
  1903 
  1711 	if ( $ref && $ref !== wp_unslash( $_SERVER['REQUEST_URI'] ) && $ref !== home_url() . wp_unslash( $_SERVER['REQUEST_URI'] ) ) {
  1904 	if ( $ref && wp_unslash( $_SERVER['REQUEST_URI'] ) !== $ref && home_url() . wp_unslash( $_SERVER['REQUEST_URI'] ) !== $ref ) {
  1712 		return wp_validate_redirect( $ref, false );
  1905 		return wp_validate_redirect( $ref, false );
  1713 	}
  1906 	}
  1714 
  1907 
  1715 	return false;
  1908 	return false;
  1716 }
  1909 }
  1737 /**
  1930 /**
  1738  * Retrieve original referer that was posted, if it exists.
  1931  * Retrieve original referer that was posted, if it exists.
  1739  *
  1932  *
  1740  * @since 2.0.4
  1933  * @since 2.0.4
  1741  *
  1934  *
  1742  * @return string|false False if no original referer or original referer if set.
  1935  * @return string|false Original referer URL on success, false on failure.
  1743  */
  1936  */
  1744 function wp_get_original_referer() {
  1937 function wp_get_original_referer() {
  1745 	if ( ! empty( $_REQUEST['_wp_original_http_referer'] ) && function_exists( 'wp_validate_redirect' ) ) {
  1938 	if ( ! empty( $_REQUEST['_wp_original_http_referer'] ) && function_exists( 'wp_validate_redirect' ) ) {
  1746 		return wp_validate_redirect( wp_unslash( $_REQUEST['_wp_original_http_referer'] ), false );
  1939 		return wp_validate_redirect( wp_unslash( $_REQUEST['_wp_original_http_referer'] ), false );
  1747 	}
  1940 	}
       
  1941 
  1748 	return false;
  1942 	return false;
  1749 }
  1943 }
  1750 
  1944 
  1751 /**
  1945 /**
  1752  * Recursive directory creation based on full path.
  1946  * Recursive directory creation based on full path.
  1768 
  1962 
  1769 	// From php.net/mkdir user contributed notes.
  1963 	// From php.net/mkdir user contributed notes.
  1770 	$target = str_replace( '//', '/', $target );
  1964 	$target = str_replace( '//', '/', $target );
  1771 
  1965 
  1772 	// Put the wrapper back on the target.
  1966 	// Put the wrapper back on the target.
  1773 	if ( $wrapper !== null ) {
  1967 	if ( null !== $wrapper ) {
  1774 		$target = $wrapper . '://' . $target;
  1968 		$target = $wrapper . '://' . $target;
  1775 	}
  1969 	}
  1776 
  1970 
  1777 	/*
  1971 	/*
  1778 	 * Safe mode fails with a trailing slash under certain PHP versions.
  1972 	 * Safe mode fails with a trailing slash under certain PHP versions.
  1792 		return false;
  1986 		return false;
  1793 	}
  1987 	}
  1794 
  1988 
  1795 	// We need to find the permissions of the parent folder that exists and inherit that.
  1989 	// We need to find the permissions of the parent folder that exists and inherit that.
  1796 	$target_parent = dirname( $target );
  1990 	$target_parent = dirname( $target );
  1797 	while ( '.' != $target_parent && ! is_dir( $target_parent ) && dirname( $target_parent ) !== $target_parent ) {
  1991 	while ( '.' !== $target_parent && ! is_dir( $target_parent ) && dirname( $target_parent ) !== $target_parent ) {
  1798 		$target_parent = dirname( $target_parent );
  1992 		$target_parent = dirname( $target_parent );
  1799 	}
  1993 	}
  1800 
  1994 
  1801 	// Get the permission bits.
  1995 	// Get the permission bits.
  1802 	if ( $stat = @stat( $target_parent ) ) {
  1996 	$stat = @stat( $target_parent );
       
  1997 	if ( $stat ) {
  1803 		$dir_perms = $stat['mode'] & 0007777;
  1998 		$dir_perms = $stat['mode'] & 0007777;
  1804 	} else {
  1999 	} else {
  1805 		$dir_perms = 0777;
  2000 		$dir_perms = 0777;
  1806 	}
  2001 	}
  1807 
  2002 
  1809 
  2004 
  1810 		/*
  2005 		/*
  1811 		 * If a umask is set that modifies $dir_perms, we'll have to re-set
  2006 		 * If a umask is set that modifies $dir_perms, we'll have to re-set
  1812 		 * the $dir_perms correctly with chmod()
  2007 		 * the $dir_perms correctly with chmod()
  1813 		 */
  2008 		 */
  1814 		if ( $dir_perms != ( $dir_perms & ~umask() ) ) {
  2009 		if ( ( $dir_perms & ~umask() ) != $dir_perms ) {
  1815 			$folder_parts = explode( '/', substr( $target, strlen( $target_parent ) + 1 ) );
  2010 			$folder_parts = explode( '/', substr( $target, strlen( $target_parent ) + 1 ) );
  1816 			for ( $i = 1, $c = count( $folder_parts ); $i <= $c; $i++ ) {
  2011 			for ( $i = 1, $c = count( $folder_parts ); $i <= $c; $i++ ) {
  1817 				@chmod( $target_parent . '/' . implode( '/', array_slice( $folder_parts, 0, $i ) ), $dir_perms );
  2012 				chmod( $target_parent . '/' . implode( '/', array_slice( $folder_parts, 0, $i ) ), $dir_perms );
  1818 			}
  2013 			}
  1819 		}
  2014 		}
  1820 
  2015 
  1821 		return true;
  2016 		return true;
  1822 	}
  2017 	}
  1849 	 */
  2044 	 */
  1850 	if ( realpath( $path ) == $path ) {
  2045 	if ( realpath( $path ) == $path ) {
  1851 		return true;
  2046 		return true;
  1852 	}
  2047 	}
  1853 
  2048 
  1854 	if ( strlen( $path ) == 0 || $path[0] == '.' ) {
  2049 	if ( strlen( $path ) == 0 || '.' === $path[0] ) {
  1855 		return false;
  2050 		return false;
  1856 	}
  2051 	}
  1857 
  2052 
  1858 	// Windows allows absolute paths like this.
  2053 	// Windows allows absolute paths like this.
  1859 	if ( preg_match( '#^[a-zA-Z]:\\\\#', $path ) ) {
  2054 	if ( preg_match( '#^[a-zA-Z]:\\\\#', $path ) ) {
  1860 		return true;
  2055 		return true;
  1861 	}
  2056 	}
  1862 
  2057 
  1863 	// A path starting with / or \ is absolute; anything else is relative.
  2058 	// A path starting with / or \ is absolute; anything else is relative.
  1864 	return ( $path[0] == '/' || $path[0] == '\\' );
  2059 	return ( '/' === $path[0] || '\\' === $path[0] );
  1865 }
  2060 }
  1866 
  2061 
  1867 /**
  2062 /**
  1868  * Join two filesystem paths together.
  2063  * Join two filesystem paths together.
  1869  *
  2064  *
  1900  * @param string $path Path to normalize.
  2095  * @param string $path Path to normalize.
  1901  * @return string Normalized path.
  2096  * @return string Normalized path.
  1902  */
  2097  */
  1903 function wp_normalize_path( $path ) {
  2098 function wp_normalize_path( $path ) {
  1904 	$wrapper = '';
  2099 	$wrapper = '';
       
  2100 
  1905 	if ( wp_is_stream( $path ) ) {
  2101 	if ( wp_is_stream( $path ) ) {
  1906 		list( $wrapper, $path ) = explode( '://', $path, 2 );
  2102 		list( $wrapper, $path ) = explode( '://', $path, 2 );
  1907 		$wrapper               .= '://';
  2103 
  1908 	}
  2104 		$wrapper .= '://';
  1909 
  2105 	}
  1910 	// Standardise all paths to use /
  2106 
       
  2107 	// Standardise all paths to use '/'.
  1911 	$path = str_replace( '\\', '/', $path );
  2108 	$path = str_replace( '\\', '/', $path );
  1912 
  2109 
  1913 	// Replace multiple slashes down to a singular, allowing for network shares having two slashes.
  2110 	// Replace multiple slashes down to a singular, allowing for network shares having two slashes.
  1914 	$path = preg_replace( '|(?<=.)/+|', '/', $path );
  2111 	$path = preg_replace( '|(?<=.)/+|', '/', $path );
  1915 
  2112 
  1916 	// Windows paths should uppercase the drive letter
  2113 	// Windows paths should uppercase the drive letter.
  1917 	if ( ':' === substr( $path, 1, 1 ) ) {
  2114 	if ( ':' === substr( $path, 1, 1 ) ) {
  1918 		$path = ucfirst( $path );
  2115 		$path = ucfirst( $path );
  1919 	}
  2116 	}
  1920 
  2117 
  1921 	return $wrapper . $path;
  2118 	return $wrapper . $path;
  1930  *
  2127  *
  1931  * In the event that this function does not find a writable location,
  2128  * In the event that this function does not find a writable location,
  1932  * It may be overridden by the WP_TEMP_DIR constant in your wp-config.php file.
  2129  * It may be overridden by the WP_TEMP_DIR constant in your wp-config.php file.
  1933  *
  2130  *
  1934  * @since 2.5.0
  2131  * @since 2.5.0
  1935  *
       
  1936  * @staticvar string $temp
       
  1937  *
  2132  *
  1938  * @return string Writable temporary directory.
  2133  * @return string Writable temporary directory.
  1939  */
  2134  */
  1940 function get_temp_dir() {
  2135 function get_temp_dir() {
  1941 	static $temp = '';
  2136 	static $temp = '';
  2003  *
  2198  *
  2004  * @param string $path Windows path to check for write-ability.
  2199  * @param string $path Windows path to check for write-ability.
  2005  * @return bool Whether the path is writable.
  2200  * @return bool Whether the path is writable.
  2006  */
  2201  */
  2007 function win_is_writable( $path ) {
  2202 function win_is_writable( $path ) {
  2008 
  2203 	if ( '/' === $path[ strlen( $path ) - 1 ] ) {
  2009 	if ( $path[ strlen( $path ) - 1 ] == '/' ) { // if it looks like a directory, check a random file within the directory
  2204 		// If it looks like a directory, check a random file within the directory.
  2010 		return win_is_writable( $path . uniqid( mt_rand() ) . '.tmp' );
  2205 		return win_is_writable( $path . uniqid( mt_rand() ) . '.tmp' );
  2011 	} elseif ( is_dir( $path ) ) { // If it's a directory (and not a file) check a random file within the directory
  2206 	} elseif ( is_dir( $path ) ) {
       
  2207 		// If it's a directory (and not a file), check a random file within the directory.
  2012 		return win_is_writable( $path . '/' . uniqid( mt_rand() ) . '.tmp' );
  2208 		return win_is_writable( $path . '/' . uniqid( mt_rand() ) . '.tmp' );
  2013 	}
  2209 	}
  2014 	// check tmp file for read/write capabilities
  2210 
       
  2211 	// Check tmp file for read/write capabilities.
  2015 	$should_delete_tmp_file = ! file_exists( $path );
  2212 	$should_delete_tmp_file = ! file_exists( $path );
  2016 	$f                      = @fopen( $path, 'a' );
  2213 
  2017 	if ( $f === false ) {
  2214 	$f = @fopen( $path, 'a' );
       
  2215 	if ( false === $f ) {
  2018 		return false;
  2216 		return false;
  2019 	}
  2217 	}
  2020 	fclose( $f );
  2218 	fclose( $f );
       
  2219 
  2021 	if ( $should_delete_tmp_file ) {
  2220 	if ( $should_delete_tmp_file ) {
  2022 		unlink( $path );
  2221 		unlink( $path );
  2023 	}
  2222 	}
       
  2223 
  2024 	return true;
  2224 	return true;
  2025 }
  2225 }
  2026 
  2226 
  2027 /**
  2227 /**
  2028  * Retrieves uploads directory information.
  2228  * Retrieves uploads directory information.
  2040 function wp_get_upload_dir() {
  2240 function wp_get_upload_dir() {
  2041 	return wp_upload_dir( null, false );
  2241 	return wp_upload_dir( null, false );
  2042 }
  2242 }
  2043 
  2243 
  2044 /**
  2244 /**
  2045  * Get an array containing the current upload directory's path and url.
  2245  * Returns an array containing the current upload directory's path and URL.
  2046  *
  2246  *
  2047  * Checks the 'upload_path' option, which should be from the web root folder,
  2247  * Checks the 'upload_path' option, which should be from the web root folder,
  2048  * and if it isn't empty it will be used. If it is empty, then the path will be
  2248  * and if it isn't empty it will be used. If it is empty, then the path will be
  2049  * 'WP_CONTENT_DIR/uploads'. If the 'UPLOADS' constant is defined, then it will
  2249  * 'WP_CONTENT_DIR/uploads'. If the 'UPLOADS' constant is defined, then it will
  2050  * override the 'upload_path' option and 'WP_CONTENT_DIR/uploads' path.
  2250  * override the 'upload_path' option and 'WP_CONTENT_DIR/uploads' path.
  2058  *
  2258  *
  2059  * If the path couldn't be created, then an error will be returned with the key
  2259  * If the path couldn't be created, then an error will be returned with the key
  2060  * 'error' containing the error message. The error suggests that the parent
  2260  * 'error' containing the error message. The error suggests that the parent
  2061  * directory is not writable by the server.
  2261  * directory is not writable by the server.
  2062  *
  2262  *
  2063  * On success, the returned array will have many indices:
       
  2064  * 'path' - base directory and sub directory or full path to upload directory.
       
  2065  * 'url' - base url and sub directory or absolute URL to upload directory.
       
  2066  * 'subdir' - sub directory if uploads use year/month folders option is on.
       
  2067  * 'basedir' - path without subdir.
       
  2068  * 'baseurl' - URL path without subdir.
       
  2069  * 'error' - false or error message.
       
  2070  *
       
  2071  * @since 2.0.0
  2263  * @since 2.0.0
  2072  * @uses _wp_upload_dir()
  2264  * @uses _wp_upload_dir()
  2073  *
       
  2074  * @staticvar array $cache
       
  2075  * @staticvar array $tested_paths
       
  2076  *
  2265  *
  2077  * @param string $time Optional. Time formatted in 'yyyy/mm'. Default null.
  2266  * @param string $time Optional. Time formatted in 'yyyy/mm'. Default null.
  2078  * @param bool   $create_dir Optional. Whether to check and create the uploads directory.
  2267  * @param bool   $create_dir Optional. Whether to check and create the uploads directory.
  2079  *                           Default true for backward compatibility.
  2268  *                           Default true for backward compatibility.
  2080  * @param bool   $refresh_cache Optional. Whether to refresh the cache. Default false.
  2269  * @param bool   $refresh_cache Optional. Whether to refresh the cache. Default false.
  2081  * @return array See above for description.
  2270  * @return array {
       
  2271  *     Array of information about the upload directory.
       
  2272  *
       
  2273  *     @type string       $path    Base directory and subdirectory or full path to upload directory.
       
  2274  *     @type string       $url     Base URL and subdirectory or absolute URL to upload directory.
       
  2275  *     @type string       $subdir  Subdirectory if uploads use year/month folders option is on.
       
  2276  *     @type string       $basedir Path without subdir.
       
  2277  *     @type string       $baseurl URL path without subdir.
       
  2278  *     @type string|false $error   False or error message.
       
  2279  * }
  2082  */
  2280  */
  2083 function wp_upload_dir( $time = null, $create_dir = true, $refresh_cache = false ) {
  2281 function wp_upload_dir( $time = null, $create_dir = true, $refresh_cache = false ) {
  2084 	static $cache = array(), $tested_paths = array();
  2282 	static $cache = array(), $tested_paths = array();
  2085 
  2283 
  2086 	$key = sprintf( '%d-%s', get_current_blog_id(), (string) $time );
  2284 	$key = sprintf( '%d-%s', get_current_blog_id(), (string) $time );
  2092 	/**
  2290 	/**
  2093 	 * Filters the uploads directory data.
  2291 	 * Filters the uploads directory data.
  2094 	 *
  2292 	 *
  2095 	 * @since 2.0.0
  2293 	 * @since 2.0.0
  2096 	 *
  2294 	 *
  2097 	 * @param array $uploads Array of upload directory data with keys of 'path',
  2295 	 * @param array $uploads {
  2098 	 *                       'url', 'subdir, 'basedir', and 'error'.
  2296 	 *     Array of information about the upload directory.
       
  2297 	 *
       
  2298 	 *     @type string       $path    Base directory and subdirectory or full path to upload directory.
       
  2299 	 *     @type string       $url     Base URL and subdirectory or absolute URL to upload directory.
       
  2300 	 *     @type string       $subdir  Subdirectory if uploads use year/month folders option is on.
       
  2301 	 *     @type string       $basedir Path without subdir.
       
  2302 	 *     @type string       $baseurl URL path without subdir.
       
  2303 	 *     @type string|false $error   False or error message.
       
  2304 	 * }
  2099 	 */
  2305 	 */
  2100 	$uploads = apply_filters( 'upload_dir', $cache[ $key ] );
  2306 	$uploads = apply_filters( 'upload_dir', $cache[ $key ] );
  2101 
  2307 
  2102 	if ( $create_dir ) {
  2308 	if ( $create_dir ) {
  2103 		$path = $uploads['path'];
  2309 		$path = $uploads['path'];
  2111 				} else {
  2317 				} else {
  2112 					$error_path = wp_basename( $uploads['basedir'] ) . $uploads['subdir'];
  2318 					$error_path = wp_basename( $uploads['basedir'] ) . $uploads['subdir'];
  2113 				}
  2319 				}
  2114 
  2320 
  2115 				$uploads['error'] = sprintf(
  2321 				$uploads['error'] = sprintf(
  2116 					/* translators: %s: directory path */
  2322 					/* translators: %s: Directory path. */
  2117 					__( 'Unable to create directory %s. Is its parent directory writable by the server?' ),
  2323 					__( 'Unable to create directory %s. Is its parent directory writable by the server?' ),
  2118 					esc_html( $error_path )
  2324 					esc_html( $error_path )
  2119 				);
  2325 				);
  2120 			}
  2326 			}
  2121 
  2327 
  2137  */
  2343  */
  2138 function _wp_upload_dir( $time = null ) {
  2344 function _wp_upload_dir( $time = null ) {
  2139 	$siteurl     = get_option( 'siteurl' );
  2345 	$siteurl     = get_option( 'siteurl' );
  2140 	$upload_path = trim( get_option( 'upload_path' ) );
  2346 	$upload_path = trim( get_option( 'upload_path' ) );
  2141 
  2347 
  2142 	if ( empty( $upload_path ) || 'wp-content/uploads' == $upload_path ) {
  2348 	if ( empty( $upload_path ) || 'wp-content/uploads' === $upload_path ) {
  2143 		$dir = WP_CONTENT_DIR . '/uploads';
  2349 		$dir = WP_CONTENT_DIR . '/uploads';
  2144 	} elseif ( 0 !== strpos( $upload_path, ABSPATH ) ) {
  2350 	} elseif ( 0 !== strpos( $upload_path, ABSPATH ) ) {
  2145 		// $dir is absolute, $upload_path is (maybe) relative to ABSPATH
  2351 		// $dir is absolute, $upload_path is (maybe) relative to ABSPATH.
  2146 		$dir = path_join( ABSPATH, $upload_path );
  2352 		$dir = path_join( ABSPATH, $upload_path );
  2147 	} else {
  2353 	} else {
  2148 		$dir = $upload_path;
  2354 		$dir = $upload_path;
  2149 	}
  2355 	}
  2150 
  2356 
  2151 	if ( ! $url = get_option( 'upload_url_path' ) ) {
  2357 	$url = get_option( 'upload_url_path' );
  2152 		if ( empty( $upload_path ) || ( 'wp-content/uploads' == $upload_path ) || ( $upload_path == $dir ) ) {
  2358 	if ( ! $url ) {
       
  2359 		if ( empty( $upload_path ) || ( 'wp-content/uploads' === $upload_path ) || ( $upload_path == $dir ) ) {
  2153 			$url = WP_CONTENT_URL . '/uploads';
  2360 			$url = WP_CONTENT_URL . '/uploads';
  2154 		} else {
  2361 		} else {
  2155 			$url = trailingslashit( $siteurl ) . $upload_path;
  2362 			$url = trailingslashit( $siteurl ) . $upload_path;
  2156 		}
  2363 		}
  2157 	}
  2364 	}
  2163 	if ( defined( 'UPLOADS' ) && ! ( is_multisite() && get_site_option( 'ms_files_rewriting' ) ) ) {
  2370 	if ( defined( 'UPLOADS' ) && ! ( is_multisite() && get_site_option( 'ms_files_rewriting' ) ) ) {
  2164 		$dir = ABSPATH . UPLOADS;
  2371 		$dir = ABSPATH . UPLOADS;
  2165 		$url = trailingslashit( $siteurl ) . UPLOADS;
  2372 		$url = trailingslashit( $siteurl ) . UPLOADS;
  2166 	}
  2373 	}
  2167 
  2374 
  2168 	// If multisite (and if not the main site in a post-MU network)
  2375 	// If multisite (and if not the main site in a post-MU network).
  2169 	if ( is_multisite() && ! ( is_main_network() && is_main_site() && defined( 'MULTISITE' ) ) ) {
  2376 	if ( is_multisite() && ! ( is_main_network() && is_main_site() && defined( 'MULTISITE' ) ) ) {
  2170 
  2377 
  2171 		if ( ! get_site_option( 'ms_files_rewriting' ) ) {
  2378 		if ( ! get_site_option( 'ms_files_rewriting' ) ) {
  2172 			/*
  2379 			/*
  2173 			 * If ms-files rewriting is disabled (networks created post-3.5), it is fairly
  2380 			 * If ms-files rewriting is disabled (networks created post-3.5), it is fairly
  2214 	$basedir = $dir;
  2421 	$basedir = $dir;
  2215 	$baseurl = $url;
  2422 	$baseurl = $url;
  2216 
  2423 
  2217 	$subdir = '';
  2424 	$subdir = '';
  2218 	if ( get_option( 'uploads_use_yearmonth_folders' ) ) {
  2425 	if ( get_option( 'uploads_use_yearmonth_folders' ) ) {
  2219 		// Generate the yearly and monthly dirs
  2426 		// Generate the yearly and monthly directories.
  2220 		if ( ! $time ) {
  2427 		if ( ! $time ) {
  2221 			$time = current_time( 'mysql' );
  2428 			$time = current_time( 'mysql' );
  2222 		}
  2429 		}
  2223 		$y      = substr( $time, 0, 4 );
  2430 		$y      = substr( $time, 0, 4 );
  2224 		$m      = substr( $time, 5, 2 );
  2431 		$m      = substr( $time, 5, 2 );
  2240 
  2447 
  2241 /**
  2448 /**
  2242  * Get a filename that is sanitized and unique for the given directory.
  2449  * Get a filename that is sanitized and unique for the given directory.
  2243  *
  2450  *
  2244  * If the filename is not unique, then a number will be added to the filename
  2451  * If the filename is not unique, then a number will be added to the filename
  2245  * before the extension, and will continue adding numbers until the filename is
  2452  * before the extension, and will continue adding numbers until the filename
  2246  * unique.
  2453  * is unique.
  2247  *
  2454  *
  2248  * The callback is passed three parameters, the first one is the directory, the
  2455  * The callback function allows the caller to use their own method to create
  2249  * second is the filename, and the third is the extension.
  2456  * unique file names. If defined, the callback should take three arguments:
       
  2457  * - directory, base filename, and extension - and return a unique filename.
  2250  *
  2458  *
  2251  * @since 2.5.0
  2459  * @since 2.5.0
  2252  *
  2460  *
  2253  * @param string   $dir                      Directory.
  2461  * @param string   $dir                      Directory.
  2254  * @param string   $filename                 File name.
  2462  * @param string   $filename                 File name.
  2256  * @return string New filename, if given wasn't unique.
  2464  * @return string New filename, if given wasn't unique.
  2257  */
  2465  */
  2258 function wp_unique_filename( $dir, $filename, $unique_filename_callback = null ) {
  2466 function wp_unique_filename( $dir, $filename, $unique_filename_callback = null ) {
  2259 	// Sanitize the file name before we begin processing.
  2467 	// Sanitize the file name before we begin processing.
  2260 	$filename = sanitize_file_name( $filename );
  2468 	$filename = sanitize_file_name( $filename );
       
  2469 	$ext2     = null;
  2261 
  2470 
  2262 	// Separate the filename into a name and extension.
  2471 	// Separate the filename into a name and extension.
  2263 	$ext  = pathinfo( $filename, PATHINFO_EXTENSION );
  2472 	$ext  = pathinfo( $filename, PATHINFO_EXTENSION );
  2264 	$name = pathinfo( $filename, PATHINFO_BASENAME );
  2473 	$name = pathinfo( $filename, PATHINFO_BASENAME );
       
  2474 
  2265 	if ( $ext ) {
  2475 	if ( $ext ) {
  2266 		$ext = '.' . $ext;
  2476 		$ext = '.' . $ext;
  2267 	}
  2477 	}
  2268 
  2478 
  2269 	// Edge case: if file is named '.ext', treat as an empty name.
  2479 	// Edge case: if file is named '.ext', treat as an empty name.
  2277 	 */
  2487 	 */
  2278 	if ( $unique_filename_callback && is_callable( $unique_filename_callback ) ) {
  2488 	if ( $unique_filename_callback && is_callable( $unique_filename_callback ) ) {
  2279 		$filename = call_user_func( $unique_filename_callback, $dir, $name, $ext );
  2489 		$filename = call_user_func( $unique_filename_callback, $dir, $name, $ext );
  2280 	} else {
  2490 	} else {
  2281 		$number = '';
  2491 		$number = '';
       
  2492 		$fname  = pathinfo( $filename, PATHINFO_FILENAME );
       
  2493 
       
  2494 		// Always append a number to file names that can potentially match image sub-size file names.
       
  2495 		if ( $fname && preg_match( '/-(?:\d+x\d+|scaled|rotated)$/', $fname ) ) {
       
  2496 			$number = 1;
       
  2497 
       
  2498 			// At this point the file name may not be unique. This is tested below and the $number is incremented.
       
  2499 			$filename = str_replace( "{$fname}{$ext}", "{$fname}-{$number}{$ext}", $filename );
       
  2500 		}
  2282 
  2501 
  2283 		// Change '.ext' to lower case.
  2502 		// Change '.ext' to lower case.
  2284 		if ( $ext && strtolower( $ext ) != $ext ) {
  2503 		if ( $ext && strtolower( $ext ) != $ext ) {
  2285 			$ext2      = strtolower( $ext );
  2504 			$ext2      = strtolower( $ext );
  2286 			$filename2 = preg_replace( '|' . preg_quote( $ext ) . '$|', $ext2, $filename );
  2505 			$filename2 = preg_replace( '|' . preg_quote( $ext ) . '$|', $ext2, $filename );
  2287 
  2506 
  2288 			// Check for both lower and upper case extension or image sub-sizes may be overwritten.
  2507 			// Check for both lower and upper case extension or image sub-sizes may be overwritten.
  2289 			while ( file_exists( $dir . "/$filename" ) || file_exists( $dir . "/$filename2" ) ) {
  2508 			while ( file_exists( $dir . "/{$filename}" ) || file_exists( $dir . "/{$filename2}" ) ) {
  2290 				$new_number = (int) $number + 1;
  2509 				$new_number = (int) $number + 1;
  2291 				$filename   = str_replace( array( "-$number$ext", "$number$ext" ), "-$new_number$ext", $filename );
  2510 				$filename   = str_replace( array( "-{$number}{$ext}", "{$number}{$ext}" ), "-{$new_number}{$ext}", $filename );
  2292 				$filename2  = str_replace( array( "-$number$ext2", "$number$ext2" ), "-$new_number$ext2", $filename2 );
  2511 				$filename2  = str_replace( array( "-{$number}{$ext2}", "{$number}{$ext2}" ), "-{$new_number}{$ext2}", $filename2 );
  2293 				$number     = $new_number;
  2512 				$number     = $new_number;
  2294 			}
  2513 			}
  2295 
  2514 
       
  2515 			$filename = $filename2;
       
  2516 		} else {
       
  2517 			while ( file_exists( $dir . "/{$filename}" ) ) {
       
  2518 				$new_number = (int) $number + 1;
       
  2519 
       
  2520 				if ( '' === "{$number}{$ext}" ) {
       
  2521 					$filename = "{$filename}-{$new_number}";
       
  2522 				} else {
       
  2523 					$filename = str_replace( array( "-{$number}{$ext}", "{$number}{$ext}" ), "-{$new_number}{$ext}", $filename );
       
  2524 				}
       
  2525 
       
  2526 				$number = $new_number;
       
  2527 			}
       
  2528 		}
       
  2529 
       
  2530 		// Prevent collisions with existing file names that contain dimension-like strings
       
  2531 		// (whether they are subsizes or originals uploaded prior to #42437).
       
  2532 		$upload_dir = wp_get_upload_dir();
       
  2533 
       
  2534 		// The (resized) image files would have name and extension, and will be in the uploads dir.
       
  2535 		if ( $name && $ext && @is_dir( $dir ) && false !== strpos( $dir, $upload_dir['basedir'] ) ) {
  2296 			/**
  2536 			/**
  2297 			 * Filters the result when generating a unique file name.
  2537 			 * Filters the file list used for calculating a unique filename for a newly added file.
  2298 			 *
  2538 			 *
  2299 			 * @since 4.5.0
  2539 			 * Returning an array from the filter will effectively short-circuit retrieval
       
  2540 			 * from the filesystem and return the passed value instead.
  2300 			 *
  2541 			 *
  2301 			 * @param string        $filename                 Unique file name.
  2542 			 * @since 5.5.0
  2302 			 * @param string        $ext                      File extension, eg. ".png".
  2543 			 *
  2303 			 * @param string        $dir                      Directory path.
  2544 			 * @param array|null $files    The list of files to use for filename comparisons.
  2304 			 * @param callable|null $unique_filename_callback Callback function that generates the unique file name.
  2545 			 *                             Default null (to retrieve the list from the filesystem).
       
  2546 			 * @param string     $dir      The directory for the new file.
       
  2547 			 * @param string     $filename The proposed filename for the new file.
  2305 			 */
  2548 			 */
  2306 			return apply_filters( 'wp_unique_filename', $filename2, $ext, $dir, $unique_filename_callback );
  2549 			$files = apply_filters( 'pre_wp_unique_filename_file_list', null, $dir, $filename );
  2307 		}
  2550 
  2308 
  2551 			if ( null === $files ) {
  2309 		while ( file_exists( $dir . "/$filename" ) ) {
  2552 				// List of all files and directories contained in $dir.
  2310 			$new_number = (int) $number + 1;
  2553 				$files = @scandir( $dir );
  2311 			if ( '' == "$number$ext" ) {
       
  2312 				$filename = "$filename-" . $new_number;
       
  2313 			} else {
       
  2314 				$filename = str_replace( array( "-$number$ext", "$number$ext" ), '-' . $new_number . $ext, $filename );
       
  2315 			}
  2554 			}
  2316 			$number = $new_number;
  2555 
  2317 		}
  2556 			if ( ! empty( $files ) ) {
  2318 	}
  2557 				// Remove "dot" dirs.
  2319 
  2558 				$files = array_diff( $files, array( '.', '..' ) );
  2320 	/** This filter is documented in wp-includes/functions.php */
  2559 			}
       
  2560 
       
  2561 			if ( ! empty( $files ) ) {
       
  2562 				// The extension case may have changed above.
       
  2563 				$new_ext = ! empty( $ext2 ) ? $ext2 : $ext;
       
  2564 
       
  2565 				// Ensure this never goes into infinite loop
       
  2566 				// as it uses pathinfo() and regex in the check, but string replacement for the changes.
       
  2567 				$count = count( $files );
       
  2568 				$i     = 0;
       
  2569 
       
  2570 				while ( $i <= $count && _wp_check_existing_file_names( $filename, $files ) ) {
       
  2571 					$new_number = (int) $number + 1;
       
  2572 					$filename   = str_replace( array( "-{$number}{$new_ext}", "{$number}{$new_ext}" ), "-{$new_number}{$new_ext}", $filename );
       
  2573 					$number     = $new_number;
       
  2574 					$i++;
       
  2575 				}
       
  2576 			}
       
  2577 		}
       
  2578 	}
       
  2579 
       
  2580 	/**
       
  2581 	 * Filters the result when generating a unique file name.
       
  2582 	 *
       
  2583 	 * @since 4.5.0
       
  2584 	 *
       
  2585 	 * @param string        $filename                 Unique file name.
       
  2586 	 * @param string        $ext                      File extension, eg. ".png".
       
  2587 	 * @param string        $dir                      Directory path.
       
  2588 	 * @param callable|null $unique_filename_callback Callback function that generates the unique file name.
       
  2589 	 */
  2321 	return apply_filters( 'wp_unique_filename', $filename, $ext, $dir, $unique_filename_callback );
  2590 	return apply_filters( 'wp_unique_filename', $filename, $ext, $dir, $unique_filename_callback );
       
  2591 }
       
  2592 
       
  2593 /**
       
  2594  * Helper function to check if a file name could match an existing image sub-size file name.
       
  2595  *
       
  2596  * @since 5.3.1
       
  2597  * @access private
       
  2598  *
       
  2599  * @param string $filename The file name to check.
       
  2600  * @param array  $files    An array of existing files in the directory.
       
  2601  * @return bool True if the tested file name could match an existing file, false otherwise.
       
  2602  */
       
  2603 function _wp_check_existing_file_names( $filename, $files ) {
       
  2604 	$fname = pathinfo( $filename, PATHINFO_FILENAME );
       
  2605 	$ext   = pathinfo( $filename, PATHINFO_EXTENSION );
       
  2606 
       
  2607 	// Edge case, file names like `.ext`.
       
  2608 	if ( empty( $fname ) ) {
       
  2609 		return false;
       
  2610 	}
       
  2611 
       
  2612 	if ( $ext ) {
       
  2613 		$ext = ".$ext";
       
  2614 	}
       
  2615 
       
  2616 	$regex = '/^' . preg_quote( $fname ) . '-(?:\d+x\d+|scaled|rotated)' . preg_quote( $ext ) . '$/i';
       
  2617 
       
  2618 	foreach ( $files as $file ) {
       
  2619 		if ( preg_match( $regex, $file ) ) {
       
  2620 			return true;
       
  2621 		}
       
  2622 	}
       
  2623 
       
  2624 	return false;
  2322 }
  2625 }
  2323 
  2626 
  2324 /**
  2627 /**
  2325  * Create a file in the upload folder with given content.
  2628  * Create a file in the upload folder with given content.
  2326  *
  2629  *
  2336  *
  2639  *
  2337  * The permissions will be set on the new file automatically by this function.
  2640  * The permissions will be set on the new file automatically by this function.
  2338  *
  2641  *
  2339  * @since 2.0.0
  2642  * @since 2.0.0
  2340  *
  2643  *
  2341  * @param string       $name       Filename.
  2644  * @param string      $name       Filename.
  2342  * @param null|string  $deprecated Never used. Set to null.
  2645  * @param null|string $deprecated Never used. Set to null.
  2343  * @param mixed        $bits       File content
  2646  * @param string      $bits       File content
  2344  * @param string       $time       Optional. Time formatted in 'yyyy/mm'. Default null.
  2647  * @param string      $time       Optional. Time formatted in 'yyyy/mm'. Default null.
  2345  * @return array
  2648  * @return array {
       
  2649  *     Information about the newly-uploaded file.
       
  2650  *
       
  2651  *     @type string       $file  Filename of the newly-uploaded file.
       
  2652  *     @type string       $url   URL of the uploaded file.
       
  2653  *     @type string       $type  File type.
       
  2654  *     @type string|false $error Error message, if there has been an error.
       
  2655  * }
  2346  */
  2656  */
  2347 function wp_upload_bits( $name, $deprecated, $bits, $time = null ) {
  2657 function wp_upload_bits( $name, $deprecated, $bits, $time = null ) {
  2348 	if ( ! empty( $deprecated ) ) {
  2658 	if ( ! empty( $deprecated ) ) {
  2349 		_deprecated_argument( __FUNCTION__, '2.0.0' );
  2659 		_deprecated_argument( __FUNCTION__, '2.0.0' );
  2350 	}
  2660 	}
  2358 		return array( 'error' => __( 'Sorry, this file type is not permitted for security reasons.' ) );
  2668 		return array( 'error' => __( 'Sorry, this file type is not permitted for security reasons.' ) );
  2359 	}
  2669 	}
  2360 
  2670 
  2361 	$upload = wp_upload_dir( $time );
  2671 	$upload = wp_upload_dir( $time );
  2362 
  2672 
  2363 	if ( $upload['error'] !== false ) {
  2673 	if ( false !== $upload['error'] ) {
  2364 		return $upload;
  2674 		return $upload;
  2365 	}
  2675 	}
  2366 
  2676 
  2367 	/**
  2677 	/**
  2368 	 * Filters whether to treat the upload bits as an error.
  2678 	 * Filters whether to treat the upload bits as an error.
  2369 	 *
  2679 	 *
  2370 	 * Passing a non-array to the filter will effectively short-circuit preparing
  2680 	 * Returning a non-array from the filter will effectively short-circuit preparing the upload bits
  2371 	 * the upload bits, returning that value instead.
  2681 	 * and return that value instead. An error message should be returned as a string.
  2372 	 *
  2682 	 *
  2373 	 * @since 3.0.0
  2683 	 * @since 3.0.0
  2374 	 *
  2684 	 *
  2375 	 * @param mixed $upload_bits_error An array of upload bits data, or a non-array error to return.
  2685 	 * @param array|string $upload_bits_error An array of upload bits data, or error message to return.
  2376 	 */
  2686 	 */
  2377 	$upload_bits_error = apply_filters(
  2687 	$upload_bits_error = apply_filters(
  2378 		'wp_upload_bits',
  2688 		'wp_upload_bits',
  2379 		array(
  2689 		array(
  2380 			'name' => $name,
  2690 			'name' => $name,
  2396 		} else {
  2706 		} else {
  2397 			$error_path = wp_basename( $upload['basedir'] ) . $upload['subdir'];
  2707 			$error_path = wp_basename( $upload['basedir'] ) . $upload['subdir'];
  2398 		}
  2708 		}
  2399 
  2709 
  2400 		$message = sprintf(
  2710 		$message = sprintf(
  2401 			/* translators: %s: directory path */
  2711 			/* translators: %s: Directory path. */
  2402 			__( 'Unable to create directory %s. Is its parent directory writable by the server?' ),
  2712 			__( 'Unable to create directory %s. Is its parent directory writable by the server?' ),
  2403 			$error_path
  2713 			$error_path
  2404 		);
  2714 		);
  2405 		return array( 'error' => $message );
  2715 		return array( 'error' => $message );
  2406 	}
  2716 	}
  2407 
  2717 
  2408 	$ifp = @ fopen( $new_file, 'wb' );
  2718 	$ifp = @fopen( $new_file, 'wb' );
  2409 	if ( ! $ifp ) {
  2719 	if ( ! $ifp ) {
  2410 		return array( 'error' => sprintf( __( 'Could not write file %s' ), $new_file ) );
  2720 		return array(
  2411 	}
  2721 			/* translators: %s: File name. */
  2412 
  2722 			'error' => sprintf( __( 'Could not write file %s' ), $new_file ),
  2413 	@fwrite( $ifp, $bits );
  2723 		);
       
  2724 	}
       
  2725 
       
  2726 	fwrite( $ifp, $bits );
  2414 	fclose( $ifp );
  2727 	fclose( $ifp );
  2415 	clearstatcache();
  2728 	clearstatcache();
  2416 
  2729 
  2417 	// Set correct file permissions
  2730 	// Set correct file permissions.
  2418 	$stat  = @ stat( dirname( $new_file ) );
  2731 	$stat  = @ stat( dirname( $new_file ) );
  2419 	$perms = $stat['mode'] & 0007777;
  2732 	$perms = $stat['mode'] & 0007777;
  2420 	$perms = $perms & 0000666;
  2733 	$perms = $perms & 0000666;
  2421 	@ chmod( $new_file, $perms );
  2734 	chmod( $new_file, $perms );
  2422 	clearstatcache();
  2735 	clearstatcache();
  2423 
  2736 
  2424 	// Compute the URL
  2737 	// Compute the URL.
  2425 	$url = $upload['url'] . "/$filename";
  2738 	$url = $upload['url'] . "/$filename";
  2426 
  2739 
  2427 	/** This filter is documented in wp-admin/includes/file.php */
  2740 	/** This filter is documented in wp-admin/includes/file.php */
  2428 	return apply_filters(
  2741 	return apply_filters(
  2429 		'wp_handle_upload',
  2742 		'wp_handle_upload',
  2448 function wp_ext2type( $ext ) {
  2761 function wp_ext2type( $ext ) {
  2449 	$ext = strtolower( $ext );
  2762 	$ext = strtolower( $ext );
  2450 
  2763 
  2451 	$ext2type = wp_get_ext_types();
  2764 	$ext2type = wp_get_ext_types();
  2452 	foreach ( $ext2type as $type => $exts ) {
  2765 	foreach ( $ext2type as $type => $exts ) {
  2453 		if ( in_array( $ext, $exts ) ) {
  2766 		if ( in_array( $ext, $exts, true ) ) {
  2454 			return $type;
  2767 			return $type;
  2455 		}
  2768 		}
  2456 	}
  2769 	}
  2457 }
  2770 }
  2458 
  2771 
  2461  *
  2774  *
  2462  * You can optionally define the mime array, if needed.
  2775  * You can optionally define the mime array, if needed.
  2463  *
  2776  *
  2464  * @since 2.0.4
  2777  * @since 2.0.4
  2465  *
  2778  *
  2466  * @param string $filename File name or path.
  2779  * @param string   $filename File name or path.
  2467  * @param array  $mimes    Optional. Key is the file extension with value as the mime type.
  2780  * @param string[] $mimes    Optional. Array of mime types keyed by their file extension regex.
  2468  * @return array Values with extension first and mime type.
  2781  * @return array {
       
  2782  *     Values for the extension and mime type.
       
  2783  *
       
  2784  *     @type string|false $ext  File extension, or false if the file doesn't match a mime type.
       
  2785  *     @type string|false $type File mime type, or false if the file doesn't match a mime type.
       
  2786  * }
  2469  */
  2787  */
  2470 function wp_check_filetype( $filename, $mimes = null ) {
  2788 function wp_check_filetype( $filename, $mimes = null ) {
  2471 	if ( empty( $mimes ) ) {
  2789 	if ( empty( $mimes ) ) {
  2472 		$mimes = get_allowed_mime_types();
  2790 		$mimes = get_allowed_mime_types();
  2473 	}
  2791 	}
  2496  *
  2814  *
  2497  * Currently this function only supports renaming images validated via wp_get_image_mime().
  2815  * Currently this function only supports renaming images validated via wp_get_image_mime().
  2498  *
  2816  *
  2499  * @since 3.0.0
  2817  * @since 3.0.0
  2500  *
  2818  *
  2501  * @param string $file     Full path to the file.
  2819  * @param string   $file     Full path to the file.
  2502  * @param string $filename The name of the file (may differ from $file due to $file being
  2820  * @param string   $filename The name of the file (may differ from $file due to $file being
  2503  *                         in a tmp directory).
  2821  *                           in a tmp directory).
  2504  * @param array   $mimes   Optional. Key is the file extension with value as the mime type.
  2822  * @param string[] $mimes    Optional. Array of mime types keyed by their file extension regex.
  2505  * @return array Values for the extension, MIME, and either a corrected filename or false
  2823  * @return array {
  2506  *               if original $filename is valid.
  2824  *     Values for the extension, mime type, and corrected filename.
       
  2825  *
       
  2826  *     @type string|false $ext             File extension, or false if the file doesn't match a mime type.
       
  2827  *     @type string|false $type            File mime type, or false if the file doesn't match a mime type.
       
  2828  *     @type string|false $proper_filename File name with its correct extension, or false if it cannot be determined.
       
  2829  * }
  2507  */
  2830  */
  2508 function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
  2831 function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
  2509 	$proper_filename = false;
  2832 	$proper_filename = false;
  2510 
  2833 
  2511 	// Do basic extension validation and MIME mapping
  2834 	// Do basic extension validation and MIME mapping.
  2512 	$wp_filetype = wp_check_filetype( $filename, $mimes );
  2835 	$wp_filetype = wp_check_filetype( $filename, $mimes );
  2513 	$ext         = $wp_filetype['ext'];
  2836 	$ext         = $wp_filetype['ext'];
  2514 	$type        = $wp_filetype['type'];
  2837 	$type        = $wp_filetype['type'];
  2515 
  2838 
  2516 	// We can't do any further validation without a file to work with
  2839 	// We can't do any further validation without a file to work with.
  2517 	if ( ! file_exists( $file ) ) {
  2840 	if ( ! file_exists( $file ) ) {
  2518 		return compact( 'ext', 'type', 'proper_filename' );
  2841 		return compact( 'ext', 'type', 'proper_filename' );
  2519 	}
  2842 	}
  2520 
  2843 
  2521 	$real_mime = false;
  2844 	$real_mime = false;
  2522 
  2845 
  2523 	// Validate image types.
  2846 	// Validate image types.
  2524 	if ( $type && 0 === strpos( $type, 'image/' ) ) {
  2847 	if ( $type && 0 === strpos( $type, 'image/' ) ) {
  2525 
  2848 
  2526 		// Attempt to figure out what type of image it actually is
  2849 		// Attempt to figure out what type of image it actually is.
  2527 		$real_mime = wp_get_image_mime( $file );
  2850 		$real_mime = wp_get_image_mime( $file );
  2528 
  2851 
  2529 		if ( $real_mime && $real_mime != $type ) {
  2852 		if ( $real_mime && $real_mime != $type ) {
  2530 			/**
  2853 			/**
  2531 			 * Filters the list mapping image mime types to their respective extensions.
  2854 			 * Filters the list mapping image mime types to their respective extensions.
  2532 			 *
  2855 			 *
  2533 			 * @since 3.0.0
  2856 			 * @since 3.0.0
  2534 			 *
  2857 			 *
  2535 			 * @param  array $mime_to_ext Array of image mime types and their matching extensions.
  2858 			 * @param array $mime_to_ext Array of image mime types and their matching extensions.
  2536 			 */
  2859 			 */
  2537 			$mime_to_ext = apply_filters(
  2860 			$mime_to_ext = apply_filters(
  2538 				'getimagesize_mimes_to_exts',
  2861 				'getimagesize_mimes_to_exts',
  2539 				array(
  2862 				array(
  2540 					'image/jpeg' => 'jpg',
  2863 					'image/jpeg' => 'jpg',
  2543 					'image/bmp'  => 'bmp',
  2866 					'image/bmp'  => 'bmp',
  2544 					'image/tiff' => 'tif',
  2867 					'image/tiff' => 'tif',
  2545 				)
  2868 				)
  2546 			);
  2869 			);
  2547 
  2870 
  2548 			// Replace whatever is after the last period in the filename with the correct extension
  2871 			// Replace whatever is after the last period in the filename with the correct extension.
  2549 			if ( ! empty( $mime_to_ext[ $real_mime ] ) ) {
  2872 			if ( ! empty( $mime_to_ext[ $real_mime ] ) ) {
  2550 				$filename_parts = explode( '.', $filename );
  2873 				$filename_parts = explode( '.', $filename );
  2551 				array_pop( $filename_parts );
  2874 				array_pop( $filename_parts );
  2552 				$filename_parts[] = $mime_to_ext[ $real_mime ];
  2875 				$filename_parts[] = $mime_to_ext[ $real_mime ];
  2553 				$new_filename     = implode( '.', $filename_parts );
  2876 				$new_filename     = implode( '.', $filename_parts );
  2554 
  2877 
  2555 				if ( $new_filename != $filename ) {
  2878 				if ( $new_filename != $filename ) {
  2556 					$proper_filename = $new_filename; // Mark that it changed
  2879 					$proper_filename = $new_filename; // Mark that it changed.
  2557 				}
  2880 				}
  2558 				// Redefine the extension / MIME
  2881 				// Redefine the extension / MIME.
  2559 				$wp_filetype = wp_check_filetype( $new_filename, $mimes );
  2882 				$wp_filetype = wp_check_filetype( $new_filename, $mimes );
  2560 				$ext         = $wp_filetype['ext'];
  2883 				$ext         = $wp_filetype['ext'];
  2561 				$type        = $wp_filetype['type'];
  2884 				$type        = $wp_filetype['type'];
  2562 			} else {
  2885 			} else {
  2563 				// Reset $real_mime and try validating again.
  2886 				// Reset $real_mime and try validating again.
  2570 	if ( $type && ! $real_mime && extension_loaded( 'fileinfo' ) ) {
  2893 	if ( $type && ! $real_mime && extension_loaded( 'fileinfo' ) ) {
  2571 		$finfo     = finfo_open( FILEINFO_MIME_TYPE );
  2894 		$finfo     = finfo_open( FILEINFO_MIME_TYPE );
  2572 		$real_mime = finfo_file( $finfo, $file );
  2895 		$real_mime = finfo_file( $finfo, $file );
  2573 		finfo_close( $finfo );
  2896 		finfo_close( $finfo );
  2574 
  2897 
  2575 		// fileinfo often misidentifies obscure files as one of these types
  2898 		// fileinfo often misidentifies obscure files as one of these types.
  2576 		$nonspecific_types = array(
  2899 		$nonspecific_types = array(
  2577 			'application/octet-stream',
  2900 			'application/octet-stream',
  2578 			'application/encrypted',
  2901 			'application/encrypted',
  2579 			'application/CDFV2-encrypted',
  2902 			'application/CDFV2-encrypted',
  2580 			'application/zip',
  2903 			'application/zip',
  2585 		 * we need to do some additional vetting. Media types and those listed in $nonspecific_types are
  2908 		 * we need to do some additional vetting. Media types and those listed in $nonspecific_types are
  2586 		 * allowed some leeway, but anything else must exactly match the real content type.
  2909 		 * allowed some leeway, but anything else must exactly match the real content type.
  2587 		 */
  2910 		 */
  2588 		if ( in_array( $real_mime, $nonspecific_types, true ) ) {
  2911 		if ( in_array( $real_mime, $nonspecific_types, true ) ) {
  2589 			// File is a non-specific binary type. That's ok if it's a type that generally tends to be binary.
  2912 			// File is a non-specific binary type. That's ok if it's a type that generally tends to be binary.
  2590 			if ( ! in_array( substr( $type, 0, strcspn( $type, '/' ) ), array( 'application', 'video', 'audio' ) ) ) {
  2913 			if ( ! in_array( substr( $type, 0, strcspn( $type, '/' ) ), array( 'application', 'video', 'audio' ), true ) ) {
  2591 				$type = $ext = false;
  2914 				$type = false;
       
  2915 				$ext  = false;
  2592 			}
  2916 			}
  2593 		} elseif ( 0 === strpos( $real_mime, 'video/' ) || 0 === strpos( $real_mime, 'audio/' ) ) {
  2917 		} elseif ( 0 === strpos( $real_mime, 'video/' ) || 0 === strpos( $real_mime, 'audio/' ) ) {
  2594 			/*
  2918 			/*
  2595 			 * For these types, only the major type must match the real value.
  2919 			 * For these types, only the major type must match the real value.
  2596 			 * This means that common mismatches are forgiven: application/vnd.apple.numbers is often misidentified as application/zip,
  2920 			 * This means that common mismatches are forgiven: application/vnd.apple.numbers is often misidentified as application/zip,
  2597 			 * and some media files are commonly named with the wrong extension (.mov instead of .mp4)
  2921 			 * and some media files are commonly named with the wrong extension (.mov instead of .mp4)
  2598 			 */
  2922 			 */
  2599 			if ( substr( $real_mime, 0, strcspn( $real_mime, '/' ) ) !== substr( $type, 0, strcspn( $type, '/' ) ) ) {
  2923 			if ( substr( $real_mime, 0, strcspn( $real_mime, '/' ) ) !== substr( $type, 0, strcspn( $type, '/' ) ) ) {
  2600 				$type = $ext = false;
  2924 				$type = false;
       
  2925 				$ext  = false;
  2601 			}
  2926 			}
  2602 		} elseif ( 'text/plain' === $real_mime ) {
  2927 		} elseif ( 'text/plain' === $real_mime ) {
  2603 			// A few common file types are occasionally detected as text/plain; allow those.
  2928 			// A few common file types are occasionally detected as text/plain; allow those.
  2604 			if ( ! in_array(
  2929 			if ( ! in_array(
  2605 				$type,
  2930 				$type,
  2607 					'text/plain',
  2932 					'text/plain',
  2608 					'text/csv',
  2933 					'text/csv',
  2609 					'text/richtext',
  2934 					'text/richtext',
  2610 					'text/tsv',
  2935 					'text/tsv',
  2611 					'text/vtt',
  2936 					'text/vtt',
  2612 				)
  2937 				),
       
  2938 				true
  2613 			)
  2939 			)
  2614 			) {
  2940 			) {
  2615 				$type = $ext = false;
  2941 				$type = false;
       
  2942 				$ext  = false;
  2616 			}
  2943 			}
  2617 		} elseif ( 'text/rtf' === $real_mime ) {
  2944 		} elseif ( 'text/rtf' === $real_mime ) {
  2618 			// Special casing for RTF files.
  2945 			// Special casing for RTF files.
  2619 			if ( ! in_array(
  2946 			if ( ! in_array(
  2620 				$type,
  2947 				$type,
  2621 				array(
  2948 				array(
  2622 					'text/rtf',
  2949 					'text/rtf',
  2623 					'text/plain',
  2950 					'text/plain',
  2624 					'application/rtf',
  2951 					'application/rtf',
  2625 				)
  2952 				),
       
  2953 				true
  2626 			)
  2954 			)
  2627 			) {
  2955 			) {
  2628 				$type = $ext = false;
  2956 				$type = false;
       
  2957 				$ext  = false;
  2629 			}
  2958 			}
  2630 		} else {
  2959 		} else {
  2631 			if ( $type !== $real_mime ) {
  2960 			if ( $type !== $real_mime ) {
  2632 				/*
  2961 				/*
  2633 				 * Everything else including image/* and application/*:
  2962 				 * Everything else including image/* and application/*:
  2634 				 * If the real content type doesn't match the file extension, assume it's dangerous.
  2963 				 * If the real content type doesn't match the file extension, assume it's dangerous.
  2635 				 */
  2964 				 */
  2636 				$type = $ext = false;
  2965 				$type = false;
       
  2966 				$ext  = false;
  2637 			}
  2967 			}
  2638 		}
  2968 		}
  2639 	}
  2969 	}
  2640 
  2970 
  2641 	// The mime type must be allowed
  2971 	// The mime type must be allowed.
  2642 	if ( $type ) {
  2972 	if ( $type ) {
  2643 		$allowed = get_allowed_mime_types();
  2973 		$allowed = get_allowed_mime_types();
  2644 
  2974 
  2645 		if ( ! in_array( $type, $allowed ) ) {
  2975 		if ( ! in_array( $type, $allowed, true ) ) {
  2646 			$type = $ext = false;
  2976 			$type = false;
       
  2977 			$ext  = false;
  2647 		}
  2978 		}
  2648 	}
  2979 	}
  2649 
  2980 
  2650 	/**
  2981 	/**
  2651 	 * Filters the "real" file type of the given file.
  2982 	 * Filters the "real" file type of the given file.
  2652 	 *
  2983 	 *
  2653 	 * @since 3.0.0
  2984 	 * @since 3.0.0
  2654 	 * @since 5.1.0 The $real_mime parameter was added.
  2985 	 * @since 5.1.0 The $real_mime parameter was added.
  2655 	 *
  2986 	 *
  2656 	 * @param array       $wp_check_filetype_and_ext File data array containing 'ext', 'type', and
  2987 	 * @param array       $wp_check_filetype_and_ext {
  2657 	 *                                               'proper_filename' keys.
  2988 	 *     Values for the extension, mime type, and corrected filename.
       
  2989 	 *
       
  2990 	 *     @type string|false $ext             File extension, or false if the file doesn't match a mime type.
       
  2991 	 *     @type string|false $type            File mime type, or false if the file doesn't match a mime type.
       
  2992 	 *     @type string|false $proper_filename File name with its correct extension, or false if it cannot be determined.
       
  2993 	 * }
  2658 	 * @param string      $file                      Full path to the file.
  2994 	 * @param string      $file                      Full path to the file.
  2659 	 * @param string      $filename                  The name of the file (may differ from $file due to
  2995 	 * @param string      $filename                  The name of the file (may differ from $file due to
  2660 	 *                                               $file being in a tmp directory).
  2996 	 *                                               $file being in a tmp directory).
  2661 	 * @param array       $mimes                     Key is the file extension with value as the mime type.
  2997 	 * @param string[]    $mimes                     Array of mime types keyed by their file extension regex.
  2662 	 * @param string|bool $real_mime                 The actual mime type or false if the type cannot be determined.
  2998 	 * @param string|bool $real_mime                 The actual mime type or false if the type cannot be determined.
  2663 	 */
  2999 	 */
  2664 	return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes, $real_mime );
  3000 	return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes, $real_mime );
  2665 }
  3001 }
  2666 
  3002 
  2683 	try {
  3019 	try {
  2684 		if ( is_callable( 'exif_imagetype' ) ) {
  3020 		if ( is_callable( 'exif_imagetype' ) ) {
  2685 			$imagetype = exif_imagetype( $file );
  3021 			$imagetype = exif_imagetype( $file );
  2686 			$mime      = ( $imagetype ) ? image_type_to_mime_type( $imagetype ) : false;
  3022 			$mime      = ( $imagetype ) ? image_type_to_mime_type( $imagetype ) : false;
  2687 		} elseif ( function_exists( 'getimagesize' ) ) {
  3023 		} elseif ( function_exists( 'getimagesize' ) ) {
  2688 			$imagesize = getimagesize( $file );
  3024 			$imagesize = @getimagesize( $file );
  2689 			$mime      = ( isset( $imagesize['mime'] ) ) ? $imagesize['mime'] : false;
  3025 			$mime      = ( isset( $imagesize['mime'] ) ) ? $imagesize['mime'] : false;
  2690 		} else {
  3026 		} else {
  2691 			$mime = false;
  3027 			$mime = false;
  2692 		}
  3028 		}
  2693 	} catch ( Exception $e ) {
  3029 	} catch ( Exception $e ) {
  2699 
  3035 
  2700 /**
  3036 /**
  2701  * Retrieve list of mime types and file extensions.
  3037  * Retrieve list of mime types and file extensions.
  2702  *
  3038  *
  2703  * @since 3.5.0
  3039  * @since 3.5.0
  2704  * @since 4.2.0 Support was added for GIMP (xcf) files.
  3040  * @since 4.2.0 Support was added for GIMP (.xcf) files.
  2705  *
  3041  * @since 4.9.2 Support was added for Flac (.flac) files.
  2706  * @return array Array of mime types keyed by the file extension regex corresponding to those types.
  3042  * @since 4.9.6 Support was added for AAC (.aac) files.
       
  3043  *
       
  3044  * @return string[] Array of mime types keyed by the file extension regex corresponding to those types.
  2707  */
  3045  */
  2708 function wp_get_mime_types() {
  3046 function wp_get_mime_types() {
  2709 	/**
  3047 	/**
  2710 	 * Filters the list of mime types and file extensions.
  3048 	 * Filters the list of mime types and file extensions.
  2711 	 *
  3049 	 *
  2712 	 * This filter should be used to add, not remove, mime types. To remove
  3050 	 * This filter should be used to add, not remove, mime types. To remove
  2713 	 * mime types, use the {@see 'upload_mimes'} filter.
  3051 	 * mime types, use the {@see 'upload_mimes'} filter.
  2714 	 *
  3052 	 *
  2715 	 * @since 3.5.0
  3053 	 * @since 3.5.0
  2716 	 *
  3054 	 *
  2717 	 * @param array $wp_get_mime_types Mime types keyed by the file extension regex
  3055 	 * @param string[] $wp_get_mime_types Mime types keyed by the file extension regex
  2718 	 *                                 corresponding to those types.
  3056 	 *                                 corresponding to those types.
  2719 	 */
  3057 	 */
  2720 	return apply_filters(
  3058 	return apply_filters(
  2721 		'mime_types',
  3059 		'mime_types',
  2722 		array(
  3060 		array(
  2725 			'gif'                          => 'image/gif',
  3063 			'gif'                          => 'image/gif',
  2726 			'png'                          => 'image/png',
  3064 			'png'                          => 'image/png',
  2727 			'bmp'                          => 'image/bmp',
  3065 			'bmp'                          => 'image/bmp',
  2728 			'tiff|tif'                     => 'image/tiff',
  3066 			'tiff|tif'                     => 'image/tiff',
  2729 			'ico'                          => 'image/x-icon',
  3067 			'ico'                          => 'image/x-icon',
       
  3068 			'heic'                         => 'image/heic',
  2730 			// Video formats.
  3069 			// Video formats.
  2731 			'asf|asx'                      => 'video/x-ms-asf',
  3070 			'asf|asx'                      => 'video/x-ms-asf',
  2732 			'wmv'                          => 'video/x-ms-wmv',
  3071 			'wmv'                          => 'video/x-ms-wmv',
  2733 			'wmx'                          => 'video/x-ms-wmx',
  3072 			'wmx'                          => 'video/x-ms-wmx',
  2734 			'wm'                           => 'video/x-ms-wm',
  3073 			'wm'                           => 'video/x-ms-wm',
  2739 			'mpeg|mpg|mpe'                 => 'video/mpeg',
  3078 			'mpeg|mpg|mpe'                 => 'video/mpeg',
  2740 			'mp4|m4v'                      => 'video/mp4',
  3079 			'mp4|m4v'                      => 'video/mp4',
  2741 			'ogv'                          => 'video/ogg',
  3080 			'ogv'                          => 'video/ogg',
  2742 			'webm'                         => 'video/webm',
  3081 			'webm'                         => 'video/webm',
  2743 			'mkv'                          => 'video/x-matroska',
  3082 			'mkv'                          => 'video/x-matroska',
  2744 			'3gp|3gpp'                     => 'video/3gpp', // Can also be audio
  3083 			'3gp|3gpp'                     => 'video/3gpp',  // Can also be audio.
  2745 			'3g2|3gp2'                     => 'video/3gpp2', // Can also be audio
  3084 			'3g2|3gp2'                     => 'video/3gpp2', // Can also be audio.
  2746 			// Text formats.
  3085 			// Text formats.
  2747 			'txt|asc|c|cc|h|srt'           => 'text/plain',
  3086 			'txt|asc|c|cc|h|srt'           => 'text/plain',
  2748 			'csv'                          => 'text/csv',
  3087 			'csv'                          => 'text/csv',
  2749 			'tsv'                          => 'text/tab-separated-values',
  3088 			'tsv'                          => 'text/tab-separated-values',
  2750 			'ics'                          => 'text/calendar',
  3089 			'ics'                          => 'text/calendar',
  2828 /**
  3167 /**
  2829  * Retrieves the list of common file extensions and their types.
  3168  * Retrieves the list of common file extensions and their types.
  2830  *
  3169  *
  2831  * @since 4.6.0
  3170  * @since 4.6.0
  2832  *
  3171  *
  2833  * @return array Array of file extensions types keyed by the type of file.
  3172  * @return array[] Multi-dimensional array of file extensions types keyed by the type of file.
  2834  */
  3173  */
  2835 function wp_get_ext_types() {
  3174 function wp_get_ext_types() {
  2836 
  3175 
  2837 	/**
  3176 	/**
  2838 	 * Filters file type based on the extension name.
  3177 	 * Filters file type based on the extension name.
  2839 	 *
  3178 	 *
  2840 	 * @since 2.5.0
  3179 	 * @since 2.5.0
  2841 	 *
  3180 	 *
  2842 	 * @see wp_ext2type()
  3181 	 * @see wp_ext2type()
  2843 	 *
  3182 	 *
  2844 	 * @param array $ext2type Multi-dimensional array with extensions for a default set
  3183 	 * @param array[] $ext2type Multi-dimensional array of file extensions types keyed by the type of file.
  2845 	 *                        of file types.
       
  2846 	 */
  3184 	 */
  2847 	return apply_filters(
  3185 	return apply_filters(
  2848 		'ext2type',
  3186 		'ext2type',
  2849 		array(
  3187 		array(
  2850 			'image'       => array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'bmp', 'tif', 'tiff', 'ico' ),
  3188 			'image'       => array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'bmp', 'tif', 'tiff', 'ico', 'heic' ),
  2851 			'audio'       => array( 'aac', 'ac3', 'aif', 'aiff', 'flac', 'm3a', 'm4a', 'm4b', 'mka', 'mp1', 'mp2', 'mp3', 'ogg', 'oga', 'ram', 'wav', 'wma' ),
  3189 			'audio'       => array( 'aac', 'ac3', 'aif', 'aiff', 'flac', 'm3a', 'm4a', 'm4b', 'mka', 'mp1', 'mp2', 'mp3', 'ogg', 'oga', 'ram', 'wav', 'wma' ),
  2852 			'video'       => array( '3g2', '3gp', '3gpp', 'asf', 'avi', 'divx', 'dv', 'flv', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'mpv', 'ogm', 'ogv', 'qt', 'rm', 'vob', 'wmv' ),
  3190 			'video'       => array( '3g2', '3gp', '3gpp', 'asf', 'avi', 'divx', 'dv', 'flv', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'mpv', 'ogm', 'ogv', 'qt', 'rm', 'vob', 'wmv' ),
  2853 			'document'    => array( 'doc', 'docx', 'docm', 'dotm', 'odt', 'pages', 'pdf', 'xps', 'oxps', 'rtf', 'wp', 'wpd', 'psd', 'xcf' ),
  3191 			'document'    => array( 'doc', 'docx', 'docm', 'dotm', 'odt', 'pages', 'pdf', 'xps', 'oxps', 'rtf', 'wp', 'wpd', 'psd', 'xcf' ),
  2854 			'spreadsheet' => array( 'numbers', 'ods', 'xls', 'xlsx', 'xlsm', 'xlsb' ),
  3192 			'spreadsheet' => array( 'numbers', 'ods', 'xls', 'xlsx', 'xlsm', 'xlsb' ),
  2855 			'interactive' => array( 'swf', 'key', 'ppt', 'pptx', 'pptm', 'pps', 'ppsx', 'ppsm', 'sldx', 'sldm', 'odp' ),
  3193 			'interactive' => array( 'swf', 'key', 'ppt', 'pptx', 'pptm', 'pps', 'ppsx', 'ppsm', 'sldx', 'sldm', 'odp' ),
  2864  * Retrieve list of allowed mime types and file extensions.
  3202  * Retrieve list of allowed mime types and file extensions.
  2865  *
  3203  *
  2866  * @since 2.8.6
  3204  * @since 2.8.6
  2867  *
  3205  *
  2868  * @param int|WP_User $user Optional. User to check. Defaults to current user.
  3206  * @param int|WP_User $user Optional. User to check. Defaults to current user.
  2869  * @return array Array of mime types keyed by the file extension regex corresponding
  3207  * @return string[] Array of mime types keyed by the file extension regex corresponding
  2870  *               to those types.
  3208  *                  to those types.
  2871  */
  3209  */
  2872 function get_allowed_mime_types( $user = null ) {
  3210 function get_allowed_mime_types( $user = null ) {
  2873 	$t = wp_get_mime_types();
  3211 	$t = wp_get_mime_types();
  2874 
  3212 
  2875 	unset( $t['swf'], $t['exe'] );
  3213 	unset( $t['swf'], $t['exe'] );
  2884 	/**
  3222 	/**
  2885 	 * Filters list of allowed mime types and file extensions.
  3223 	 * Filters list of allowed mime types and file extensions.
  2886 	 *
  3224 	 *
  2887 	 * @since 2.0.0
  3225 	 * @since 2.0.0
  2888 	 *
  3226 	 *
  2889 	 * @param array            $t    Mime types keyed by the file extension regex corresponding to
  3227 	 * @param array            $t    Mime types keyed by the file extension regex corresponding to those types.
  2890 	 *                               those types. 'swf' and 'exe' removed from full list. 'htm|html' also
       
  2891 	 *                               removed depending on '$user' capabilities.
       
  2892 	 * @param int|WP_User|null $user User ID, User object or null if not provided (indicates current user).
  3228 	 * @param int|WP_User|null $user User ID, User object or null if not provided (indicates current user).
  2893 	 */
  3229 	 */
  2894 	return apply_filters( 'upload_mimes', $t, $user );
  3230 	return apply_filters( 'upload_mimes', $t, $user );
  2895 }
  3231 }
  2896 
  3232 
  2903  * @since 2.0.4
  3239  * @since 2.0.4
  2904  *
  3240  *
  2905  * @param string $action The nonce action.
  3241  * @param string $action The nonce action.
  2906  */
  3242  */
  2907 function wp_nonce_ays( $action ) {
  3243 function wp_nonce_ays( $action ) {
  2908 	if ( 'log-out' == $action ) {
  3244 	if ( 'log-out' === $action ) {
  2909 		$html = sprintf(
  3245 		$html = sprintf(
  2910 			/* translators: %s: site name */
  3246 			/* translators: %s: Site title. */
  2911 			__( 'You are attempting to log out of %s' ),
  3247 			__( 'You are attempting to log out of %s' ),
  2912 			get_bloginfo( 'name' )
  3248 			get_bloginfo( 'name' )
  2913 		);
  3249 		);
  2914 		$html       .= '</p><p>';
  3250 		$html       .= '</p><p>';
  2915 		$redirect_to = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '';
  3251 		$redirect_to = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '';
  2916 		$html       .= sprintf(
  3252 		$html       .= sprintf(
  2917 			/* translators: %s: logout URL */
  3253 			/* translators: %s: Logout URL. */
  2918 			__( 'Do you really want to <a href="%s">log out</a>?' ),
  3254 			__( 'Do you really want to <a href="%s">log out</a>?' ),
  2919 			wp_logout_url( $redirect_to )
  3255 			wp_logout_url( $redirect_to )
  2920 		);
  3256 		);
  2921 	} else {
  3257 	} else {
  2922 		$html = __( 'The link you followed has expired.' );
  3258 		$html = __( 'The link you followed has expired.' );
  2947  *
  3283  *
  2948  * @since 2.0.4
  3284  * @since 2.0.4
  2949  * @since 4.1.0 The `$title` and `$args` parameters were changed to optionally accept
  3285  * @since 4.1.0 The `$title` and `$args` parameters were changed to optionally accept
  2950  *              an integer to be used as the response code.
  3286  *              an integer to be used as the response code.
  2951  * @since 5.1.0 The `$link_url`, `$link_text`, and `$exit` arguments were added.
  3287  * @since 5.1.0 The `$link_url`, `$link_text`, and `$exit` arguments were added.
  2952  *
  3288  * @since 5.3.0 The `$charset` argument was added.
  2953  * @global WP_Query $wp_query Global WP_Query instance.
  3289  * @since 5.5.0 The `$text_direction` argument has a priority over get_language_attributes()
       
  3290  *              in the default handler.
       
  3291  *
       
  3292  * @global WP_Query $wp_query WordPress Query object.
  2954  *
  3293  *
  2955  * @param string|WP_Error  $message Optional. Error message. If this is a WP_Error object,
  3294  * @param string|WP_Error  $message Optional. Error message. If this is a WP_Error object,
  2956  *                                  and not an Ajax or XML-RPC request, the error's messages are used.
  3295  *                                  and not an Ajax or XML-RPC request, the error's messages are used.
  2957  *                                  Default empty.
  3296  *                                  Default empty.
  2958  * @param string|int       $title   Optional. Error title. If `$message` is a `WP_Error` object,
  3297  * @param string|int       $title   Optional. Error title. If `$message` is a `WP_Error` object,
  2967  *     @type string $link_url       A URL to include a link to. Only works in combination with $link_text.
  3306  *     @type string $link_url       A URL to include a link to. Only works in combination with $link_text.
  2968  *                                  Default empty string.
  3307  *                                  Default empty string.
  2969  *     @type string $link_text      A label for the link to include. Only works in combination with $link_url.
  3308  *     @type string $link_text      A label for the link to include. Only works in combination with $link_url.
  2970  *                                  Default empty string.
  3309  *                                  Default empty string.
  2971  *     @type bool   $back_link      Whether to include a link to go back. Default false.
  3310  *     @type bool   $back_link      Whether to include a link to go back. Default false.
  2972  *     @type string $text_direction The text direction. This is only useful internally, when WordPress
  3311  *     @type string $text_direction The text direction. This is only useful internally, when WordPress is still
  2973  *                                  is still loading and the site's locale is not set up yet. Accepts 'rtl'.
  3312  *                                  loading and the site's locale is not set up yet. Accepts 'rtl' and 'ltr'.
  2974  *                                  Default is the value of is_rtl().
  3313  *                                  Default is the value of is_rtl().
       
  3314  *     @type string $charset        Character set of the HTML output. Default 'utf-8'.
  2975  *     @type string $code           Error code to use. Default is 'wp_die', or the main error code if $message
  3315  *     @type string $code           Error code to use. Default is 'wp_die', or the main error code if $message
  2976  *                                  is a WP_Error.
  3316  *                                  is a WP_Error.
  2977  *     @type bool   $exit           Whether to exit the process after completion. Default true.
  3317  *     @type bool   $exit           Whether to exit the process after completion. Default true.
  2978  * }
  3318  * }
  2979  */
  3319  */
  3062  * @param string|WP_Error $message Error message or WP_Error object.
  3402  * @param string|WP_Error $message Error message or WP_Error object.
  3063  * @param string          $title   Optional. Error title. Default empty.
  3403  * @param string          $title   Optional. Error title. Default empty.
  3064  * @param string|array    $args    Optional. Arguments to control behavior. Default empty array.
  3404  * @param string|array    $args    Optional. Arguments to control behavior. Default empty array.
  3065  */
  3405  */
  3066 function _default_wp_die_handler( $message, $title = '', $args = array() ) {
  3406 function _default_wp_die_handler( $message, $title = '', $args = array() ) {
  3067 	list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args );
  3407 	list( $message, $title, $parsed_args ) = _wp_die_process_input( $message, $title, $args );
  3068 
  3408 
  3069 	if ( is_string( $message ) ) {
  3409 	if ( is_string( $message ) ) {
  3070 		if ( ! empty( $r['additional_errors'] ) ) {
  3410 		if ( ! empty( $parsed_args['additional_errors'] ) ) {
  3071 			$message = array_merge(
  3411 			$message = array_merge(
  3072 				array( $message ),
  3412 				array( $message ),
  3073 				wp_list_pluck( $r['additional_errors'], 'message' )
  3413 				wp_list_pluck( $parsed_args['additional_errors'], 'message' )
  3074 			);
  3414 			);
  3075 			$message = "<ul>\n\t\t<li>" . join( "</li>\n\t\t<li>", $message ) . "</li>\n\t</ul>";
  3415 			$message = "<ul>\n\t\t<li>" . join( "</li>\n\t\t<li>", $message ) . "</li>\n\t</ul>";
  3076 		} else {
  3416 		}
  3077 			$message = "<p>$message</p>";
  3417 
  3078 		}
  3418 		$message = sprintf(
       
  3419 			'<div class="wp-die-message">%s</div>',
       
  3420 			$message
       
  3421 		);
  3079 	}
  3422 	}
  3080 
  3423 
  3081 	$have_gettext = function_exists( '__' );
  3424 	$have_gettext = function_exists( '__' );
  3082 
  3425 
  3083 	if ( ! empty( $r['link_url'] ) && ! empty( $r['link_text'] ) ) {
  3426 	if ( ! empty( $parsed_args['link_url'] ) && ! empty( $parsed_args['link_text'] ) ) {
  3084 		$link_url = $r['link_url'];
  3427 		$link_url = $parsed_args['link_url'];
  3085 		if ( function_exists( 'esc_url' ) ) {
  3428 		if ( function_exists( 'esc_url' ) ) {
  3086 			$link_url = esc_url( $link_url );
  3429 			$link_url = esc_url( $link_url );
  3087 		}
  3430 		}
  3088 		$link_text = $r['link_text'];
  3431 		$link_text = $parsed_args['link_text'];
  3089 		$message  .= "\n<p><a href='{$link_url}'>{$link_text}</a></p>";
  3432 		$message  .= "\n<p><a href='{$link_url}'>{$link_text}</a></p>";
  3090 	}
  3433 	}
  3091 
  3434 
  3092 	if ( isset( $r['back_link'] ) && $r['back_link'] ) {
  3435 	if ( isset( $parsed_args['back_link'] ) && $parsed_args['back_link'] ) {
  3093 		$back_text = $have_gettext ? __( '&laquo; Back' ) : '&laquo; Back';
  3436 		$back_text = $have_gettext ? __( '&laquo; Back' ) : '&laquo; Back';
  3094 		$message  .= "\n<p><a href='javascript:history.back()'>$back_text</a></p>";
  3437 		$message  .= "\n<p><a href='javascript:history.back()'>$back_text</a></p>";
  3095 	}
  3438 	}
  3096 
  3439 
  3097 	if ( ! did_action( 'admin_head' ) ) :
  3440 	if ( ! did_action( 'admin_head' ) ) :
  3098 		if ( ! headers_sent() ) {
  3441 		if ( ! headers_sent() ) {
  3099 			header( 'Content-Type: text/html; charset=utf-8' );
  3442 			header( "Content-Type: text/html; charset={$parsed_args['charset']}" );
  3100 			status_header( $r['response'] );
  3443 			status_header( $parsed_args['response'] );
  3101 			nocache_headers();
  3444 			nocache_headers();
  3102 		}
  3445 		}
  3103 
  3446 
  3104 		$text_direction = $r['text_direction'];
  3447 		$text_direction = $parsed_args['text_direction'];
  3105 		if ( function_exists( 'language_attributes' ) && function_exists( 'is_rtl' ) ) {
  3448 		$dir_attr       = "dir='$text_direction'";
       
  3449 
       
  3450 		// If `text_direction` was not explicitly passed,
       
  3451 		// use get_language_attributes() if available.
       
  3452 		if ( empty( $args['text_direction'] )
       
  3453 			&& function_exists( 'language_attributes' ) && function_exists( 'is_rtl' )
       
  3454 		) {
  3106 			$dir_attr = get_language_attributes();
  3455 			$dir_attr = get_language_attributes();
  3107 		} else {
       
  3108 			$dir_attr = "dir='$text_direction'";
       
  3109 		}
  3456 		}
  3110 		?>
  3457 		?>
  3111 <!DOCTYPE html>
  3458 <!DOCTYPE html>
  3112 <html xmlns="http://www.w3.org/1999/xhtml" <?php echo $dir_attr; ?>>
  3459 <html <?php echo $dir_attr; ?>>
  3113 <head>
  3460 <head>
  3114 	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  3461 	<meta http-equiv="Content-Type" content="text/html; charset=<?php echo $parsed_args['charset']; ?>" />
  3115 	<meta name="viewport" content="width=device-width">
  3462 	<meta name="viewport" content="width=device-width">
  3116 		<?php
  3463 		<?php
  3117 		if ( function_exists( 'wp_no_robots' ) ) {
  3464 		if ( function_exists( 'wp_no_robots' ) ) {
  3118 			wp_no_robots();
  3465 			wp_no_robots();
  3119 		}
  3466 		}
  3143 			padding-bottom: 7px;
  3490 			padding-bottom: 7px;
  3144 		}
  3491 		}
  3145 		#error-page {
  3492 		#error-page {
  3146 			margin-top: 50px;
  3493 			margin-top: 50px;
  3147 		}
  3494 		}
  3148 		#error-page p {
  3495 		#error-page p,
       
  3496 		#error-page .wp-die-message {
  3149 			font-size: 14px;
  3497 			font-size: 14px;
  3150 			line-height: 1.5;
  3498 			line-height: 1.5;
  3151 			margin: 25px 0 20px;
  3499 			margin: 25px 0 20px;
  3152 		}
  3500 		}
  3153 		#error-page code {
  3501 		#error-page code {
  3160 		a {
  3508 		a {
  3161 			color: #0073aa;
  3509 			color: #0073aa;
  3162 		}
  3510 		}
  3163 		a:hover,
  3511 		a:hover,
  3164 		a:active {
  3512 		a:active {
  3165 			color: #00a0d2;
  3513 			color: #006799;
  3166 		}
  3514 		}
  3167 		a:focus {
  3515 		a:focus {
  3168 			color: #124964;
  3516 			color: #124964;
  3169 			-webkit-box-shadow:
  3517 			-webkit-box-shadow:
  3170 				0 0 0 1px #5b9dd9,
  3518 				0 0 0 1px #5b9dd9,
  3179 			border: 1px solid #ccc;
  3527 			border: 1px solid #ccc;
  3180 			color: #555;
  3528 			color: #555;
  3181 			display: inline-block;
  3529 			display: inline-block;
  3182 			text-decoration: none;
  3530 			text-decoration: none;
  3183 			font-size: 13px;
  3531 			font-size: 13px;
  3184 			line-height: 26px;
  3532 			line-height: 2;
  3185 			height: 28px;
  3533 			height: 28px;
  3186 			margin: 0;
  3534 			margin: 0;
  3187 			padding: 0 10px 1px;
  3535 			padding: 0 10px 1px;
  3188 			cursor: pointer;
  3536 			cursor: pointer;
  3189 			-webkit-border-radius: 3px;
  3537 			-webkit-border-radius: 3px;
  3194 			-moz-box-sizing:    border-box;
  3542 			-moz-box-sizing:    border-box;
  3195 			box-sizing:         border-box;
  3543 			box-sizing:         border-box;
  3196 
  3544 
  3197 			-webkit-box-shadow: 0 1px 0 #ccc;
  3545 			-webkit-box-shadow: 0 1px 0 #ccc;
  3198 			box-shadow: 0 1px 0 #ccc;
  3546 			box-shadow: 0 1px 0 #ccc;
  3199 			 vertical-align: top;
  3547 			vertical-align: top;
  3200 		}
  3548 		}
  3201 
  3549 
  3202 		.button.button-large {
  3550 		.button.button-large {
  3203 			height: 30px;
  3551 			height: 30px;
  3204 			line-height: 28px;
  3552 			line-height: 2.15384615;
  3205 			padding: 0 12px 2px;
  3553 			padding: 0 12px 2px;
  3206 		}
  3554 		}
  3207 
  3555 
  3208 		.button:hover,
  3556 		.button:hover,
  3209 		.button:focus {
  3557 		.button:focus {
  3220 		}
  3568 		}
  3221 
  3569 
  3222 		.button:active {
  3570 		.button:active {
  3223 			background: #eee;
  3571 			background: #eee;
  3224 			border-color: #999;
  3572 			border-color: #999;
  3225 			 -webkit-box-shadow: inset 0 2px 5px -3px rgba(0, 0, 0, 0.5);
  3573 			-webkit-box-shadow: inset 0 2px 5px -3px rgba(0, 0, 0, 0.5);
  3226 			 box-shadow: inset 0 2px 5px -3px rgba(0, 0, 0, 0.5);
  3574 			box-shadow: inset 0 2px 5px -3px rgba(0, 0, 0, 0.5);
  3227 			 -webkit-transform: translateY(1px);
       
  3228 			 -ms-transform: translateY(1px);
       
  3229 			 transform: translateY(1px);
       
  3230 		}
  3575 		}
  3231 
  3576 
  3232 		<?php
  3577 		<?php
  3233 		if ( 'rtl' == $text_direction ) {
  3578 		if ( 'rtl' === $text_direction ) {
  3234 			echo 'body { font-family: Tahoma, Arial; }';
  3579 			echo 'body { font-family: Tahoma, Arial; }';
  3235 		}
  3580 		}
  3236 		?>
  3581 		?>
  3237 	</style>
  3582 	</style>
  3238 </head>
  3583 </head>
  3240 <?php endif; // ! did_action( 'admin_head' ) ?>
  3585 <?php endif; // ! did_action( 'admin_head' ) ?>
  3241 	<?php echo $message; ?>
  3586 	<?php echo $message; ?>
  3242 </body>
  3587 </body>
  3243 </html>
  3588 </html>
  3244 	<?php
  3589 	<?php
  3245 	if ( $r['exit'] ) {
  3590 	if ( $parsed_args['exit'] ) {
  3246 		die();
  3591 		die();
  3247 	}
  3592 	}
  3248 }
  3593 }
  3249 
  3594 
  3250 /**
  3595 /**
  3258  * @param string       $message Error message.
  3603  * @param string       $message Error message.
  3259  * @param string       $title   Optional. Error title (unused). Default empty.
  3604  * @param string       $title   Optional. Error title (unused). Default empty.
  3260  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  3605  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  3261  */
  3606  */
  3262 function _ajax_wp_die_handler( $message, $title = '', $args = array() ) {
  3607 function _ajax_wp_die_handler( $message, $title = '', $args = array() ) {
  3263 	// Set default 'response' to 200 for AJAX requests.
  3608 	// Set default 'response' to 200 for Ajax requests.
  3264 	$args = wp_parse_args(
  3609 	$args = wp_parse_args(
  3265 		$args,
  3610 		$args,
  3266 		array( 'response' => 200 )
  3611 		array( 'response' => 200 )
  3267 	);
  3612 	);
  3268 
  3613 
  3269 	list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args );
  3614 	list( $message, $title, $parsed_args ) = _wp_die_process_input( $message, $title, $args );
  3270 
  3615 
  3271 	if ( ! headers_sent() ) {
  3616 	if ( ! headers_sent() ) {
  3272 		// This is intentional. For backward-compatibility, support passing null here.
  3617 		// This is intentional. For backward-compatibility, support passing null here.
  3273 		if ( null !== $args['response'] ) {
  3618 		if ( null !== $args['response'] ) {
  3274 			status_header( $r['response'] );
  3619 			status_header( $parsed_args['response'] );
  3275 		}
  3620 		}
  3276 		nocache_headers();
  3621 		nocache_headers();
  3277 	}
  3622 	}
  3278 
  3623 
  3279 	if ( is_scalar( $message ) ) {
  3624 	if ( is_scalar( $message ) ) {
  3280 		$message = (string) $message;
  3625 		$message = (string) $message;
  3281 	} else {
  3626 	} else {
  3282 		$message = '0';
  3627 		$message = '0';
  3283 	}
  3628 	}
  3284 
  3629 
  3285 	if ( $r['exit'] ) {
  3630 	if ( $parsed_args['exit'] ) {
  3286 		die( $message );
  3631 		die( $message );
  3287 	}
  3632 	}
  3288 
  3633 
  3289 	echo $message;
  3634 	echo $message;
  3290 }
  3635 }
  3300  * @param string       $message Error message.
  3645  * @param string       $message Error message.
  3301  * @param string       $title   Optional. Error title. Default empty.
  3646  * @param string       $title   Optional. Error title. Default empty.
  3302  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  3647  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  3303  */
  3648  */
  3304 function _json_wp_die_handler( $message, $title = '', $args = array() ) {
  3649 function _json_wp_die_handler( $message, $title = '', $args = array() ) {
  3305 	list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args );
  3650 	list( $message, $title, $parsed_args ) = _wp_die_process_input( $message, $title, $args );
  3306 
  3651 
  3307 	$data = array(
  3652 	$data = array(
  3308 		'code'              => $r['code'],
  3653 		'code'              => $parsed_args['code'],
  3309 		'message'           => $message,
  3654 		'message'           => $message,
  3310 		'data'              => array(
  3655 		'data'              => array(
  3311 			'status' => $r['response'],
  3656 			'status' => $parsed_args['response'],
  3312 		),
  3657 		),
  3313 		'additional_errors' => $r['additional_errors'],
  3658 		'additional_errors' => $parsed_args['additional_errors'],
  3314 	);
  3659 	);
  3315 
  3660 
  3316 	if ( ! headers_sent() ) {
  3661 	if ( ! headers_sent() ) {
  3317 		header( 'Content-Type: application/json; charset=utf-8' );
  3662 		header( "Content-Type: application/json; charset={$parsed_args['charset']}" );
  3318 		if ( null !== $r['response'] ) {
  3663 		if ( null !== $parsed_args['response'] ) {
  3319 			status_header( $r['response'] );
  3664 			status_header( $parsed_args['response'] );
  3320 		}
  3665 		}
  3321 		nocache_headers();
  3666 		nocache_headers();
  3322 	}
  3667 	}
  3323 
  3668 
  3324 	echo wp_json_encode( $data );
  3669 	echo wp_json_encode( $data );
  3325 	if ( $r['exit'] ) {
  3670 	if ( $parsed_args['exit'] ) {
  3326 		die();
  3671 		die();
  3327 	}
  3672 	}
  3328 }
  3673 }
  3329 
  3674 
  3330 /**
  3675 /**
  3338  * @param string       $message Error message.
  3683  * @param string       $message Error message.
  3339  * @param string       $title   Optional. Error title. Default empty.
  3684  * @param string       $title   Optional. Error title. Default empty.
  3340  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  3685  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  3341  */
  3686  */
  3342 function _jsonp_wp_die_handler( $message, $title = '', $args = array() ) {
  3687 function _jsonp_wp_die_handler( $message, $title = '', $args = array() ) {
  3343 	list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args );
  3688 	list( $message, $title, $parsed_args ) = _wp_die_process_input( $message, $title, $args );
  3344 
  3689 
  3345 	$data = array(
  3690 	$data = array(
  3346 		'code'              => $r['code'],
  3691 		'code'              => $parsed_args['code'],
  3347 		'message'           => $message,
  3692 		'message'           => $message,
  3348 		'data'              => array(
  3693 		'data'              => array(
  3349 			'status' => $r['response'],
  3694 			'status' => $parsed_args['response'],
  3350 		),
  3695 		),
  3351 		'additional_errors' => $r['additional_errors'],
  3696 		'additional_errors' => $parsed_args['additional_errors'],
  3352 	);
  3697 	);
  3353 
  3698 
  3354 	if ( ! headers_sent() ) {
  3699 	if ( ! headers_sent() ) {
  3355 		header( 'Content-Type: application/javascript; charset=utf-8' );
  3700 		header( "Content-Type: application/javascript; charset={$parsed_args['charset']}" );
  3356 		header( 'X-Content-Type-Options: nosniff' );
  3701 		header( 'X-Content-Type-Options: nosniff' );
  3357 		header( 'X-Robots-Tag: noindex' );
  3702 		header( 'X-Robots-Tag: noindex' );
  3358 		if ( null !== $r['response'] ) {
  3703 		if ( null !== $parsed_args['response'] ) {
  3359 			status_header( $r['response'] );
  3704 			status_header( $parsed_args['response'] );
  3360 		}
  3705 		}
  3361 		nocache_headers();
  3706 		nocache_headers();
  3362 	}
  3707 	}
  3363 
  3708 
  3364 	$result         = wp_json_encode( $data );
  3709 	$result         = wp_json_encode( $data );
  3365 	$jsonp_callback = $_GET['_jsonp'];
  3710 	$jsonp_callback = $_GET['_jsonp'];
  3366 	echo '/**/' . $jsonp_callback . '(' . $result . ')';
  3711 	echo '/**/' . $jsonp_callback . '(' . $result . ')';
  3367 	if ( $r['exit'] ) {
  3712 	if ( $parsed_args['exit'] ) {
  3368 		die();
  3713 		die();
  3369 	}
  3714 	}
  3370 }
  3715 }
  3371 
  3716 
  3372 /**
  3717 /**
  3384  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  3729  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  3385  */
  3730  */
  3386 function _xmlrpc_wp_die_handler( $message, $title = '', $args = array() ) {
  3731 function _xmlrpc_wp_die_handler( $message, $title = '', $args = array() ) {
  3387 	global $wp_xmlrpc_server;
  3732 	global $wp_xmlrpc_server;
  3388 
  3733 
  3389 	list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args );
  3734 	list( $message, $title, $parsed_args ) = _wp_die_process_input( $message, $title, $args );
  3390 
  3735 
  3391 	if ( ! headers_sent() ) {
  3736 	if ( ! headers_sent() ) {
  3392 		nocache_headers();
  3737 		nocache_headers();
  3393 	}
  3738 	}
  3394 
  3739 
  3395 	if ( $wp_xmlrpc_server ) {
  3740 	if ( $wp_xmlrpc_server ) {
  3396 		$error = new IXR_Error( $r['response'], $message );
  3741 		$error = new IXR_Error( $parsed_args['response'], $message );
  3397 		$wp_xmlrpc_server->output( $error->getXml() );
  3742 		$wp_xmlrpc_server->output( $error->getXml() );
  3398 	}
  3743 	}
  3399 	if ( $r['exit'] ) {
  3744 	if ( $parsed_args['exit'] ) {
  3400 		die();
  3745 		die();
  3401 	}
  3746 	}
  3402 }
  3747 }
  3403 
  3748 
  3404 /**
  3749 /**
  3412  * @param string       $message Error message.
  3757  * @param string       $message Error message.
  3413  * @param string       $title   Optional. Error title. Default empty.
  3758  * @param string       $title   Optional. Error title. Default empty.
  3414  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  3759  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  3415  */
  3760  */
  3416 function _xml_wp_die_handler( $message, $title = '', $args = array() ) {
  3761 function _xml_wp_die_handler( $message, $title = '', $args = array() ) {
  3417 	list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args );
  3762 	list( $message, $title, $parsed_args ) = _wp_die_process_input( $message, $title, $args );
  3418 
  3763 
  3419 	$message = htmlspecialchars( $message );
  3764 	$message = htmlspecialchars( $message );
  3420 	$title   = htmlspecialchars( $title );
  3765 	$title   = htmlspecialchars( $title );
  3421 
  3766 
  3422 	$xml = <<<EOD
  3767 	$xml = <<<EOD
  3423 <error>
  3768 <error>
  3424     <code>{$r['code']}</code>
  3769     <code>{$parsed_args['code']}</code>
  3425     <title><![CDATA[{$title}]]></title>
  3770     <title><![CDATA[{$title}]]></title>
  3426     <message><![CDATA[{$message}]]></message>
  3771     <message><![CDATA[{$message}]]></message>
  3427     <data>
  3772     <data>
  3428         <status>{$r['response']}</status>
  3773         <status>{$parsed_args['response']}</status>
  3429     </data>
  3774     </data>
  3430 </error>
  3775 </error>
  3431 
  3776 
  3432 EOD;
  3777 EOD;
  3433 
  3778 
  3434 	if ( ! headers_sent() ) {
  3779 	if ( ! headers_sent() ) {
  3435 		header( 'Content-Type: text/xml; charset=utf-8' );
  3780 		header( "Content-Type: text/xml; charset={$parsed_args['charset']}" );
  3436 		if ( null !== $r['response'] ) {
  3781 		if ( null !== $parsed_args['response'] ) {
  3437 			status_header( $r['response'] );
  3782 			status_header( $parsed_args['response'] );
  3438 		}
  3783 		}
  3439 		nocache_headers();
  3784 		nocache_headers();
  3440 	}
  3785 	}
  3441 
  3786 
  3442 	echo $xml;
  3787 	echo $xml;
  3443 	if ( $r['exit'] ) {
  3788 	if ( $parsed_args['exit'] ) {
  3444 		die();
  3789 		die();
  3445 	}
  3790 	}
  3446 }
  3791 }
  3447 
  3792 
  3448 /**
  3793 /**
  3457  * @param string       $message Optional. Response to print. Default empty.
  3802  * @param string       $message Optional. Response to print. Default empty.
  3458  * @param string       $title   Optional. Error title (unused). Default empty.
  3803  * @param string       $title   Optional. Error title (unused). Default empty.
  3459  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  3804  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  3460  */
  3805  */
  3461 function _scalar_wp_die_handler( $message = '', $title = '', $args = array() ) {
  3806 function _scalar_wp_die_handler( $message = '', $title = '', $args = array() ) {
  3462 	list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args );
  3807 	list( $message, $title, $parsed_args ) = _wp_die_process_input( $message, $title, $args );
  3463 
  3808 
  3464 	if ( $r['exit'] ) {
  3809 	if ( $parsed_args['exit'] ) {
  3465 		if ( is_scalar( $message ) ) {
  3810 		if ( is_scalar( $message ) ) {
  3466 			die( (string) $message );
  3811 			die( (string) $message );
  3467 		}
  3812 		}
  3468 		die();
  3813 		die();
  3469 	}
  3814 	}
  3477  * Processes arguments passed to wp_die() consistently for its handlers.
  3822  * Processes arguments passed to wp_die() consistently for its handlers.
  3478  *
  3823  *
  3479  * @since 5.1.0
  3824  * @since 5.1.0
  3480  * @access private
  3825  * @access private
  3481  *
  3826  *
  3482  * @param string       $message Error message.
  3827  * @param string|WP_Error $message Error message or WP_Error object.
  3483  * @param string       $title   Optional. Error title. Default empty.
  3828  * @param string          $title   Optional. Error title. Default empty.
  3484  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  3829  * @param string|array    $args    Optional. Arguments to control behavior. Default empty array.
  3485  * @return array List of processed $message string, $title string, and $args array.
  3830  * @return array {
       
  3831  *     Processed arguments.
       
  3832  *
       
  3833  *     @type string $0 Error message.
       
  3834  *     @type string $1 Error title.
       
  3835  *     @type array  $2 Arguments to control behavior.
       
  3836  * }
  3486  */
  3837  */
  3487 function _wp_die_process_input( $message, $title = '', $args = array() ) {
  3838 function _wp_die_process_input( $message, $title = '', $args = array() ) {
  3488 	$defaults = array(
  3839 	$defaults = array(
  3489 		'response'          => 0,
  3840 		'response'          => 0,
  3490 		'code'              => '',
  3841 		'code'              => '',
  3491 		'exit'              => true,
  3842 		'exit'              => true,
  3492 		'back_link'         => false,
  3843 		'back_link'         => false,
  3493 		'link_url'          => '',
  3844 		'link_url'          => '',
  3494 		'link_text'         => '',
  3845 		'link_text'         => '',
  3495 		'text_direction'    => '',
  3846 		'text_direction'    => '',
       
  3847 		'charset'           => 'utf-8',
  3496 		'additional_errors' => array(),
  3848 		'additional_errors' => array(),
  3497 	);
  3849 	);
  3498 
  3850 
  3499 	$args = wp_parse_args( $args, $defaults );
  3851 	$args = wp_parse_args( $args, $defaults );
  3500 
  3852 
  3546 		if ( function_exists( 'is_rtl' ) && is_rtl() ) {
  3898 		if ( function_exists( 'is_rtl' ) && is_rtl() ) {
  3547 			$args['text_direction'] = 'rtl';
  3899 			$args['text_direction'] = 'rtl';
  3548 		}
  3900 		}
  3549 	}
  3901 	}
  3550 
  3902 
       
  3903 	if ( ! empty( $args['charset'] ) ) {
       
  3904 		$args['charset'] = _canonical_charset( $args['charset'] );
       
  3905 	}
       
  3906 
  3551 	return array( $message, $title, $args );
  3907 	return array( $message, $title, $args );
  3552 }
  3908 }
  3553 
  3909 
  3554 /**
  3910 /**
  3555  * Encode a variable into JSON, with some sanity checks.
  3911  * Encode a variable into JSON, with some sanity checks.
  3556  *
  3912  *
  3557  * @since 4.1.0
  3913  * @since 4.1.0
       
  3914  * @since 5.3.0 No longer handles support for PHP < 5.6.
  3558  *
  3915  *
  3559  * @param mixed $data    Variable (usually an array or object) to encode as JSON.
  3916  * @param mixed $data    Variable (usually an array or object) to encode as JSON.
  3560  * @param int   $options Optional. Options to be passed to json_encode(). Default 0.
  3917  * @param int   $options Optional. Options to be passed to json_encode(). Default 0.
  3561  * @param int   $depth   Optional. Maximum depth to walk through $data. Must be
  3918  * @param int   $depth   Optional. Maximum depth to walk through $data. Must be
  3562  *                       greater than 0. Default 512.
  3919  *                       greater than 0. Default 512.
  3563  * @return string|false The JSON encoded string, or false if it cannot be encoded.
  3920  * @return string|false The JSON encoded string, or false if it cannot be encoded.
  3564  */
  3921  */
  3565 function wp_json_encode( $data, $options = 0, $depth = 512 ) {
  3922 function wp_json_encode( $data, $options = 0, $depth = 512 ) {
  3566 	/*
  3923 	$json = json_encode( $data, $options, $depth );
  3567 	 * json_encode() has had extra params added over the years.
       
  3568 	 * $options was added in 5.3, and $depth in 5.5.
       
  3569 	 * We need to make sure we call it with the correct arguments.
       
  3570 	 */
       
  3571 	if ( version_compare( PHP_VERSION, '5.5', '>=' ) ) {
       
  3572 		$args = array( $data, $options, $depth );
       
  3573 	} elseif ( version_compare( PHP_VERSION, '5.3', '>=' ) ) {
       
  3574 		$args = array( $data, $options );
       
  3575 	} else {
       
  3576 		$args = array( $data );
       
  3577 	}
       
  3578 
       
  3579 	// Prepare the data for JSON serialization.
       
  3580 	$args[0] = _wp_json_prepare_data( $data );
       
  3581 
       
  3582 	$json = @call_user_func_array( 'json_encode', $args );
       
  3583 
  3924 
  3584 	// If json_encode() was successful, no need to do more sanity checking.
  3925 	// If json_encode() was successful, no need to do more sanity checking.
  3585 	// ... unless we're in an old version of PHP, and json_encode() returned
  3926 	if ( false !== $json ) {
  3586 	// a string containing 'null'. Then we need to do more sanity checking.
       
  3587 	if ( false !== $json && ( version_compare( PHP_VERSION, '5.5', '>=' ) || false === strpos( $json, 'null' ) ) ) {
       
  3588 		return $json;
  3927 		return $json;
  3589 	}
  3928 	}
  3590 
  3929 
  3591 	try {
  3930 	try {
  3592 		$args[0] = _wp_json_sanity_check( $data, $depth );
  3931 		$data = _wp_json_sanity_check( $data, $depth );
  3593 	} catch ( Exception $e ) {
  3932 	} catch ( Exception $e ) {
  3594 		return false;
  3933 		return false;
  3595 	}
  3934 	}
  3596 
  3935 
  3597 	return call_user_func_array( 'json_encode', $args );
  3936 	return json_encode( $data, $options, $depth );
  3598 }
  3937 }
  3599 
  3938 
  3600 /**
  3939 /**
  3601  * Perform sanity checks on data that shall be encoded to JSON.
  3940  * Perform sanity checks on data that shall be encoded to JSON.
  3602  *
  3941  *
  3603  * @ignore
  3942  * @ignore
  3604  * @since 4.1.0
  3943  * @since 4.1.0
  3605  * @access private
  3944  * @access private
  3606  *
  3945  *
  3607  * @see wp_json_encode()
  3946  * @see wp_json_encode()
       
  3947  *
       
  3948  * @throws Exception If depth limit is reached.
  3608  *
  3949  *
  3609  * @param mixed $data  Variable (usually an array or object) to encode as JSON.
  3950  * @param mixed $data  Variable (usually an array or object) to encode as JSON.
  3610  * @param int   $depth Maximum depth to walk through $data. Must be greater than 0.
  3951  * @param int   $depth Maximum depth to walk through $data. Must be greater than 0.
  3611  * @return mixed The sanitized data that shall be encoded to JSON.
  3952  * @return mixed The sanitized data that shall be encoded to JSON.
  3612  */
  3953  */
  3667  * @since 4.1.0
  4008  * @since 4.1.0
  3668  * @access private
  4009  * @access private
  3669  *
  4010  *
  3670  * @see _wp_json_sanity_check()
  4011  * @see _wp_json_sanity_check()
  3671  *
  4012  *
  3672  * @staticvar bool $use_mb
       
  3673  *
       
  3674  * @param string $string The string which is to be converted.
  4013  * @param string $string The string which is to be converted.
  3675  * @return string The checked string.
  4014  * @return string The checked string.
  3676  */
  4015  */
  3677 function _wp_json_convert_string( $string ) {
  4016 function _wp_json_convert_string( $string ) {
  3678 	static $use_mb = null;
  4017 	static $use_mb = null;
  3697  *
  4036  *
  3698  * This supports the JsonSerializable interface for PHP 5.2-5.3 as well.
  4037  * This supports the JsonSerializable interface for PHP 5.2-5.3 as well.
  3699  *
  4038  *
  3700  * @ignore
  4039  * @ignore
  3701  * @since 4.4.0
  4040  * @since 4.4.0
       
  4041  * @deprecated 5.3.0 This function is no longer needed as support for PHP 5.2-5.3
       
  4042  *                   has been dropped.
  3702  * @access private
  4043  * @access private
  3703  *
  4044  *
  3704  * @param mixed $data Native representation.
  4045  * @param mixed $data Native representation.
  3705  * @return bool|int|float|null|string|array Data ready for `json_encode()`.
  4046  * @return bool|int|float|null|string|array Data ready for `json_encode()`.
  3706  */
  4047  */
  3707 function _wp_json_prepare_data( $data ) {
  4048 function _wp_json_prepare_data( $data ) {
  3708 	if ( ! defined( 'WP_JSON_SERIALIZE_COMPATIBLE' ) || WP_JSON_SERIALIZE_COMPATIBLE === false ) {
  4049 	_deprecated_function( __FUNCTION__, '5.3.0' );
  3709 		return $data;
  4050 	return $data;
  3710 	}
       
  3711 
       
  3712 	switch ( gettype( $data ) ) {
       
  3713 		case 'boolean':
       
  3714 		case 'integer':
       
  3715 		case 'double':
       
  3716 		case 'string':
       
  3717 		case 'NULL':
       
  3718 			// These values can be passed through.
       
  3719 			return $data;
       
  3720 
       
  3721 		case 'array':
       
  3722 			// Arrays must be mapped in case they also return objects.
       
  3723 			return array_map( '_wp_json_prepare_data', $data );
       
  3724 
       
  3725 		case 'object':
       
  3726 			// If this is an incomplete object (__PHP_Incomplete_Class), bail.
       
  3727 			if ( ! is_object( $data ) ) {
       
  3728 				return null;
       
  3729 			}
       
  3730 
       
  3731 			if ( $data instanceof JsonSerializable ) {
       
  3732 				$data = $data->jsonSerialize();
       
  3733 			} else {
       
  3734 				$data = get_object_vars( $data );
       
  3735 			}
       
  3736 
       
  3737 			// Now, pass the array (or whatever was returned from jsonSerialize through).
       
  3738 			return _wp_json_prepare_data( $data );
       
  3739 
       
  3740 		default:
       
  3741 			return null;
       
  3742 	}
       
  3743 }
  4051 }
  3744 
  4052 
  3745 /**
  4053 /**
  3746  * Send a JSON response back to an Ajax request.
  4054  * Send a JSON response back to an Ajax request.
  3747  *
  4055  *
  3751  * @param mixed $response    Variable (usually an array or object) to encode as JSON,
  4059  * @param mixed $response    Variable (usually an array or object) to encode as JSON,
  3752  *                           then print and die.
  4060  *                           then print and die.
  3753  * @param int   $status_code The HTTP status code to output.
  4061  * @param int   $status_code The HTTP status code to output.
  3754  */
  4062  */
  3755 function wp_send_json( $response, $status_code = null ) {
  4063 function wp_send_json( $response, $status_code = null ) {
  3756 	@header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
  4064 	if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
  3757 	if ( null !== $status_code ) {
  4065 		_doing_it_wrong(
  3758 		status_header( $status_code );
  4066 			__FUNCTION__,
  3759 	}
  4067 			sprintf(
       
  4068 				/* translators: 1: WP_REST_Response, 2: WP_Error */
       
  4069 				__( 'Return a %1$s or %2$s object from your callback when using the REST API.' ),
       
  4070 				'WP_REST_Response',
       
  4071 				'WP_Error'
       
  4072 			),
       
  4073 			'5.5.0'
       
  4074 		);
       
  4075 	}
       
  4076 
       
  4077 	if ( ! headers_sent() ) {
       
  4078 		header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
       
  4079 		if ( null !== $status_code ) {
       
  4080 			status_header( $status_code );
       
  4081 		}
       
  4082 	}
       
  4083 
  3760 	echo wp_json_encode( $response );
  4084 	echo wp_json_encode( $response );
  3761 
  4085 
  3762 	if ( wp_doing_ajax() ) {
  4086 	if ( wp_doing_ajax() ) {
  3763 		wp_die(
  4087 		wp_die(
  3764 			'',
  4088 			'',
  3829 
  4153 
  3830 	wp_send_json( $response, $status_code );
  4154 	wp_send_json( $response, $status_code );
  3831 }
  4155 }
  3832 
  4156 
  3833 /**
  4157 /**
  3834  * Checks that a JSONP callback is a valid JavaScript callback.
  4158  * Checks that a JSONP callback is a valid JavaScript callback name.
  3835  *
  4159  *
  3836  * Only allows alphanumeric characters and the dot character in callback
  4160  * Only allows alphanumeric characters and the dot character in callback
  3837  * function names. This helps to mitigate XSS attacks caused by directly
  4161  * function names. This helps to mitigate XSS attacks caused by directly
  3838  * outputting user input.
  4162  * outputting user input.
  3839  *
  4163  *
  3840  * @since 4.6.0
  4164  * @since 4.6.0
  3841  *
  4165  *
  3842  * @param string $callback Supplied JSONP callback function.
  4166  * @param string $callback Supplied JSONP callback function name.
  3843  * @return bool True if valid callback, otherwise false.
  4167  * @return bool Whether the callback function name is valid.
  3844  */
  4168  */
  3845 function wp_check_jsonp_callback( $callback ) {
  4169 function wp_check_jsonp_callback( $callback ) {
  3846 	if ( ! is_string( $callback ) ) {
  4170 	if ( ! is_string( $callback ) ) {
  3847 		return false;
  4171 		return false;
  3848 	}
  4172 	}
  3964  * @since 2.2.0
  4288  * @since 2.2.0
  3965  */
  4289  */
  3966 function smilies_init() {
  4290 function smilies_init() {
  3967 	global $wpsmiliestrans, $wp_smiliessearch;
  4291 	global $wpsmiliestrans, $wp_smiliessearch;
  3968 
  4292 
  3969 	// don't bother setting up smilies if they are disabled
  4293 	// Don't bother setting up smilies if they are disabled.
  3970 	if ( ! get_option( 'use_smilies' ) ) {
  4294 	if ( ! get_option( 'use_smilies' ) ) {
  3971 		return;
  4295 		return;
  3972 	}
  4296 	}
  3973 
  4297 
  3974 	if ( ! isset( $wpsmiliestrans ) ) {
  4298 	if ( ! isset( $wpsmiliestrans ) ) {
  4027 	 * This filter must be added before `smilies_init` is run, as
  4351 	 * This filter must be added before `smilies_init` is run, as
  4028 	 * it is normally only run once to setup the smilies regex.
  4352 	 * it is normally only run once to setup the smilies regex.
  4029 	 *
  4353 	 *
  4030 	 * @since 4.7.0
  4354 	 * @since 4.7.0
  4031 	 *
  4355 	 *
  4032 	 * @param array $wpsmiliestrans List of the smilies.
  4356 	 * @param string[] $wpsmiliestrans List of the smilies' hexadecimal representations, keyed by their smily code.
  4033 	 */
  4357 	 */
  4034 	$wpsmiliestrans = apply_filters( 'smilies', $wpsmiliestrans );
  4358 	$wpsmiliestrans = apply_filters( 'smilies', $wpsmiliestrans );
  4035 
  4359 
  4036 	if ( count( $wpsmiliestrans ) == 0 ) {
  4360 	if ( count( $wpsmiliestrans ) == 0 ) {
  4037 		return;
  4361 		return;
  4044 	 */
  4368 	 */
  4045 	krsort( $wpsmiliestrans );
  4369 	krsort( $wpsmiliestrans );
  4046 
  4370 
  4047 	$spaces = wp_spaces_regexp();
  4371 	$spaces = wp_spaces_regexp();
  4048 
  4372 
  4049 	// Begin first "subpattern"
  4373 	// Begin first "subpattern".
  4050 	$wp_smiliessearch = '/(?<=' . $spaces . '|^)';
  4374 	$wp_smiliessearch = '/(?<=' . $spaces . '|^)';
  4051 
  4375 
  4052 	$subchar = '';
  4376 	$subchar = '';
  4053 	foreach ( (array) $wpsmiliestrans as $smiley => $img ) {
  4377 	foreach ( (array) $wpsmiliestrans as $smiley => $img ) {
  4054 		$firstchar = substr( $smiley, 0, 1 );
  4378 		$firstchar = substr( $smiley, 0, 1 );
  4055 		$rest      = substr( $smiley, 1 );
  4379 		$rest      = substr( $smiley, 1 );
  4056 
  4380 
  4057 		// new subpattern?
  4381 		// New subpattern?
  4058 		if ( $firstchar != $subchar ) {
  4382 		if ( $firstchar != $subchar ) {
  4059 			if ( $subchar != '' ) {
  4383 			if ( '' !== $subchar ) {
  4060 				$wp_smiliessearch .= ')(?=' . $spaces . '|$)';  // End previous "subpattern"
  4384 				$wp_smiliessearch .= ')(?=' . $spaces . '|$)';  // End previous "subpattern".
  4061 				$wp_smiliessearch .= '|(?<=' . $spaces . '|^)'; // Begin another "subpattern"
  4385 				$wp_smiliessearch .= '|(?<=' . $spaces . '|^)'; // Begin another "subpattern".
  4062 			}
  4386 			}
  4063 			$subchar           = $firstchar;
  4387 			$subchar           = $firstchar;
  4064 			$wp_smiliessearch .= preg_quote( $firstchar, '/' ) . '(?:';
  4388 			$wp_smiliessearch .= preg_quote( $firstchar, '/' ) . '(?:';
  4065 		} else {
  4389 		} else {
  4066 			$wp_smiliessearch .= '|';
  4390 			$wp_smiliessearch .= '|';
  4080  *
  4404  *
  4081  * @since 2.2.0
  4405  * @since 2.2.0
  4082  * @since 2.3.0 `$args` can now also be an object.
  4406  * @since 2.3.0 `$args` can now also be an object.
  4083  *
  4407  *
  4084  * @param string|array|object $args     Value to merge with $defaults.
  4408  * @param string|array|object $args     Value to merge with $defaults.
  4085  * @param array               $defaults Optional. Array that serves as the defaults. Default empty.
  4409  * @param array               $defaults Optional. Array that serves as the defaults.
       
  4410  *                                      Default empty array.
  4086  * @return array Merged user defined values with defaults.
  4411  * @return array Merged user defined values with defaults.
  4087  */
  4412  */
  4088 function wp_parse_args( $args, $defaults = '' ) {
  4413 function wp_parse_args( $args, $defaults = array() ) {
  4089 	if ( is_object( $args ) ) {
  4414 	if ( is_object( $args ) ) {
  4090 		$r = get_object_vars( $args );
  4415 		$parsed_args = get_object_vars( $args );
  4091 	} elseif ( is_array( $args ) ) {
  4416 	} elseif ( is_array( $args ) ) {
  4092 		$r =& $args;
  4417 		$parsed_args =& $args;
  4093 	} else {
  4418 	} else {
  4094 		wp_parse_str( $args, $r );
  4419 		wp_parse_str( $args, $parsed_args );
  4095 	}
  4420 	}
  4096 
  4421 
  4097 	if ( is_array( $defaults ) ) {
  4422 	if ( is_array( $defaults ) && $defaults ) {
  4098 		return array_merge( $defaults, $r );
  4423 		return array_merge( $defaults, $parsed_args );
  4099 	}
  4424 	}
  4100 	return $r;
  4425 	return $parsed_args;
  4101 }
  4426 }
  4102 
  4427 
  4103 /**
  4428 /**
  4104  * Cleans up an array, comma- or space-separated list of scalar values.
  4429  * Cleans up an array, comma- or space-separated list of scalar values.
  4105  *
  4430  *
  4119 /**
  4444 /**
  4120  * Clean up an array, comma- or space-separated list of IDs.
  4445  * Clean up an array, comma- or space-separated list of IDs.
  4121  *
  4446  *
  4122  * @since 3.0.0
  4447  * @since 3.0.0
  4123  *
  4448  *
  4124  * @param array|string $list List of ids.
  4449  * @param array|string $list List of IDs.
  4125  * @return array Sanitized array of IDs.
  4450  * @return int[] Sanitized array of IDs.
  4126  */
  4451  */
  4127 function wp_parse_id_list( $list ) {
  4452 function wp_parse_id_list( $list ) {
  4128 	$list = wp_parse_list( $list );
  4453 	$list = wp_parse_list( $list );
  4129 
  4454 
  4130 	return array_unique( array_map( 'absint', $list ) );
  4455 	return array_unique( array_map( 'absint', $list ) );
  4133 /**
  4458 /**
  4134  * Clean up an array, comma- or space-separated list of slugs.
  4459  * Clean up an array, comma- or space-separated list of slugs.
  4135  *
  4460  *
  4136  * @since 4.7.0
  4461  * @since 4.7.0
  4137  *
  4462  *
  4138  * @param  array|string $list List of slugs.
  4463  * @param array|string $list List of slugs.
  4139  * @return array Sanitized array of slugs.
  4464  * @return string[] Sanitized array of slugs.
  4140  */
  4465  */
  4141 function wp_parse_slug_list( $list ) {
  4466 function wp_parse_slug_list( $list ) {
  4142 	$list = wp_parse_list( $list );
  4467 	$list = wp_parse_list( $list );
  4143 
  4468 
  4144 	return array_unique( array_map( 'sanitize_title', $list ) );
  4469 	return array_unique( array_map( 'sanitize_title', $list ) );
  4294  */
  4619  */
  4295 function wp_maybe_load_widgets() {
  4620 function wp_maybe_load_widgets() {
  4296 	/**
  4621 	/**
  4297 	 * Filters whether to load the Widgets library.
  4622 	 * Filters whether to load the Widgets library.
  4298 	 *
  4623 	 *
  4299 	 * Passing a falsey value to the filter will effectively short-circuit
  4624 	 * Returning a falsey value from the filter will effectively short-circuit
  4300 	 * the Widgets library from loading.
  4625 	 * the Widgets library from loading.
  4301 	 *
  4626 	 *
  4302 	 * @since 2.8.0
  4627 	 * @since 2.8.0
  4303 	 *
  4628 	 *
  4304 	 * @param bool $wp_maybe_load_widgets Whether to load the Widgets library.
  4629 	 * @param bool $wp_maybe_load_widgets Whether to load the Widgets library.
  4306 	 */
  4631 	 */
  4307 	if ( ! apply_filters( 'load_default_widgets', true ) ) {
  4632 	if ( ! apply_filters( 'load_default_widgets', true ) ) {
  4308 		return;
  4633 		return;
  4309 	}
  4634 	}
  4310 
  4635 
  4311 	require_once( ABSPATH . WPINC . '/default-widgets.php' );
  4636 	require_once ABSPATH . WPINC . '/default-widgets.php';
  4312 
  4637 
  4313 	add_action( '_admin_menu', 'wp_widgets_add_menu' );
  4638 	add_action( '_admin_menu', 'wp_widgets_add_menu' );
  4314 }
  4639 }
  4315 
  4640 
  4316 /**
  4641 /**
  4368 
  4693 
  4369 	wp_load_translations_early();
  4694 	wp_load_translations_early();
  4370 
  4695 
  4371 	// Load custom DB error template, if present.
  4696 	// Load custom DB error template, if present.
  4372 	if ( file_exists( WP_CONTENT_DIR . '/db-error.php' ) ) {
  4697 	if ( file_exists( WP_CONTENT_DIR . '/db-error.php' ) ) {
  4373 		require_once( WP_CONTENT_DIR . '/db-error.php' );
  4698 		require_once WP_CONTENT_DIR . '/db-error.php';
  4374 		die();
  4699 		die();
  4375 	}
  4700 	}
  4376 
  4701 
  4377 	// If installing or in the admin, provide the verbose message.
  4702 	// If installing or in the admin, provide the verbose message.
  4378 	if ( wp_installing() || defined( 'WP_ADMIN' ) ) {
  4703 	if ( wp_installing() || defined( 'WP_ADMIN' ) ) {
  4405  * The current behavior is to trigger a user error if `WP_DEBUG` is true.
  4730  * The current behavior is to trigger a user error if `WP_DEBUG` is true.
  4406  *
  4731  *
  4407  * This function is to be used in every function that is deprecated.
  4732  * This function is to be used in every function that is deprecated.
  4408  *
  4733  *
  4409  * @since 2.5.0
  4734  * @since 2.5.0
  4410  * @access private
  4735  * @since 5.4.0 This function is no longer marked as "private".
       
  4736  * @since 5.4.0 The error type is now classified as E_USER_DEPRECATED (used to default to E_USER_NOTICE).
  4411  *
  4737  *
  4412  * @param string $function    The function that was called.
  4738  * @param string $function    The function that was called.
  4413  * @param string $version     The version of WordPress that deprecated the function.
  4739  * @param string $version     The version of WordPress that deprecated the function.
  4414  * @param string $replacement Optional. The function that should have been called. Default null.
  4740  * @param string $replacement Optional. The function that should have been called. Default empty.
  4415  */
  4741  */
  4416 function _deprecated_function( $function, $version, $replacement = null ) {
  4742 function _deprecated_function( $function, $version, $replacement = '' ) {
  4417 
  4743 
  4418 	/**
  4744 	/**
  4419 	 * Fires when a deprecated function is called.
  4745 	 * Fires when a deprecated function is called.
  4420 	 *
  4746 	 *
  4421 	 * @since 2.5.0
  4747 	 * @since 2.5.0
  4433 	 *
  4759 	 *
  4434 	 * @param bool $trigger Whether to trigger the error for deprecated functions. Default true.
  4760 	 * @param bool $trigger Whether to trigger the error for deprecated functions. Default true.
  4435 	 */
  4761 	 */
  4436 	if ( WP_DEBUG && apply_filters( 'deprecated_function_trigger_error', true ) ) {
  4762 	if ( WP_DEBUG && apply_filters( 'deprecated_function_trigger_error', true ) ) {
  4437 		if ( function_exists( '__' ) ) {
  4763 		if ( function_exists( '__' ) ) {
  4438 			if ( ! is_null( $replacement ) ) {
  4764 			if ( $replacement ) {
  4439 				/* translators: 1: PHP function name, 2: version number, 3: alternative function name */
  4765 				trigger_error(
  4440 				trigger_error( sprintf( __( '%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ), $function, $version, $replacement ) );
  4766 					sprintf(
       
  4767 						/* translators: 1: PHP function name, 2: Version number, 3: Alternative function name. */
       
  4768 						__( '%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ),
       
  4769 						$function,
       
  4770 						$version,
       
  4771 						$replacement
       
  4772 					),
       
  4773 					E_USER_DEPRECATED
       
  4774 				);
  4441 			} else {
  4775 			} else {
  4442 				/* translators: 1: PHP function name, 2: version number */
  4776 				trigger_error(
  4443 				trigger_error( sprintf( __( '%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.' ), $function, $version ) );
  4777 					sprintf(
       
  4778 						/* translators: 1: PHP function name, 2: Version number. */
       
  4779 						__( '%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.' ),
       
  4780 						$function,
       
  4781 						$version
       
  4782 					),
       
  4783 					E_USER_DEPRECATED
       
  4784 				);
  4444 			}
  4785 			}
  4445 		} else {
  4786 		} else {
  4446 			if ( ! is_null( $replacement ) ) {
  4787 			if ( $replacement ) {
  4447 				trigger_error( sprintf( '%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.', $function, $version, $replacement ) );
  4788 				trigger_error(
       
  4789 					sprintf(
       
  4790 						'%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.',
       
  4791 						$function,
       
  4792 						$version,
       
  4793 						$replacement
       
  4794 					),
       
  4795 					E_USER_DEPRECATED
       
  4796 				);
  4448 			} else {
  4797 			} else {
  4449 				trigger_error( sprintf( '%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.', $function, $version ) );
  4798 				trigger_error(
       
  4799 					sprintf(
       
  4800 						'%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.',
       
  4801 						$function,
       
  4802 						$version
       
  4803 					),
       
  4804 					E_USER_DEPRECATED
       
  4805 				);
  4450 			}
  4806 			}
  4451 		}
  4807 		}
  4452 	}
  4808 	}
  4453 }
  4809 }
  4454 
  4810 
  4462  *
  4818  *
  4463  * This function is to be used in every PHP4 style constructor method that is deprecated.
  4819  * This function is to be used in every PHP4 style constructor method that is deprecated.
  4464  *
  4820  *
  4465  * @since 4.3.0
  4821  * @since 4.3.0
  4466  * @since 4.5.0 Added the `$parent_class` parameter.
  4822  * @since 4.5.0 Added the `$parent_class` parameter.
  4467  *
  4823  * @since 5.4.0 This function is no longer marked as "private".
  4468  * @access private
  4824  * @since 5.4.0 The error type is now classified as E_USER_DEPRECATED (used to default to E_USER_NOTICE).
  4469  *
  4825  *
  4470  * @param string $class        The class containing the deprecated constructor.
  4826  * @param string $class        The class containing the deprecated constructor.
  4471  * @param string $version      The version of WordPress that deprecated the function.
  4827  * @param string $version      The version of WordPress that deprecated the function.
  4472  * @param string $parent_class Optional. The parent class calling the deprecated constructor.
  4828  * @param string $parent_class Optional. The parent class calling the deprecated constructor.
  4473  *                             Default empty string.
  4829  *                             Default empty string.
  4495 	 *
  4851 	 *
  4496 	 * @param bool $trigger Whether to trigger the error for deprecated functions. Default true.
  4852 	 * @param bool $trigger Whether to trigger the error for deprecated functions. Default true.
  4497 	 */
  4853 	 */
  4498 	if ( WP_DEBUG && apply_filters( 'deprecated_constructor_trigger_error', true ) ) {
  4854 	if ( WP_DEBUG && apply_filters( 'deprecated_constructor_trigger_error', true ) ) {
  4499 		if ( function_exists( '__' ) ) {
  4855 		if ( function_exists( '__' ) ) {
  4500 			if ( ! empty( $parent_class ) ) {
  4856 			if ( $parent_class ) {
  4501 				/* translators: 1: PHP class name, 2: PHP parent class name, 3: version number, 4: __construct() method */
       
  4502 				trigger_error(
  4857 				trigger_error(
  4503 					sprintf(
  4858 					sprintf(
       
  4859 						/* translators: 1: PHP class name, 2: PHP parent class name, 3: Version number, 4: __construct() method. */
  4504 						__( 'The called constructor method for %1$s in %2$s is <strong>deprecated</strong> since version %3$s! Use %4$s instead.' ),
  4860 						__( 'The called constructor method for %1$s in %2$s is <strong>deprecated</strong> since version %3$s! Use %4$s instead.' ),
  4505 						$class,
  4861 						$class,
  4506 						$parent_class,
  4862 						$parent_class,
  4507 						$version,
  4863 						$version,
  4508 						'<pre>__construct()</pre>'
  4864 						'<code>__construct()</code>'
  4509 					)
  4865 					),
       
  4866 					E_USER_DEPRECATED
  4510 				);
  4867 				);
  4511 			} else {
  4868 			} else {
  4512 				/* translators: 1: PHP class name, 2: version number, 3: __construct() method */
       
  4513 				trigger_error(
  4869 				trigger_error(
  4514 					sprintf(
  4870 					sprintf(
       
  4871 						/* translators: 1: PHP class name, 2: Version number, 3: __construct() method. */
  4515 						__( 'The called constructor method for %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ),
  4872 						__( 'The called constructor method for %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ),
  4516 						$class,
  4873 						$class,
  4517 						$version,
  4874 						$version,
  4518 						'<pre>__construct()</pre>'
  4875 						'<code>__construct()</code>'
  4519 					)
  4876 					),
       
  4877 					E_USER_DEPRECATED
  4520 				);
  4878 				);
  4521 			}
  4879 			}
  4522 		} else {
  4880 		} else {
  4523 			if ( ! empty( $parent_class ) ) {
  4881 			if ( $parent_class ) {
  4524 				trigger_error(
  4882 				trigger_error(
  4525 					sprintf(
  4883 					sprintf(
  4526 						'The called constructor method for %1$s in %2$s is <strong>deprecated</strong> since version %3$s! Use %4$s instead.',
  4884 						'The called constructor method for %1$s in %2$s is <strong>deprecated</strong> since version %3$s! Use %4$s instead.',
  4527 						$class,
  4885 						$class,
  4528 						$parent_class,
  4886 						$parent_class,
  4529 						$version,
  4887 						$version,
  4530 						'<pre>__construct()</pre>'
  4888 						'<code>__construct()</code>'
  4531 					)
  4889 					),
       
  4890 					E_USER_DEPRECATED
  4532 				);
  4891 				);
  4533 			} else {
  4892 			} else {
  4534 				trigger_error(
  4893 				trigger_error(
  4535 					sprintf(
  4894 					sprintf(
  4536 						'The called constructor method for %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.',
  4895 						'The called constructor method for %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.',
  4537 						$class,
  4896 						$class,
  4538 						$version,
  4897 						$version,
  4539 						'<pre>__construct()</pre>'
  4898 						'<code>__construct()</code>'
  4540 					)
  4899 					),
       
  4900 					E_USER_DEPRECATED
  4541 				);
  4901 				);
  4542 			}
  4902 			}
  4543 		}
  4903 		}
  4544 	}
  4904 	}
  4545 
  4905 
  4555  * The current behavior is to trigger a user error if `WP_DEBUG` is true.
  4915  * The current behavior is to trigger a user error if `WP_DEBUG` is true.
  4556  *
  4916  *
  4557  * This function is to be used in every file that is deprecated.
  4917  * This function is to be used in every file that is deprecated.
  4558  *
  4918  *
  4559  * @since 2.5.0
  4919  * @since 2.5.0
  4560  * @access private
  4920  * @since 5.4.0 This function is no longer marked as "private".
       
  4921  * @since 5.4.0 The error type is now classified as E_USER_DEPRECATED (used to default to E_USER_NOTICE).
  4561  *
  4922  *
  4562  * @param string $file        The file that was included.
  4923  * @param string $file        The file that was included.
  4563  * @param string $version     The version of WordPress that deprecated the file.
  4924  * @param string $version     The version of WordPress that deprecated the file.
  4564  * @param string $replacement Optional. The file that should have been included based on ABSPATH.
  4925  * @param string $replacement Optional. The file that should have been included based on ABSPATH.
  4565  *                            Default null.
  4926  *                            Default empty.
  4566  * @param string $message     Optional. A message regarding the change. Default empty.
  4927  * @param string $message     Optional. A message regarding the change. Default empty.
  4567  */
  4928  */
  4568 function _deprecated_file( $file, $version, $replacement = null, $message = '' ) {
  4929 function _deprecated_file( $file, $version, $replacement = '', $message = '' ) {
  4569 
  4930 
  4570 	/**
  4931 	/**
  4571 	 * Fires when a deprecated file is called.
  4932 	 * Fires when a deprecated file is called.
  4572 	 *
  4933 	 *
  4573 	 * @since 2.5.0
  4934 	 * @since 2.5.0
  4586 	 *
  4947 	 *
  4587 	 * @param bool $trigger Whether to trigger the error for deprecated files. Default true.
  4948 	 * @param bool $trigger Whether to trigger the error for deprecated files. Default true.
  4588 	 */
  4949 	 */
  4589 	if ( WP_DEBUG && apply_filters( 'deprecated_file_trigger_error', true ) ) {
  4950 	if ( WP_DEBUG && apply_filters( 'deprecated_file_trigger_error', true ) ) {
  4590 		$message = empty( $message ) ? '' : ' ' . $message;
  4951 		$message = empty( $message ) ? '' : ' ' . $message;
       
  4952 
  4591 		if ( function_exists( '__' ) ) {
  4953 		if ( function_exists( '__' ) ) {
  4592 			if ( ! is_null( $replacement ) ) {
  4954 			if ( $replacement ) {
  4593 				/* translators: 1: PHP file name, 2: version number, 3: alternative file name */
  4955 				trigger_error(
  4594 				trigger_error( sprintf( __( '%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ), $file, $version, $replacement ) . $message );
  4956 					sprintf(
       
  4957 						/* translators: 1: PHP file name, 2: Version number, 3: Alternative file name. */
       
  4958 						__( '%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ),
       
  4959 						$file,
       
  4960 						$version,
       
  4961 						$replacement
       
  4962 					) . $message,
       
  4963 					E_USER_DEPRECATED
       
  4964 				);
  4595 			} else {
  4965 			} else {
  4596 				/* translators: 1: PHP file name, 2: version number */
  4966 				trigger_error(
  4597 				trigger_error( sprintf( __( '%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.' ), $file, $version ) . $message );
  4967 					sprintf(
       
  4968 						/* translators: 1: PHP file name, 2: Version number. */
       
  4969 						__( '%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.' ),
       
  4970 						$file,
       
  4971 						$version
       
  4972 					) . $message,
       
  4973 					E_USER_DEPRECATED
       
  4974 				);
  4598 			}
  4975 			}
  4599 		} else {
  4976 		} else {
  4600 			if ( ! is_null( $replacement ) ) {
  4977 			if ( $replacement ) {
  4601 				trigger_error( sprintf( '%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.', $file, $version, $replacement ) . $message );
  4978 				trigger_error(
       
  4979 					sprintf(
       
  4980 						'%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.',
       
  4981 						$file,
       
  4982 						$version,
       
  4983 						$replacement
       
  4984 					) . $message,
       
  4985 					E_USER_DEPRECATED
       
  4986 				);
  4602 			} else {
  4987 			} else {
  4603 				trigger_error( sprintf( '%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.', $file, $version ) . $message );
  4988 				trigger_error(
       
  4989 					sprintf(
       
  4990 						'%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.',
       
  4991 						$file,
       
  4992 						$version
       
  4993 					) . $message,
       
  4994 					E_USER_DEPRECATED
       
  4995 				);
  4604 			}
  4996 			}
  4605 		}
  4997 		}
  4606 	}
  4998 	}
  4607 }
  4999 }
  4608 /**
  5000 /**
  4622  * argument.
  5014  * argument.
  4623  *
  5015  *
  4624  * The current behavior is to trigger a user error if WP_DEBUG is true.
  5016  * The current behavior is to trigger a user error if WP_DEBUG is true.
  4625  *
  5017  *
  4626  * @since 3.0.0
  5018  * @since 3.0.0
  4627  * @access private
  5019  * @since 5.4.0 This function is no longer marked as "private".
       
  5020  * @since 5.4.0 The error type is now classified as E_USER_DEPRECATED (used to default to E_USER_NOTICE).
  4628  *
  5021  *
  4629  * @param string $function The function that was called.
  5022  * @param string $function The function that was called.
  4630  * @param string $version  The version of WordPress that deprecated the argument used.
  5023  * @param string $version  The version of WordPress that deprecated the argument used.
  4631  * @param string $message  Optional. A message regarding the change. Default null.
  5024  * @param string $message  Optional. A message regarding the change. Default empty.
  4632  */
  5025  */
  4633 function _deprecated_argument( $function, $version, $message = null ) {
  5026 function _deprecated_argument( $function, $version, $message = '' ) {
  4634 
  5027 
  4635 	/**
  5028 	/**
  4636 	 * Fires when a deprecated argument is called.
  5029 	 * Fires when a deprecated argument is called.
  4637 	 *
  5030 	 *
  4638 	 * @since 3.0.0
  5031 	 * @since 3.0.0
  4650 	 *
  5043 	 *
  4651 	 * @param bool $trigger Whether to trigger the error for deprecated arguments. Default true.
  5044 	 * @param bool $trigger Whether to trigger the error for deprecated arguments. Default true.
  4652 	 */
  5045 	 */
  4653 	if ( WP_DEBUG && apply_filters( 'deprecated_argument_trigger_error', true ) ) {
  5046 	if ( WP_DEBUG && apply_filters( 'deprecated_argument_trigger_error', true ) ) {
  4654 		if ( function_exists( '__' ) ) {
  5047 		if ( function_exists( '__' ) ) {
  4655 			if ( ! is_null( $message ) ) {
  5048 			if ( $message ) {
  4656 				/* translators: 1: PHP function name, 2: version number, 3: optional message regarding the change */
  5049 				trigger_error(
  4657 				trigger_error( sprintf( __( '%1$s was called with an argument that is <strong>deprecated</strong> since version %2$s! %3$s' ), $function, $version, $message ) );
  5050 					sprintf(
       
  5051 						/* translators: 1: PHP function name, 2: Version number, 3: Optional message regarding the change. */
       
  5052 						__( '%1$s was called with an argument that is <strong>deprecated</strong> since version %2$s! %3$s' ),
       
  5053 						$function,
       
  5054 						$version,
       
  5055 						$message
       
  5056 					),
       
  5057 					E_USER_DEPRECATED
       
  5058 				);
  4658 			} else {
  5059 			} else {
  4659 				/* translators: 1: PHP function name, 2: version number */
  5060 				trigger_error(
  4660 				trigger_error( sprintf( __( '%1$s was called with an argument that is <strong>deprecated</strong> since version %2$s with no alternative available.' ), $function, $version ) );
  5061 					sprintf(
       
  5062 						/* translators: 1: PHP function name, 2: Version number. */
       
  5063 						__( '%1$s was called with an argument that is <strong>deprecated</strong> since version %2$s with no alternative available.' ),
       
  5064 						$function,
       
  5065 						$version
       
  5066 					),
       
  5067 					E_USER_DEPRECATED
       
  5068 				);
  4661 			}
  5069 			}
  4662 		} else {
  5070 		} else {
  4663 			if ( ! is_null( $message ) ) {
  5071 			if ( $message ) {
  4664 				trigger_error( sprintf( '%1$s was called with an argument that is <strong>deprecated</strong> since version %2$s! %3$s', $function, $version, $message ) );
  5072 				trigger_error(
       
  5073 					sprintf(
       
  5074 						'%1$s was called with an argument that is <strong>deprecated</strong> since version %2$s! %3$s',
       
  5075 						$function,
       
  5076 						$version,
       
  5077 						$message
       
  5078 					),
       
  5079 					E_USER_DEPRECATED
       
  5080 				);
  4665 			} else {
  5081 			} else {
  4666 				trigger_error( sprintf( '%1$s was called with an argument that is <strong>deprecated</strong> since version %2$s with no alternative available.', $function, $version ) );
  5082 				trigger_error(
       
  5083 					sprintf(
       
  5084 						'%1$s was called with an argument that is <strong>deprecated</strong> since version %2$s with no alternative available.',
       
  5085 						$function,
       
  5086 						$version
       
  5087 					),
       
  5088 					E_USER_DEPRECATED
       
  5089 				);
  4667 			}
  5090 			}
  4668 		}
  5091 		}
  4669 	}
  5092 	}
  4670 }
  5093 }
  4671 
  5094 
  4679  *
  5102  *
  4680  * This function is called by the do_action_deprecated() and apply_filters_deprecated()
  5103  * This function is called by the do_action_deprecated() and apply_filters_deprecated()
  4681  * functions, and so generally does not need to be called directly.
  5104  * functions, and so generally does not need to be called directly.
  4682  *
  5105  *
  4683  * @since 4.6.0
  5106  * @since 4.6.0
       
  5107  * @since 5.4.0 The error type is now classified as E_USER_DEPRECATED (used to default to E_USER_NOTICE).
  4684  * @access private
  5108  * @access private
  4685  *
  5109  *
  4686  * @param string $hook        The hook that was used.
  5110  * @param string $hook        The hook that was used.
  4687  * @param string $version     The version of WordPress that deprecated the hook.
  5111  * @param string $version     The version of WordPress that deprecated the hook.
  4688  * @param string $replacement Optional. The hook that should have been used.
  5112  * @param string $replacement Optional. The hook that should have been used. Default empty.
  4689  * @param string $message     Optional. A message regarding the change.
  5113  * @param string $message     Optional. A message regarding the change. Default empty.
  4690  */
  5114  */
  4691 function _deprecated_hook( $hook, $version, $replacement = null, $message = null ) {
  5115 function _deprecated_hook( $hook, $version, $replacement = '', $message = '' ) {
  4692 	/**
  5116 	/**
  4693 	 * Fires when a deprecated hook is called.
  5117 	 * Fires when a deprecated hook is called.
  4694 	 *
  5118 	 *
  4695 	 * @since 4.6.0
  5119 	 * @since 4.6.0
  4696 	 *
  5120 	 *
  4709 	 * @param bool $trigger Whether to trigger deprecated hook errors. Requires
  5133 	 * @param bool $trigger Whether to trigger deprecated hook errors. Requires
  4710 	 *                      `WP_DEBUG` to be defined true.
  5134 	 *                      `WP_DEBUG` to be defined true.
  4711 	 */
  5135 	 */
  4712 	if ( WP_DEBUG && apply_filters( 'deprecated_hook_trigger_error', true ) ) {
  5136 	if ( WP_DEBUG && apply_filters( 'deprecated_hook_trigger_error', true ) ) {
  4713 		$message = empty( $message ) ? '' : ' ' . $message;
  5137 		$message = empty( $message ) ? '' : ' ' . $message;
  4714 		if ( ! is_null( $replacement ) ) {
  5138 
  4715 			/* translators: 1: WordPress hook name, 2: version number, 3: alternative hook name */
  5139 		if ( $replacement ) {
  4716 			trigger_error( sprintf( __( '%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ), $hook, $version, $replacement ) . $message );
  5140 			trigger_error(
       
  5141 				sprintf(
       
  5142 					/* translators: 1: WordPress hook name, 2: Version number, 3: Alternative hook name. */
       
  5143 					__( '%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ),
       
  5144 					$hook,
       
  5145 					$version,
       
  5146 					$replacement
       
  5147 				) . $message,
       
  5148 				E_USER_DEPRECATED
       
  5149 			);
  4717 		} else {
  5150 		} else {
  4718 			/* translators: 1: WordPress hook name, 2: version number */
  5151 			trigger_error(
  4719 			trigger_error( sprintf( __( '%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.' ), $hook, $version ) . $message );
  5152 				sprintf(
       
  5153 					/* translators: 1: WordPress hook name, 2: Version number. */
       
  5154 					__( '%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.' ),
       
  5155 					$hook,
       
  5156 					$version
       
  5157 				) . $message,
       
  5158 				E_USER_DEPRECATED
       
  5159 			);
  4720 		}
  5160 		}
  4721 	}
  5161 	}
  4722 }
  5162 }
  4723 
  5163 
  4724 /**
  5164 /**
  4729  * function.
  5169  * function.
  4730  *
  5170  *
  4731  * The current behavior is to trigger a user error if `WP_DEBUG` is true.
  5171  * The current behavior is to trigger a user error if `WP_DEBUG` is true.
  4732  *
  5172  *
  4733  * @since 3.1.0
  5173  * @since 3.1.0
  4734  * @access private
  5174  * @since 5.4.0 This function is no longer marked as "private".
  4735  *
  5175  *
  4736  * @param string $function The function that was called.
  5176  * @param string $function The function that was called.
  4737  * @param string $message  A message explaining what has been done incorrectly.
  5177  * @param string $message  A message explaining what has been done incorrectly.
  4738  * @param string $version  The version of WordPress where the message was added.
  5178  * @param string $version  The version of WordPress where the message was added.
  4739  */
  5179  */
  4761 	 * @param string $message  A message explaining what has been done incorrectly.
  5201 	 * @param string $message  A message explaining what has been done incorrectly.
  4762 	 * @param string $version  The version of WordPress where the message was added.
  5202 	 * @param string $version  The version of WordPress where the message was added.
  4763 	 */
  5203 	 */
  4764 	if ( WP_DEBUG && apply_filters( 'doing_it_wrong_trigger_error', true, $function, $message, $version ) ) {
  5204 	if ( WP_DEBUG && apply_filters( 'doing_it_wrong_trigger_error', true, $function, $message, $version ) ) {
  4765 		if ( function_exists( '__' ) ) {
  5205 		if ( function_exists( '__' ) ) {
  4766 			if ( is_null( $version ) ) {
  5206 			if ( $version ) {
  4767 				$version = '';
  5207 				/* translators: %s: Version number. */
  4768 			} else {
       
  4769 				/* translators: %s: version number */
       
  4770 				$version = sprintf( __( '(This message was added in version %s.)' ), $version );
  5208 				$version = sprintf( __( '(This message was added in version %s.)' ), $version );
  4771 			}
  5209 			}
  4772 			/* translators: %s: Codex URL */
  5210 
  4773 			$message .= ' ' . sprintf(
  5211 			$message .= ' ' . sprintf(
       
  5212 				/* translators: %s: Documentation URL. */
  4774 				__( 'Please see <a href="%s">Debugging in WordPress</a> for more information.' ),
  5213 				__( 'Please see <a href="%s">Debugging in WordPress</a> for more information.' ),
  4775 				__( 'https://codex.wordpress.org/Debugging_in_WordPress' )
  5214 				__( 'https://wordpress.org/support/article/debugging-in-wordpress/' )
  4776 			);
  5215 			);
  4777 			/* translators: Developer debugging message. 1: PHP function name, 2: Explanatory message, 3: Version information message */
  5216 
  4778 			trigger_error( sprintf( __( '%1$s was called <strong>incorrectly</strong>. %2$s %3$s' ), $function, $message, $version ) );
  5217 			trigger_error(
       
  5218 				sprintf(
       
  5219 					/* translators: Developer debugging message. 1: PHP function name, 2: Explanatory message, 3: WordPress version number. */
       
  5220 					__( '%1$s was called <strong>incorrectly</strong>. %2$s %3$s' ),
       
  5221 					$function,
       
  5222 					$message,
       
  5223 					$version
       
  5224 				),
       
  5225 				E_USER_NOTICE
       
  5226 			);
  4779 		} else {
  5227 		} else {
  4780 			if ( is_null( $version ) ) {
  5228 			if ( $version ) {
  4781 				$version = '';
       
  4782 			} else {
       
  4783 				$version = sprintf( '(This message was added in version %s.)', $version );
  5229 				$version = sprintf( '(This message was added in version %s.)', $version );
  4784 			}
  5230 			}
       
  5231 
  4785 			$message .= sprintf(
  5232 			$message .= sprintf(
  4786 				' Please see <a href="%s">Debugging in WordPress</a> for more information.',
  5233 				' Please see <a href="%s">Debugging in WordPress</a> for more information.',
  4787 				'https://codex.wordpress.org/Debugging_in_WordPress'
  5234 				'https://wordpress.org/support/article/debugging-in-wordpress/'
  4788 			);
  5235 			);
  4789 			trigger_error( sprintf( '%1$s was called <strong>incorrectly</strong>. %2$s %3$s', $function, $message, $version ) );
  5236 
       
  5237 			trigger_error(
       
  5238 				sprintf(
       
  5239 					'%1$s was called <strong>incorrectly</strong>. %2$s %3$s',
       
  5240 					$function,
       
  5241 					$message,
       
  5242 					$version
       
  5243 				),
       
  5244 				E_USER_NOTICE
       
  5245 			);
  4790 		}
  5246 		}
  4791 	}
  5247 	}
  4792 }
  5248 }
  4793 
  5249 
  4794 /**
  5250 /**
  4799  * @return bool Whether the server is running lighttpd < 1.5.0.
  5255  * @return bool Whether the server is running lighttpd < 1.5.0.
  4800  */
  5256  */
  4801 function is_lighttpd_before_150() {
  5257 function is_lighttpd_before_150() {
  4802 	$server_parts    = explode( '/', isset( $_SERVER['SERVER_SOFTWARE'] ) ? $_SERVER['SERVER_SOFTWARE'] : '' );
  5258 	$server_parts    = explode( '/', isset( $_SERVER['SERVER_SOFTWARE'] ) ? $_SERVER['SERVER_SOFTWARE'] : '' );
  4803 	$server_parts[1] = isset( $server_parts[1] ) ? $server_parts[1] : '';
  5259 	$server_parts[1] = isset( $server_parts[1] ) ? $server_parts[1] : '';
  4804 	return  'lighttpd' == $server_parts[0] && -1 == version_compare( $server_parts[1], '1.5.0' );
  5260 
       
  5261 	return ( 'lighttpd' === $server_parts[0] && -1 == version_compare( $server_parts[1], '1.5.0' ) );
  4805 }
  5262 }
  4806 
  5263 
  4807 /**
  5264 /**
  4808  * Does the specified module exist in the Apache config?
  5265  * Does the specified module exist in the Apache config?
  4809  *
  5266  *
  4822 		return false;
  5279 		return false;
  4823 	}
  5280 	}
  4824 
  5281 
  4825 	if ( function_exists( 'apache_get_modules' ) ) {
  5282 	if ( function_exists( 'apache_get_modules' ) ) {
  4826 		$mods = apache_get_modules();
  5283 		$mods = apache_get_modules();
  4827 		if ( in_array( $mod, $mods ) ) {
  5284 		if ( in_array( $mod, $mods, true ) ) {
  4828 			return true;
  5285 			return true;
  4829 		}
  5286 		}
  4830 	} elseif ( function_exists( 'phpinfo' ) && false === strpos( ini_get( 'disable_functions' ), 'phpinfo' ) ) {
  5287 	} elseif ( function_exists( 'phpinfo' ) && false === strpos( ini_get( 'disable_functions' ), 'phpinfo' ) ) {
  4831 			ob_start();
  5288 			ob_start();
  4832 			phpinfo( 8 );
  5289 			phpinfo( 8 );
  4833 			$phpinfo = ob_get_clean();
  5290 			$phpinfo = ob_get_clean();
  4834 		if ( false !== strpos( $phpinfo, $mod ) ) {
  5291 		if ( false !== strpos( $phpinfo, $mod ) ) {
  4835 			return true;
  5292 			return true;
  4836 		}
  5293 		}
  4837 	}
  5294 	}
       
  5295 
  4838 	return $default;
  5296 	return $default;
  4839 }
  5297 }
  4840 
  5298 
  4841 /**
  5299 /**
  4842  * Check if IIS 7+ supports pretty permalinks.
  5300  * Check if IIS 7+ supports pretty permalinks.
  4859 		 * Next we check if the URL Rewrite Module 1.1 is loaded and enabled for the web site. When
  5317 		 * Next we check if the URL Rewrite Module 1.1 is loaded and enabled for the web site. When
  4860 		 * URL Rewrite 1.1 is loaded it always sets a server variable called 'IIS_UrlRewriteModule'.
  5318 		 * URL Rewrite 1.1 is loaded it always sets a server variable called 'IIS_UrlRewriteModule'.
  4861 		 * Lastly we make sure that PHP is running via FastCGI. This is important because if it runs
  5319 		 * Lastly we make sure that PHP is running via FastCGI. This is important because if it runs
  4862 		 * via ISAPI then pretty permalinks will not work.
  5320 		 * via ISAPI then pretty permalinks will not work.
  4863 		 */
  5321 		 */
  4864 		$supports_permalinks = class_exists( 'DOMDocument', false ) && isset( $_SERVER['IIS_UrlRewriteModule'] ) && ( PHP_SAPI == 'cgi-fcgi' );
  5322 		$supports_permalinks = class_exists( 'DOMDocument', false ) && isset( $_SERVER['IIS_UrlRewriteModule'] ) && ( 'cgi-fcgi' === PHP_SAPI );
  4865 	}
  5323 	}
  4866 
  5324 
  4867 	/**
  5325 	/**
  4868 	 * Filters whether IIS 7+ supports pretty permalinks.
  5326 	 * Filters whether IIS 7+ supports pretty permalinks.
  4869 	 *
  5327 	 *
  4883  *
  5341  *
  4884  * A return value of `3` means the file is not in the allowed files list.
  5342  * A return value of `3` means the file is not in the allowed files list.
  4885  *
  5343  *
  4886  * @since 1.2.0
  5344  * @since 1.2.0
  4887  *
  5345  *
  4888  * @param string $file          File path.
  5346  * @param string   $file          File path.
  4889  * @param array  $allowed_files Optional. List of allowed files.
  5347  * @param string[] $allowed_files Optional. Array of allowed files.
  4890  * @return int 0 means nothing is wrong, greater than 0 means something was wrong.
  5348  * @return int 0 means nothing is wrong, greater than 0 means something was wrong.
  4891  */
  5349  */
  4892 function validate_file( $file, $allowed_files = array() ) {
  5350 function validate_file( $file, $allowed_files = array() ) {
  4893 	// `../` on its own is not allowed:
  5351 	// `../` on its own is not allowed:
  4894 	if ( '../' === $file ) {
  5352 	if ( '../' === $file ) {
  4904 	if ( false !== strpos( $file, '../' ) && '../' !== mb_substr( $file, -3, 3 ) ) {
  5362 	if ( false !== strpos( $file, '../' ) && '../' !== mb_substr( $file, -3, 3 ) ) {
  4905 		return 1;
  5363 		return 1;
  4906 	}
  5364 	}
  4907 
  5365 
  4908 	// Files not in the allowed file list are not allowed:
  5366 	// Files not in the allowed file list are not allowed:
  4909 	if ( ! empty( $allowed_files ) && ! in_array( $file, $allowed_files ) ) {
  5367 	if ( ! empty( $allowed_files ) && ! in_array( $file, $allowed_files, true ) ) {
  4910 		return 3;
  5368 		return 3;
  4911 	}
  5369 	}
  4912 
  5370 
  4913 	// Absolute Windows drive paths are not allowed:
  5371 	// Absolute Windows drive paths are not allowed:
  4914 	if ( ':' == substr( $file, 1, 1 ) ) {
  5372 	if ( ':' === substr( $file, 1, 1 ) ) {
  4915 		return 2;
  5373 		return 2;
  4916 	}
  5374 	}
  4917 
  5375 
  4918 	return 0;
  5376 	return 0;
  4919 }
  5377 }
  4920 
  5378 
  4921 /**
  5379 /**
  4922  * Whether to force SSL used for the Administration Screens.
  5380  * Whether to force SSL used for the Administration Screens.
  4923  *
  5381  *
  4924  * @since 2.6.0
  5382  * @since 2.6.0
  4925  *
       
  4926  * @staticvar bool $forced
       
  4927  *
  5383  *
  4928  * @param string|bool $force Optional. Whether to force SSL in admin screens. Default null.
  5384  * @param string|bool $force Optional. Whether to force SSL in admin screens. Default null.
  4929  * @return bool True if forced, false if not forced.
  5385  * @return bool True if forced, false if not forced.
  4930  */
  5386  */
  4931 function force_ssl_admin( $force = null ) {
  5387 function force_ssl_admin( $force = null ) {
  4949  * @since 2.6.0
  5405  * @since 2.6.0
  4950  *
  5406  *
  4951  * @return string The guessed URL.
  5407  * @return string The guessed URL.
  4952  */
  5408  */
  4953 function wp_guess_url() {
  5409 function wp_guess_url() {
  4954 	if ( defined( 'WP_SITEURL' ) && '' != WP_SITEURL ) {
  5410 	if ( defined( 'WP_SITEURL' ) && '' !== WP_SITEURL ) {
  4955 		$url = WP_SITEURL;
  5411 		$url = WP_SITEURL;
  4956 	} else {
  5412 	} else {
  4957 		$abspath_fix         = str_replace( '\\', '/', ABSPATH );
  5413 		$abspath_fix         = str_replace( '\\', '/', ABSPATH );
  4958 		$script_filename_dir = dirname( $_SERVER['SCRIPT_FILENAME'] );
  5414 		$script_filename_dir = dirname( $_SERVER['SCRIPT_FILENAME'] );
  4959 
  5415 
  4960 		// The request is for the admin
  5416 		// The request is for the admin.
  4961 		if ( strpos( $_SERVER['REQUEST_URI'], 'wp-admin' ) !== false || strpos( $_SERVER['REQUEST_URI'], 'wp-login.php' ) !== false ) {
  5417 		if ( strpos( $_SERVER['REQUEST_URI'], 'wp-admin' ) !== false || strpos( $_SERVER['REQUEST_URI'], 'wp-login.php' ) !== false ) {
  4962 			$path = preg_replace( '#/(wp-admin/.*|wp-login.php)#i', '', $_SERVER['REQUEST_URI'] );
  5418 			$path = preg_replace( '#/(wp-admin/.*|wp-login.php)#i', '', $_SERVER['REQUEST_URI'] );
  4963 
  5419 
  4964 			// The request is for a file in ABSPATH
  5420 			// The request is for a file in ABSPATH.
  4965 		} elseif ( $script_filename_dir . '/' == $abspath_fix ) {
  5421 		} elseif ( $script_filename_dir . '/' === $abspath_fix ) {
  4966 			// Strip off any file/query params in the path
  5422 			// Strip off any file/query params in the path.
  4967 			$path = preg_replace( '#/[^/]*$#i', '', $_SERVER['PHP_SELF'] );
  5423 			$path = preg_replace( '#/[^/]*$#i', '', $_SERVER['PHP_SELF'] );
  4968 
  5424 
  4969 		} else {
  5425 		} else {
  4970 			if ( false !== strpos( $_SERVER['SCRIPT_FILENAME'], $abspath_fix ) ) {
  5426 			if ( false !== strpos( $_SERVER['SCRIPT_FILENAME'], $abspath_fix ) ) {
  4971 				// Request is hitting a file inside ABSPATH
  5427 				// Request is hitting a file inside ABSPATH.
  4972 				$directory = str_replace( ABSPATH, '', $script_filename_dir );
  5428 				$directory = str_replace( ABSPATH, '', $script_filename_dir );
  4973 				// Strip off the sub directory, and any file/query params
  5429 				// Strip off the subdirectory, and any file/query params.
  4974 				$path = preg_replace( '#/' . preg_quote( $directory, '#' ) . '/[^/]*$#i', '', $_SERVER['REQUEST_URI'] );
  5430 				$path = preg_replace( '#/' . preg_quote( $directory, '#' ) . '/[^/]*$#i', '', $_SERVER['REQUEST_URI'] );
  4975 			} elseif ( false !== strpos( $abspath_fix, $script_filename_dir ) ) {
  5431 			} elseif ( false !== strpos( $abspath_fix, $script_filename_dir ) ) {
  4976 				// Request is hitting a file above ABSPATH
  5432 				// Request is hitting a file above ABSPATH.
  4977 				$subdirectory = substr( $abspath_fix, strpos( $abspath_fix, $script_filename_dir ) + strlen( $script_filename_dir ) );
  5433 				$subdirectory = substr( $abspath_fix, strpos( $abspath_fix, $script_filename_dir ) + strlen( $script_filename_dir ) );
  4978 				// Strip off any file/query params from the path, appending the sub directory to the installation
  5434 				// Strip off any file/query params from the path, appending the subdirectory to the installation.
  4979 				$path = preg_replace( '#/[^/]*$#i', '', $_SERVER['REQUEST_URI'] ) . $subdirectory;
  5435 				$path = preg_replace( '#/[^/]*$#i', '', $_SERVER['REQUEST_URI'] ) . $subdirectory;
  4980 			} else {
  5436 			} else {
  4981 				$path = $_SERVER['REQUEST_URI'];
  5437 				$path = $_SERVER['REQUEST_URI'];
  4982 			}
  5438 			}
  4983 		}
  5439 		}
  4984 
  5440 
  4985 		$schema = is_ssl() ? 'https://' : 'http://'; // set_url_scheme() is not defined yet
  5441 		$schema = is_ssl() ? 'https://' : 'http://'; // set_url_scheme() is not defined yet.
  4986 		$url    = $schema . $_SERVER['HTTP_HOST'] . $path;
  5442 		$url    = $schema . $_SERVER['HTTP_HOST'] . $path;
  4987 	}
  5443 	}
  4988 
  5444 
  4989 	return rtrim( $url, '/' );
  5445 	return rtrim( $url, '/' );
  4990 }
  5446 }
  4998  *
  5454  *
  4999  * Suspension lasts for a single page load at most. Remember to call this
  5455  * Suspension lasts for a single page load at most. Remember to call this
  5000  * function again if you wish to re-enable cache adds earlier.
  5456  * function again if you wish to re-enable cache adds earlier.
  5001  *
  5457  *
  5002  * @since 3.3.0
  5458  * @since 3.3.0
  5003  *
       
  5004  * @staticvar bool $_suspend
       
  5005  *
  5459  *
  5006  * @param bool $suspend Optional. Suspends additions if true, re-enables them if false.
  5460  * @param bool $suspend Optional. Suspends additions if true, re-enables them if false.
  5007  * @return bool The current suspend setting
  5461  * @return bool The current suspend setting
  5008  */
  5462  */
  5009 function wp_suspend_cache_addition( $suspend = null ) {
  5463 function wp_suspend_cache_addition( $suspend = null ) {
  5059 		$site_id = get_current_blog_id();
  5513 		$site_id = get_current_blog_id();
  5060 	}
  5514 	}
  5061 
  5515 
  5062 	$site_id = (int) $site_id;
  5516 	$site_id = (int) $site_id;
  5063 
  5517 
  5064 	return $site_id === get_main_site_id( $network_id );
  5518 	return get_main_site_id( $network_id ) === $site_id;
  5065 }
  5519 }
  5066 
  5520 
  5067 /**
  5521 /**
  5068  * Gets the main site ID.
  5522  * Gets the main site ID.
  5069  *
  5523  *
  5103 		$network_id = get_current_network_id();
  5557 		$network_id = get_current_network_id();
  5104 	}
  5558 	}
  5105 
  5559 
  5106 	$network_id = (int) $network_id;
  5560 	$network_id = (int) $network_id;
  5107 
  5561 
  5108 	return ( $network_id === get_main_network_id() );
  5562 	return ( get_main_network_id() === $network_id );
  5109 }
  5563 }
  5110 
  5564 
  5111 /**
  5565 /**
  5112  * Get the main network ID.
  5566  * Get the main network ID.
  5113  *
  5567  *
  5150 /**
  5604 /**
  5151  * Determine whether global terms are enabled.
  5605  * Determine whether global terms are enabled.
  5152  *
  5606  *
  5153  * @since 3.0.0
  5607  * @since 3.0.0
  5154  *
  5608  *
  5155  * @staticvar bool $global_terms
       
  5156  *
       
  5157  * @return bool True if multisite and global terms enabled.
  5609  * @return bool True if multisite and global terms enabled.
  5158  */
  5610  */
  5159 function global_terms_enabled() {
  5611 function global_terms_enabled() {
  5160 	if ( ! is_multisite() ) {
  5612 	if ( ! is_multisite() ) {
  5161 		return false;
  5613 		return false;
  5165 	if ( is_null( $global_terms ) ) {
  5617 	if ( is_null( $global_terms ) ) {
  5166 
  5618 
  5167 		/**
  5619 		/**
  5168 		 * Filters whether global terms are enabled.
  5620 		 * Filters whether global terms are enabled.
  5169 		 *
  5621 		 *
  5170 		 * Passing a non-null value to the filter will effectively short-circuit the function,
  5622 		 * Returning a non-null value from the filter will effectively short-circuit the function
  5171 		 * returning the value of the 'global_terms_enabled' site option instead.
  5623 		 * and return the value of the 'global_terms_enabled' site option instead.
  5172 		 *
  5624 		 *
  5173 		 * @since 3.0.0
  5625 		 * @since 3.0.0
  5174 		 *
  5626 		 *
  5175 		 * @param null $enabled Whether global terms are enabled.
  5627 		 * @param null $enabled Whether global terms are enabled.
  5176 		 */
  5628 		 */
  5224  * @since 2.8.0
  5676  * @since 2.8.0
  5225  *
  5677  *
  5226  * @return float|false Timezone GMT offset, false otherwise.
  5678  * @return float|false Timezone GMT offset, false otherwise.
  5227  */
  5679  */
  5228 function wp_timezone_override_offset() {
  5680 function wp_timezone_override_offset() {
  5229 	if ( ! $timezone_string = get_option( 'timezone_string' ) ) {
  5681 	$timezone_string = get_option( 'timezone_string' );
       
  5682 	if ( ! $timezone_string ) {
  5230 		return false;
  5683 		return false;
  5231 	}
  5684 	}
  5232 
  5685 
  5233 	$timezone_object = timezone_open( $timezone_string );
  5686 	$timezone_object = timezone_open( $timezone_string );
  5234 	$datetime_object = date_create();
  5687 	$datetime_object = date_create();
  5247  * @param array $a
  5700  * @param array $a
  5248  * @param array $b
  5701  * @param array $b
  5249  * @return int
  5702  * @return int
  5250  */
  5703  */
  5251 function _wp_timezone_choice_usort_callback( $a, $b ) {
  5704 function _wp_timezone_choice_usort_callback( $a, $b ) {
  5252 	// Don't use translated versions of Etc
  5705 	// Don't use translated versions of Etc.
  5253 	if ( 'Etc' === $a['continent'] && 'Etc' === $b['continent'] ) {
  5706 	if ( 'Etc' === $a['continent'] && 'Etc' === $b['continent'] ) {
  5254 		// Make the order of these more like the old dropdown
  5707 		// Make the order of these more like the old dropdown.
  5255 		if ( 'GMT+' === substr( $a['city'], 0, 4 ) && 'GMT+' === substr( $b['city'], 0, 4 ) ) {
  5708 		if ( 'GMT+' === substr( $a['city'], 0, 4 ) && 'GMT+' === substr( $b['city'], 0, 4 ) ) {
  5256 			return -1 * ( strnatcasecmp( $a['city'], $b['city'] ) );
  5709 			return -1 * ( strnatcasecmp( $a['city'], $b['city'] ) );
  5257 		}
  5710 		}
  5258 		if ( 'UTC' === $a['city'] ) {
  5711 		if ( 'UTC' === $a['city'] ) {
  5259 			if ( 'GMT+' === substr( $b['city'], 0, 4 ) ) {
  5712 			if ( 'GMT+' === substr( $b['city'], 0, 4 ) ) {
  5273 		if ( $a['t_city'] == $b['t_city'] ) {
  5726 		if ( $a['t_city'] == $b['t_city'] ) {
  5274 			return strnatcasecmp( $a['t_subcity'], $b['t_subcity'] );
  5727 			return strnatcasecmp( $a['t_subcity'], $b['t_subcity'] );
  5275 		}
  5728 		}
  5276 		return strnatcasecmp( $a['t_city'], $b['t_city'] );
  5729 		return strnatcasecmp( $a['t_city'], $b['t_city'] );
  5277 	} else {
  5730 	} else {
  5278 		// Force Etc to the bottom of the list
  5731 		// Force Etc to the bottom of the list.
  5279 		if ( 'Etc' === $a['continent'] ) {
  5732 		if ( 'Etc' === $a['continent'] ) {
  5280 			return 1;
  5733 			return 1;
  5281 		}
  5734 		}
  5282 		if ( 'Etc' === $b['continent'] ) {
  5735 		if ( 'Etc' === $b['continent'] ) {
  5283 			return -1;
  5736 			return -1;
  5289 /**
  5742 /**
  5290  * Gives a nicely-formatted list of timezone strings.
  5743  * Gives a nicely-formatted list of timezone strings.
  5291  *
  5744  *
  5292  * @since 2.9.0
  5745  * @since 2.9.0
  5293  * @since 4.7.0 Added the `$locale` parameter.
  5746  * @since 4.7.0 Added the `$locale` parameter.
  5294  *
       
  5295  * @staticvar bool $mo_loaded
       
  5296  * @staticvar string $locale_loaded
       
  5297  *
  5747  *
  5298  * @param string $selected_zone Selected timezone.
  5748  * @param string $selected_zone Selected timezone.
  5299  * @param string $locale        Optional. Locale to load the timezones in. Default current site locale.
  5749  * @param string $locale        Optional. Locale to load the timezones in. Default current site locale.
  5300  * @return string
  5750  * @return string
  5301  */
  5751  */
  5314 	}
  5764 	}
  5315 
  5765 
  5316 	$zonen = array();
  5766 	$zonen = array();
  5317 	foreach ( timezone_identifiers_list() as $zone ) {
  5767 	foreach ( timezone_identifiers_list() as $zone ) {
  5318 		$zone = explode( '/', $zone );
  5768 		$zone = explode( '/', $zone );
  5319 		if ( ! in_array( $zone[0], $continents ) ) {
  5769 		if ( ! in_array( $zone[0], $continents, true ) ) {
  5320 			continue;
  5770 			continue;
  5321 		}
  5771 		}
  5322 
  5772 
  5323 		// This determines what gets set and translated - we don't translate Etc/* strings here, they are done later
  5773 		// This determines what gets set and translated - we don't translate Etc/* strings here, they are done later.
  5324 		$exists    = array(
  5774 		$exists    = array(
  5325 			0 => ( isset( $zone[0] ) && $zone[0] ),
  5775 			0 => ( isset( $zone[0] ) && $zone[0] ),
  5326 			1 => ( isset( $zone[1] ) && $zone[1] ),
  5776 			1 => ( isset( $zone[1] ) && $zone[1] ),
  5327 			2 => ( isset( $zone[2] ) && $zone[2] ),
  5777 			2 => ( isset( $zone[2] ) && $zone[2] ),
  5328 		);
  5778 		);
  5348 	if ( empty( $selected_zone ) ) {
  5798 	if ( empty( $selected_zone ) ) {
  5349 		$structure[] = '<option selected="selected" value="">' . __( 'Select a city' ) . '</option>';
  5799 		$structure[] = '<option selected="selected" value="">' . __( 'Select a city' ) . '</option>';
  5350 	}
  5800 	}
  5351 
  5801 
  5352 	foreach ( $zonen as $key => $zone ) {
  5802 	foreach ( $zonen as $key => $zone ) {
  5353 		// Build value in an array to join later
  5803 		// Build value in an array to join later.
  5354 		$value = array( $zone['continent'] );
  5804 		$value = array( $zone['continent'] );
  5355 
  5805 
  5356 		if ( empty( $zone['city'] ) ) {
  5806 		if ( empty( $zone['city'] ) ) {
  5357 			// It's at the continent level (generally won't happen)
  5807 			// It's at the continent level (generally won't happen).
  5358 			$display = $zone['t_continent'];
  5808 			$display = $zone['t_continent'];
  5359 		} else {
  5809 		} else {
  5360 			// It's inside a continent group
  5810 			// It's inside a continent group.
  5361 
  5811 
  5362 			// Continent optgroup
  5812 			// Continent optgroup.
  5363 			if ( ! isset( $zonen[ $key - 1 ] ) || $zonen[ $key - 1 ]['continent'] !== $zone['continent'] ) {
  5813 			if ( ! isset( $zonen[ $key - 1 ] ) || $zonen[ $key - 1 ]['continent'] !== $zone['continent'] ) {
  5364 				$label       = $zone['t_continent'];
  5814 				$label       = $zone['t_continent'];
  5365 				$structure[] = '<optgroup label="' . esc_attr( $label ) . '">';
  5815 				$structure[] = '<optgroup label="' . esc_attr( $label ) . '">';
  5366 			}
  5816 			}
  5367 
  5817 
  5368 			// Add the city to the value
  5818 			// Add the city to the value.
  5369 			$value[] = $zone['city'];
  5819 			$value[] = $zone['city'];
  5370 
  5820 
  5371 			$display = $zone['t_city'];
  5821 			$display = $zone['t_city'];
  5372 			if ( ! empty( $zone['subcity'] ) ) {
  5822 			if ( ! empty( $zone['subcity'] ) ) {
  5373 				// Add the subcity to the value
  5823 				// Add the subcity to the value.
  5374 				$value[]  = $zone['subcity'];
  5824 				$value[]  = $zone['subcity'];
  5375 				$display .= ' - ' . $zone['t_subcity'];
  5825 				$display .= ' - ' . $zone['t_subcity'];
  5376 			}
  5826 			}
  5377 		}
  5827 		}
  5378 
  5828 
  5379 		// Build the value
  5829 		// Build the value.
  5380 		$value    = join( '/', $value );
  5830 		$value    = join( '/', $value );
  5381 		$selected = '';
  5831 		$selected = '';
  5382 		if ( $value === $selected_zone ) {
  5832 		if ( $value === $selected_zone ) {
  5383 			$selected = 'selected="selected" ';
  5833 			$selected = 'selected="selected" ';
  5384 		}
  5834 		}
  5385 		$structure[] = '<option ' . $selected . 'value="' . esc_attr( $value ) . '">' . esc_html( $display ) . '</option>';
  5835 		$structure[] = '<option ' . $selected . 'value="' . esc_attr( $value ) . '">' . esc_html( $display ) . '</option>';
  5386 
  5836 
  5387 		// Close continent optgroup
  5837 		// Close continent optgroup.
  5388 		if ( ! empty( $zone['city'] ) && ( ! isset( $zonen[ $key + 1 ] ) || ( isset( $zonen[ $key + 1 ] ) && $zonen[ $key + 1 ]['continent'] !== $zone['continent'] ) ) ) {
  5838 		if ( ! empty( $zone['city'] ) && ( ! isset( $zonen[ $key + 1 ] ) || ( isset( $zonen[ $key + 1 ] ) && $zonen[ $key + 1 ]['continent'] !== $zone['continent'] ) ) ) {
  5389 			$structure[] = '</optgroup>';
  5839 			$structure[] = '</optgroup>';
  5390 		}
  5840 		}
  5391 	}
  5841 	}
  5392 
  5842 
  5393 	// Do UTC
  5843 	// Do UTC.
  5394 	$structure[] = '<optgroup label="' . esc_attr__( 'UTC' ) . '">';
  5844 	$structure[] = '<optgroup label="' . esc_attr__( 'UTC' ) . '">';
  5395 	$selected    = '';
  5845 	$selected    = '';
  5396 	if ( 'UTC' === $selected_zone ) {
  5846 	if ( 'UTC' === $selected_zone ) {
  5397 		$selected = 'selected="selected" ';
  5847 		$selected = 'selected="selected" ';
  5398 	}
  5848 	}
  5399 	$structure[] = '<option ' . $selected . 'value="' . esc_attr( 'UTC' ) . '">' . __( 'UTC' ) . '</option>';
  5849 	$structure[] = '<option ' . $selected . 'value="' . esc_attr( 'UTC' ) . '">' . __( 'UTC' ) . '</option>';
  5400 	$structure[] = '</optgroup>';
  5850 	$structure[] = '</optgroup>';
  5401 
  5851 
  5402 	// Do manual UTC offsets
  5852 	// Do manual UTC offsets.
  5403 	$structure[]  = '<optgroup label="' . esc_attr__( 'Manual Offsets' ) . '">';
  5853 	$structure[]  = '<optgroup label="' . esc_attr__( 'Manual Offsets' ) . '">';
  5404 	$offset_range = array(
  5854 	$offset_range = array(
  5405 		-12,
  5855 		-12,
  5406 		-11.5,
  5856 		-11.5,
  5407 		-11,
  5857 		-11,
  5519 			continue;
  5969 			continue;
  5520 		}
  5970 		}
  5521 
  5971 
  5522 		$del_post = get_post( $post_id );
  5972 		$del_post = get_post( $post_id );
  5523 
  5973 
  5524 		if ( ! $del_post || 'trash' != $del_post->post_status ) {
  5974 		if ( ! $del_post || 'trash' !== $del_post->post_status ) {
  5525 			delete_post_meta( $post_id, '_wp_trash_meta_status' );
  5975 			delete_post_meta( $post_id, '_wp_trash_meta_status' );
  5526 			delete_post_meta( $post_id, '_wp_trash_meta_time' );
  5976 			delete_post_meta( $post_id, '_wp_trash_meta_time' );
  5527 		} else {
  5977 		} else {
  5528 			wp_delete_post( $post_id );
  5978 			wp_delete_post( $post_id );
  5529 		}
  5979 		}
  5537 			continue;
  5987 			continue;
  5538 		}
  5988 		}
  5539 
  5989 
  5540 		$del_comment = get_comment( $comment_id );
  5990 		$del_comment = get_comment( $comment_id );
  5541 
  5991 
  5542 		if ( ! $del_comment || 'trash' != $del_comment->comment_approved ) {
  5992 		if ( ! $del_comment || 'trash' !== $del_comment->comment_approved ) {
  5543 			delete_comment_meta( $comment_id, '_wp_trash_meta_time' );
  5993 			delete_comment_meta( $comment_id, '_wp_trash_meta_time' );
  5544 			delete_comment_meta( $comment_id, '_wp_trash_meta_status' );
  5994 			delete_comment_meta( $comment_id, '_wp_trash_meta_status' );
  5545 		} else {
  5995 		} else {
  5546 			wp_delete_comment( $del_comment );
  5996 			wp_delete_comment( $del_comment );
  5547 		}
  5997 		}
  5549 }
  5999 }
  5550 
  6000 
  5551 /**
  6001 /**
  5552  * Retrieve metadata from a file.
  6002  * Retrieve metadata from a file.
  5553  *
  6003  *
  5554  * Searches for metadata in the first 8kiB of a file, such as a plugin or theme.
  6004  * Searches for metadata in the first 8 KB of a file, such as a plugin or theme.
  5555  * Each piece of metadata must be on its own line. Fields can not span multiple
  6005  * Each piece of metadata must be on its own line. Fields can not span multiple
  5556  * lines, the value will get cut at the end of the first line.
  6006  * lines, the value will get cut at the end of the first line.
  5557  *
  6007  *
  5558  * If the file data is not within that first 8kiB, then the author should correct
  6008  * If the file data is not within that first 8 KB, then the author should correct
  5559  * their plugin file and move the data headers to the top.
  6009  * their plugin file and move the data headers to the top.
  5560  *
  6010  *
  5561  * @link https://codex.wordpress.org/File_Header
  6011  * @link https://codex.wordpress.org/File_Header
  5562  *
  6012  *
  5563  * @since 2.9.0
  6013  * @since 2.9.0
  5564  *
  6014  *
  5565  * @param string $file            Absolute path to the file.
  6015  * @param string $file            Absolute path to the file.
  5566  * @param array  $default_headers List of headers, in the format `array('HeaderKey' => 'Header Name')`.
  6016  * @param array  $default_headers List of headers, in the format `array( 'HeaderKey' => 'Header Name' )`.
  5567  * @param string $context         Optional. If specified adds filter hook {@see 'extra_$context_headers'}.
  6017  * @param string $context         Optional. If specified adds filter hook {@see 'extra_$context_headers'}.
  5568  *                                Default empty.
  6018  *                                Default empty.
  5569  * @return array Array of file headers in `HeaderKey => Header Value` format.
  6019  * @return string[] Array of file header values keyed by header name.
  5570  */
  6020  */
  5571 function get_file_data( $file, $default_headers, $context = '' ) {
  6021 function get_file_data( $file, $default_headers, $context = '' ) {
  5572 	// We don't need to write to the file, so just open for reading.
  6022 	// We don't need to write to the file, so just open for reading.
  5573 	$fp = fopen( $file, 'r' );
  6023 	$fp = fopen( $file, 'r' );
  5574 
  6024 
  5575 	// Pull only the first 8kiB of the file in.
  6025 	// Pull only the first 8 KB of the file in.
  5576 	$file_data = fread( $fp, 8192 );
  6026 	$file_data = fread( $fp, 8 * KB_IN_BYTES );
  5577 
  6027 
  5578 	// PHP will close file handle, but we are good citizens.
  6028 	// PHP will close file handle, but we are good citizens.
  5579 	fclose( $fp );
  6029 	fclose( $fp );
  5580 
  6030 
  5581 	// Make sure we catch CR-only line endings.
  6031 	// Make sure we catch CR-only line endings.
  5589 	 *
  6039 	 *
  5590 	 * @since 2.9.0
  6040 	 * @since 2.9.0
  5591 	 *
  6041 	 *
  5592 	 * @param array $extra_context_headers Empty array by default.
  6042 	 * @param array $extra_context_headers Empty array by default.
  5593 	 */
  6043 	 */
  5594 	if ( $context && $extra_headers = apply_filters( "extra_{$context}_headers", array() ) ) {
  6044 	$extra_headers = $context ? apply_filters( "extra_{$context}_headers", array() ) : array();
  5595 		$extra_headers = array_combine( $extra_headers, $extra_headers ); // keys equal values
  6045 	if ( $extra_headers ) {
       
  6046 		$extra_headers = array_combine( $extra_headers, $extra_headers ); // Keys equal values.
  5596 		$all_headers   = array_merge( $extra_headers, (array) $default_headers );
  6047 		$all_headers   = array_merge( $extra_headers, (array) $default_headers );
  5597 	} else {
  6048 	} else {
  5598 		$all_headers = $default_headers;
  6049 		$all_headers = $default_headers;
  5599 	}
  6050 	}
  5600 
  6051 
  5618  *
  6069  *
  5619  * @see __return_false()
  6070  * @see __return_false()
  5620  *
  6071  *
  5621  * @return true True.
  6072  * @return true True.
  5622  */
  6073  */
  5623 function __return_true() {
  6074 function __return_true() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionDoubleUnderscore,PHPCompatibility.FunctionNameRestrictions.ReservedFunctionNames.FunctionDoubleUnderscore
  5624 	return true;
  6075 	return true;
  5625 }
  6076 }
  5626 
  6077 
  5627 /**
  6078 /**
  5628  * Returns false.
  6079  * Returns false.
  5633  *
  6084  *
  5634  * @see __return_true()
  6085  * @see __return_true()
  5635  *
  6086  *
  5636  * @return false False.
  6087  * @return false False.
  5637  */
  6088  */
  5638 function __return_false() {
  6089 function __return_false() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionDoubleUnderscore,PHPCompatibility.FunctionNameRestrictions.ReservedFunctionNames.FunctionDoubleUnderscore
  5639 	return false;
  6090 	return false;
  5640 }
  6091 }
  5641 
  6092 
  5642 /**
  6093 /**
  5643  * Returns 0.
  6094  * Returns 0.
  5646  *
  6097  *
  5647  * @since 3.0.0
  6098  * @since 3.0.0
  5648  *
  6099  *
  5649  * @return int 0.
  6100  * @return int 0.
  5650  */
  6101  */
  5651 function __return_zero() {
  6102 function __return_zero() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionDoubleUnderscore,PHPCompatibility.FunctionNameRestrictions.ReservedFunctionNames.FunctionDoubleUnderscore
  5652 	return 0;
  6103 	return 0;
  5653 }
  6104 }
  5654 
  6105 
  5655 /**
  6106 /**
  5656  * Returns an empty array.
  6107  * Returns an empty array.
  5659  *
  6110  *
  5660  * @since 3.0.0
  6111  * @since 3.0.0
  5661  *
  6112  *
  5662  * @return array Empty array.
  6113  * @return array Empty array.
  5663  */
  6114  */
  5664 function __return_empty_array() {
  6115 function __return_empty_array() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionDoubleUnderscore,PHPCompatibility.FunctionNameRestrictions.ReservedFunctionNames.FunctionDoubleUnderscore
  5665 	return array();
  6116 	return array();
  5666 }
  6117 }
  5667 
  6118 
  5668 /**
  6119 /**
  5669  * Returns null.
  6120  * Returns null.
  5672  *
  6123  *
  5673  * @since 3.4.0
  6124  * @since 3.4.0
  5674  *
  6125  *
  5675  * @return null Null value.
  6126  * @return null Null value.
  5676  */
  6127  */
  5677 function __return_null() {
  6128 function __return_null() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionDoubleUnderscore,PHPCompatibility.FunctionNameRestrictions.ReservedFunctionNames.FunctionDoubleUnderscore
  5678 	return null;
  6129 	return null;
  5679 }
  6130 }
  5680 
  6131 
  5681 /**
  6132 /**
  5682  * Returns an empty string.
  6133  * Returns an empty string.
  5687  *
  6138  *
  5688  * @see __return_null()
  6139  * @see __return_null()
  5689  *
  6140  *
  5690  * @return string Empty string.
  6141  * @return string Empty string.
  5691  */
  6142  */
  5692 function __return_empty_string() {
  6143 function __return_empty_string() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionDoubleUnderscore,PHPCompatibility.FunctionNameRestrictions.ReservedFunctionNames.FunctionDoubleUnderscore
  5693 	return '';
  6144 	return '';
  5694 }
  6145 }
  5695 
  6146 
  5696 /**
  6147 /**
  5697  * Send a HTTP header to disable content type sniffing in browsers which support it.
  6148  * Send a HTTP header to disable content type sniffing in browsers which support it.
  5700  *
  6151  *
  5701  * @see https://blogs.msdn.com/ie/archive/2008/07/02/ie8-security-part-v-comprehensive-protection.aspx
  6152  * @see https://blogs.msdn.com/ie/archive/2008/07/02/ie8-security-part-v-comprehensive-protection.aspx
  5702  * @see https://src.chromium.org/viewvc/chrome?view=rev&revision=6985
  6153  * @see https://src.chromium.org/viewvc/chrome?view=rev&revision=6985
  5703  */
  6154  */
  5704 function send_nosniff_header() {
  6155 function send_nosniff_header() {
  5705 	@header( 'X-Content-Type-Options: nosniff' );
  6156 	header( 'X-Content-Type-Options: nosniff' );
  5706 }
  6157 }
  5707 
  6158 
  5708 /**
  6159 /**
  5709  * Return a MySQL expression for selecting the week number based on the start_of_week option.
  6160  * Return a MySQL expression for selecting the week number based on the start_of_week option.
  5710  *
  6161  *
  5713  *
  6164  *
  5714  * @param string $column Database column.
  6165  * @param string $column Database column.
  5715  * @return string SQL clause.
  6166  * @return string SQL clause.
  5716  */
  6167  */
  5717 function _wp_mysql_week( $column ) {
  6168 function _wp_mysql_week( $column ) {
  5718 	switch ( $start_of_week = (int) get_option( 'start_of_week' ) ) {
  6169 	$start_of_week = (int) get_option( 'start_of_week' );
       
  6170 	switch ( $start_of_week ) {
  5719 		case 1:
  6171 		case 1:
  5720 			return "WEEK( $column, 1 )";
  6172 			return "WEEK( $column, 1 )";
  5721 		case 2:
  6173 		case 2:
  5722 		case 3:
  6174 		case 3:
  5723 		case 4:
  6175 		case 4:
  5744  * @return array IDs of all members of loop.
  6196  * @return array IDs of all members of loop.
  5745  */
  6197  */
  5746 function wp_find_hierarchy_loop( $callback, $start, $start_parent, $callback_args = array() ) {
  6198 function wp_find_hierarchy_loop( $callback, $start, $start_parent, $callback_args = array() ) {
  5747 	$override = is_null( $start_parent ) ? array() : array( $start => $start_parent );
  6199 	$override = is_null( $start_parent ) ? array() : array( $start => $start_parent );
  5748 
  6200 
  5749 	if ( ! $arbitrary_loop_member = wp_find_hierarchy_loop_tortoise_hare( $callback, $start, $override, $callback_args ) ) {
  6201 	$arbitrary_loop_member = wp_find_hierarchy_loop_tortoise_hare( $callback, $start, $override, $callback_args );
       
  6202 	if ( ! $arbitrary_loop_member ) {
  5750 		return array();
  6203 		return array();
  5751 	}
  6204 	}
  5752 
  6205 
  5753 	return wp_find_hierarchy_loop_tortoise_hare( $callback, $arbitrary_loop_member, $override, $callback_args, true );
  6206 	return wp_find_hierarchy_loop_tortoise_hare( $callback, $arbitrary_loop_member, $override, $callback_args, true );
  5754 }
  6207 }
  5772  *                                the returned array might include branches). Default false.
  6225  *                                the returned array might include branches). Default false.
  5773  * @return mixed Scalar ID of some arbitrary member of the loop, or array of IDs of all members of loop if
  6226  * @return mixed Scalar ID of some arbitrary member of the loop, or array of IDs of all members of loop if
  5774  *               $_return_loop
  6227  *               $_return_loop
  5775  */
  6228  */
  5776 function wp_find_hierarchy_loop_tortoise_hare( $callback, $start, $override = array(), $callback_args = array(), $_return_loop = false ) {
  6229 function wp_find_hierarchy_loop_tortoise_hare( $callback, $start, $override = array(), $callback_args = array(), $_return_loop = false ) {
  5777 	$tortoise = $hare = $evanescent_hare = $start;
  6230 	$tortoise        = $start;
  5778 	$return   = array();
  6231 	$hare            = $start;
  5779 
  6232 	$evanescent_hare = $start;
  5780 	// Set evanescent_hare to one past hare
  6233 	$return          = array();
  5781 	// Increment hare two steps
  6234 
       
  6235 	// Set evanescent_hare to one past hare.
       
  6236 	// Increment hare two steps.
  5782 	while (
  6237 	while (
  5783 		$tortoise
  6238 		$tortoise
  5784 	&&
  6239 	&&
  5785 		( $evanescent_hare = isset( $override[ $hare ] ) ? $override[ $hare ] : call_user_func_array( $callback, array_merge( array( $hare ), $callback_args ) ) )
  6240 		( $evanescent_hare = isset( $override[ $hare ] ) ? $override[ $hare ] : call_user_func_array( $callback, array_merge( array( $hare ), $callback_args ) ) )
  5786 	&&
  6241 	&&
  5787 		( $hare = isset( $override[ $evanescent_hare ] ) ? $override[ $evanescent_hare ] : call_user_func_array( $callback, array_merge( array( $evanescent_hare ), $callback_args ) ) )
  6242 		( $hare = isset( $override[ $evanescent_hare ] ) ? $override[ $evanescent_hare ] : call_user_func_array( $callback, array_merge( array( $evanescent_hare ), $callback_args ) ) )
  5788 	) {
  6243 	) {
  5789 		if ( $_return_loop ) {
  6244 		if ( $_return_loop ) {
  5790 			$return[ $tortoise ] = $return[ $evanescent_hare ] = $return[ $hare ] = true;
  6245 			$return[ $tortoise ]        = true;
  5791 		}
  6246 			$return[ $evanescent_hare ] = true;
  5792 
  6247 			$return[ $hare ]            = true;
  5793 		// tortoise got lapped - must be a loop
  6248 		}
       
  6249 
       
  6250 		// Tortoise got lapped - must be a loop.
  5794 		if ( $tortoise == $evanescent_hare || $tortoise == $hare ) {
  6251 		if ( $tortoise == $evanescent_hare || $tortoise == $hare ) {
  5795 			return $_return_loop ? $return : $tortoise;
  6252 			return $_return_loop ? $return : $tortoise;
  5796 		}
  6253 		}
  5797 
  6254 
  5798 		// Increment tortoise by one step
  6255 		// Increment tortoise by one step.
  5799 		$tortoise = isset( $override[ $tortoise ] ) ? $override[ $tortoise ] : call_user_func_array( $callback, array_merge( array( $tortoise ), $callback_args ) );
  6256 		$tortoise = isset( $override[ $tortoise ] ) ? $override[ $tortoise ] : call_user_func_array( $callback, array_merge( array( $tortoise ), $callback_args ) );
  5800 	}
  6257 	}
  5801 
  6258 
  5802 	return false;
  6259 	return false;
  5803 }
  6260 }
  5808  * @since 3.1.3
  6265  * @since 3.1.3
  5809  *
  6266  *
  5810  * @see https://developer.mozilla.org/en/the_x-frame-options_response_header
  6267  * @see https://developer.mozilla.org/en/the_x-frame-options_response_header
  5811  */
  6268  */
  5812 function send_frame_options_header() {
  6269 function send_frame_options_header() {
  5813 	@header( 'X-Frame-Options: SAMEORIGIN' );
  6270 	header( 'X-Frame-Options: SAMEORIGIN' );
  5814 }
  6271 }
  5815 
  6272 
  5816 /**
  6273 /**
  5817  * Retrieve a list of protocols to allow in HTML attributes.
  6274  * Retrieve a list of protocols to allow in HTML attributes.
  5818  *
  6275  *
  5819  * @since 3.3.0
  6276  * @since 3.3.0
  5820  * @since 4.3.0 Added 'webcal' to the protocols array.
  6277  * @since 4.3.0 Added 'webcal' to the protocols array.
  5821  * @since 4.7.0 Added 'urn' to the protocols array.
  6278  * @since 4.7.0 Added 'urn' to the protocols array.
       
  6279  * @since 5.3.0 Added 'sms' to the protocols array.
  5822  *
  6280  *
  5823  * @see wp_kses()
  6281  * @see wp_kses()
  5824  * @see esc_url()
  6282  * @see esc_url()
  5825  *
  6283  *
  5826  * @staticvar array $protocols
       
  5827  *
       
  5828  * @return string[] Array of allowed protocols. Defaults to an array containing 'http', 'https',
  6284  * @return string[] Array of allowed protocols. Defaults to an array containing 'http', 'https',
  5829  *                  'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet',
  6285  *                  'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet',
  5830  *                  'mms', 'rtsp', 'svn', 'tel', 'fax', 'xmpp', 'webcal', and 'urn'. This covers
  6286  *                  'mms', 'rtsp', 'sms', 'svn', 'tel', 'fax', 'xmpp', 'webcal', and 'urn'.
  5831  *                  all common link protocols, except for 'javascript' which should not be
  6287  *                  This covers all common link protocols, except for 'javascript' which should not
  5832  *                  allowed for untrusted users.
  6288  *                  be allowed for untrusted users.
  5833  */
  6289  */
  5834 function wp_allowed_protocols() {
  6290 function wp_allowed_protocols() {
  5835 	static $protocols = array();
  6291 	static $protocols = array();
  5836 
  6292 
  5837 	if ( empty( $protocols ) ) {
  6293 	if ( empty( $protocols ) ) {
  5838 		$protocols = array( 'http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet', 'mms', 'rtsp', 'svn', 'tel', 'fax', 'xmpp', 'webcal', 'urn' );
  6294 		$protocols = array( 'http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet', 'mms', 'rtsp', 'sms', 'svn', 'tel', 'fax', 'xmpp', 'webcal', 'urn' );
  5839 	}
  6295 	}
  5840 
  6296 
  5841 	if ( ! did_action( 'wp_loaded' ) ) {
  6297 	if ( ! did_action( 'wp_loaded' ) ) {
  5842 		/**
  6298 		/**
  5843 		 * Filters the list of protocols allowed in HTML attributes.
  6299 		 * Filters the list of protocols allowed in HTML attributes.
  5844 		 *
  6300 		 *
  5845 		 * @since 3.0.0
  6301 		 * @since 3.0.0
  5846 		 *
  6302 		 *
  5847 		 * @param array $protocols Array of allowed protocols e.g. 'http', 'ftp', 'tel', and more.
  6303 		 * @param string[] $protocols Array of allowed protocols e.g. 'http', 'ftp', 'tel', and more.
  5848 		 */
  6304 		 */
  5849 		$protocols = array_unique( (array) apply_filters( 'kses_allowed_protocols', $protocols ) );
  6305 		$protocols = array_unique( (array) apply_filters( 'kses_allowed_protocols', $protocols ) );
  5850 	}
  6306 	}
  5851 
  6307 
  5852 	return $protocols;
  6308 	return $protocols;
  5857  * to the current point in code.
  6313  * to the current point in code.
  5858  *
  6314  *
  5859  * @since 3.4.0
  6315  * @since 3.4.0
  5860  *
  6316  *
  5861  * @see https://core.trac.wordpress.org/ticket/19589
  6317  * @see https://core.trac.wordpress.org/ticket/19589
  5862  *
       
  5863  * @staticvar array $truncate_paths Array of paths to truncate.
       
  5864  *
  6318  *
  5865  * @param string $ignore_class Optional. A class to ignore all function calls within - useful
  6319  * @param string $ignore_class Optional. A class to ignore all function calls within - useful
  5866  *                             when you want to just give info about the callee. Default null.
  6320  *                             when you want to just give info about the callee. Default null.
  5867  * @param int    $skip_frames  Optional. A number of stack frames to skip - useful for unwinding
  6321  * @param int    $skip_frames  Optional. A number of stack frames to skip - useful for unwinding
  5868  *                             back to the source of the issue. Default 0.
  6322  *                             back to the source of the issue. Default 0.
  5872  *                      of individual calls.
  6326  *                      of individual calls.
  5873  */
  6327  */
  5874 function wp_debug_backtrace_summary( $ignore_class = null, $skip_frames = 0, $pretty = true ) {
  6328 function wp_debug_backtrace_summary( $ignore_class = null, $skip_frames = 0, $pretty = true ) {
  5875 	static $truncate_paths;
  6329 	static $truncate_paths;
  5876 
  6330 
  5877 	if ( version_compare( PHP_VERSION, '5.2.5', '>=' ) ) {
  6331 	$trace       = debug_backtrace( false );
  5878 		$trace = debug_backtrace( false );
       
  5879 	} else {
       
  5880 		$trace = debug_backtrace();
       
  5881 	}
       
  5882 
       
  5883 	$caller      = array();
  6332 	$caller      = array();
  5884 	$check_class = ! is_null( $ignore_class );
  6333 	$check_class = ! is_null( $ignore_class );
  5885 	$skip_frames++; // skip this function
  6334 	$skip_frames++; // Skip this function.
  5886 
  6335 
  5887 	if ( ! isset( $truncate_paths ) ) {
  6336 	if ( ! isset( $truncate_paths ) ) {
  5888 		$truncate_paths = array(
  6337 		$truncate_paths = array(
  5889 			wp_normalize_path( WP_CONTENT_DIR ),
  6338 			wp_normalize_path( WP_CONTENT_DIR ),
  5890 			wp_normalize_path( ABSPATH ),
  6339 			wp_normalize_path( ABSPATH ),
  5894 	foreach ( $trace as $call ) {
  6343 	foreach ( $trace as $call ) {
  5895 		if ( $skip_frames > 0 ) {
  6344 		if ( $skip_frames > 0 ) {
  5896 			$skip_frames--;
  6345 			$skip_frames--;
  5897 		} elseif ( isset( $call['class'] ) ) {
  6346 		} elseif ( isset( $call['class'] ) ) {
  5898 			if ( $check_class && $ignore_class == $call['class'] ) {
  6347 			if ( $check_class && $ignore_class == $call['class'] ) {
  5899 				continue; // Filter out calls
  6348 				continue; // Filter out calls.
  5900 			}
  6349 			}
  5901 
  6350 
  5902 			$caller[] = "{$call['class']}{$call['type']}{$call['function']}";
  6351 			$caller[] = "{$call['class']}{$call['type']}{$call['function']}";
  5903 		} else {
  6352 		} else {
  5904 			if ( in_array( $call['function'], array( 'do_action', 'apply_filters', 'do_action_ref_array', 'apply_filters_ref_array' ) ) ) {
  6353 			if ( in_array( $call['function'], array( 'do_action', 'apply_filters', 'do_action_ref_array', 'apply_filters_ref_array' ), true ) ) {
  5905 				$caller[] = "{$call['function']}('{$call['args'][0]}')";
  6354 				$caller[] = "{$call['function']}('{$call['args'][0]}')";
  5906 			} elseif ( in_array( $call['function'], array( 'include', 'include_once', 'require', 'require_once' ) ) ) {
  6355 			} elseif ( in_array( $call['function'], array( 'include', 'include_once', 'require', 'require_once' ), true ) ) {
  5907 				$filename = isset( $call['args'][0] ) ? $call['args'][0] : '';
  6356 				$filename = isset( $call['args'][0] ) ? $call['args'][0] : '';
  5908 				$caller[] = $call['function'] . "('" . str_replace( $truncate_paths, '', wp_normalize_path( $filename ) ) . "')";
  6357 				$caller[] = $call['function'] . "('" . str_replace( $truncate_paths, '', wp_normalize_path( $filename ) ) . "')";
  5909 			} else {
  6358 			} else {
  5910 				$caller[] = $call['function'];
  6359 				$caller[] = $call['function'];
  5911 			}
  6360 			}
  5927  * @param int[]  $object_ids Array of IDs.
  6376  * @param int[]  $object_ids Array of IDs.
  5928  * @param string $cache_key  The cache bucket to check against.
  6377  * @param string $cache_key  The cache bucket to check against.
  5929  * @return int[] Array of IDs not present in the cache.
  6378  * @return int[] Array of IDs not present in the cache.
  5930  */
  6379  */
  5931 function _get_non_cached_ids( $object_ids, $cache_key ) {
  6380 function _get_non_cached_ids( $object_ids, $cache_key ) {
  5932 	$clean = array();
  6381 	$non_cached_ids = array();
  5933 	foreach ( $object_ids as $id ) {
  6382 	$cache_values   = wp_cache_get_multiple( $object_ids, $cache_key );
  5934 		$id = (int) $id;
  6383 
  5935 		if ( ! wp_cache_get( $id, $cache_key ) ) {
  6384 	foreach ( $cache_values as $id => $value ) {
  5936 			$clean[] = $id;
  6385 		if ( ! $value ) {
  5937 		}
  6386 			$non_cached_ids[] = (int) $id;
  5938 	}
  6387 		}
  5939 
  6388 	}
  5940 	return $clean;
  6389 
       
  6390 	return $non_cached_ids;
  5941 }
  6391 }
  5942 
  6392 
  5943 /**
  6393 /**
  5944  * Test if the current device has the capability to upload files.
  6394  * Test if the current device has the capability to upload files.
  5945  *
  6395  *
  5974  */
  6424  */
  5975 function wp_is_stream( $path ) {
  6425 function wp_is_stream( $path ) {
  5976 	$scheme_separator = strpos( $path, '://' );
  6426 	$scheme_separator = strpos( $path, '://' );
  5977 
  6427 
  5978 	if ( false === $scheme_separator ) {
  6428 	if ( false === $scheme_separator ) {
  5979 		// $path isn't a stream
  6429 		// $path isn't a stream.
  5980 		return false;
  6430 		return false;
  5981 	}
  6431 	}
  5982 
  6432 
  5983 	$stream = substr( $path, 0, $scheme_separator );
  6433 	$stream = substr( $path, 0, $scheme_separator );
  5984 
  6434 
  5988 /**
  6438 /**
  5989  * Test if the supplied date is valid for the Gregorian calendar.
  6439  * Test if the supplied date is valid for the Gregorian calendar.
  5990  *
  6440  *
  5991  * @since 3.5.0
  6441  * @since 3.5.0
  5992  *
  6442  *
  5993  * @link https://secure.php.net/manual/en/function.checkdate.php
  6443  * @link https://www.php.net/manual/en/function.checkdate.php
  5994  *
  6444  *
  5995  * @param  int    $month       Month number.
  6445  * @param int    $month       Month number.
  5996  * @param  int    $day         Day number.
  6446  * @param int    $day         Day number.
  5997  * @param  int    $year        Year number.
  6447  * @param int    $year        Year number.
  5998  * @param  string $source_date The date to filter.
  6448  * @param string $source_date The date to filter.
  5999  * @return bool True if valid date, false if not valid date.
  6449  * @return bool True if valid date, false if not valid date.
  6000  */
  6450  */
  6001 function wp_checkdate( $month, $day, $year, $source_date ) {
  6451 function wp_checkdate( $month, $day, $year, $source_date ) {
  6002 	/**
  6452 	/**
  6003 	 * Filters whether the given date is valid for the Gregorian calendar.
  6453 	 * Filters whether the given date is valid for the Gregorian calendar.
  6030 		return;
  6480 		return;
  6031 	}
  6481 	}
  6032 
  6482 
  6033 	$screen = get_current_screen();
  6483 	$screen = get_current_screen();
  6034 	$hidden = array( 'update', 'update-network', 'update-core', 'update-core-network', 'upgrade', 'upgrade-network', 'network' );
  6484 	$hidden = array( 'update', 'update-network', 'update-core', 'update-core-network', 'upgrade', 'upgrade-network', 'network' );
  6035 	$show   = ! in_array( $screen->id, $hidden );
  6485 	$show   = ! in_array( $screen->id, $hidden, true );
  6036 
  6486 
  6037 	/**
  6487 	/**
  6038 	 * Filters whether to load the authentication check.
  6488 	 * Filters whether to load the authentication check.
  6039 	 *
  6489 	 *
  6040 	 * Passing a falsey value to the filter will effectively short-circuit
  6490 	 * Returning a falsey value from the filter will effectively short-circuit
  6041 	 * loading the authentication check.
  6491 	 * loading the authentication check.
  6042 	 *
  6492 	 *
  6043 	 * @since 3.6.0
  6493 	 * @since 3.6.0
  6044 	 *
  6494 	 *
  6045 	 * @param bool      $show   Whether to load the authentication check.
  6495 	 * @param bool      $show   Whether to load the authentication check.
  6114  * @since 3.6.0
  6564  * @since 3.6.0
  6115  *
  6565  *
  6116  * @global int $login_grace_period
  6566  * @global int $login_grace_period
  6117  *
  6567  *
  6118  * @param array $response  The Heartbeat response.
  6568  * @param array $response  The Heartbeat response.
  6119  * @return array $response The Heartbeat response with 'wp-auth-check' value set.
  6569  * @return array The Heartbeat response with 'wp-auth-check' value set.
  6120  */
  6570  */
  6121 function wp_auth_check( $response ) {
  6571 function wp_auth_check( $response ) {
  6122 	$response['wp-auth-check'] = is_user_logged_in() && empty( $GLOBALS['login_grace_period'] );
  6572 	$response['wp-auth-check'] = is_user_logged_in() && empty( $GLOBALS['login_grace_period'] );
  6123 	return $response;
  6573 	return $response;
  6124 }
  6574 }
  6139  * @param string $tag An HTML tag name. Example: 'video'.
  6589  * @param string $tag An HTML tag name. Example: 'video'.
  6140  * @return string Tag RegEx.
  6590  * @return string Tag RegEx.
  6141  */
  6591  */
  6142 function get_tag_regex( $tag ) {
  6592 function get_tag_regex( $tag ) {
  6143 	if ( empty( $tag ) ) {
  6593 	if ( empty( $tag ) ) {
  6144 		return;
  6594 		return '';
  6145 	}
  6595 	}
  6146 	return sprintf( '<%1$s[^<]*(?:>[\s\S]*<\/%1$s>|\s*\/>)', tag_escape( $tag ) );
  6596 	return sprintf( '<%1$s[^<]*(?:>[\s\S]*<\/%1$s>|\s*\/>)', tag_escape( $tag ) );
  6147 }
  6597 }
  6148 
  6598 
  6149 /**
  6599 /**
  6150  * Retrieve a canonical form of the provided charset appropriate for passing to PHP
  6600  * Retrieve a canonical form of the provided charset appropriate for passing to PHP
  6151  * functions such as htmlspecialchars() and charset html attributes.
  6601  * functions such as htmlspecialchars() and charset HTML attributes.
  6152  *
  6602  *
  6153  * @since 3.6.0
  6603  * @since 3.6.0
  6154  * @access private
  6604  * @access private
  6155  *
  6605  *
  6156  * @see https://core.trac.wordpress.org/ticket/23688
  6606  * @see https://core.trac.wordpress.org/ticket/23688
  6190  *
  6640  *
  6191  * @since 3.7.0
  6641  * @since 3.7.0
  6192  *
  6642  *
  6193  * @see reset_mbstring_encoding()
  6643  * @see reset_mbstring_encoding()
  6194  *
  6644  *
  6195  * @staticvar array $encodings
       
  6196  * @staticvar bool  $overloaded
       
  6197  *
       
  6198  * @param bool $reset Optional. Whether to reset the encoding back to a previously-set encoding.
  6645  * @param bool $reset Optional. Whether to reset the encoding back to a previously-set encoding.
  6199  *                    Default false.
  6646  *                    Default false.
  6200  */
  6647  */
  6201 function mbstring_binary_safe_encoding( $reset = false ) {
  6648 function mbstring_binary_safe_encoding( $reset = false ) {
  6202 	static $encodings  = array();
  6649 	static $encodings  = array();
  6203 	static $overloaded = null;
  6650 	static $overloaded = null;
  6204 
  6651 
  6205 	if ( is_null( $overloaded ) ) {
  6652 	if ( is_null( $overloaded ) ) {
  6206 		$overloaded = function_exists( 'mb_internal_encoding' ) && ( ini_get( 'mbstring.func_overload' ) & 2 );
  6653 		$overloaded = function_exists( 'mb_internal_encoding' ) && ( ini_get( 'mbstring.func_overload' ) & 2 ); // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.mbstring_func_overloadDeprecated
  6207 	}
  6654 	}
  6208 
  6655 
  6209 	if ( false === $overloaded ) {
  6656 	if ( false === $overloaded ) {
  6210 		return;
  6657 		return;
  6211 	}
  6658 	}
  6316  *
  6763  *
  6317  * This prevents reusing the same tab for a preview when the user has navigated away.
  6764  * This prevents reusing the same tab for a preview when the user has navigated away.
  6318  *
  6765  *
  6319  * @since 4.3.0
  6766  * @since 4.3.0
  6320  *
  6767  *
  6321  * @global WP_Post $post
  6768  * @global WP_Post $post Global post object.
  6322  */
  6769  */
  6323 function wp_post_preview_js() {
  6770 function wp_post_preview_js() {
  6324 	global $post;
  6771 	global $post;
  6325 
  6772 
  6326 	if ( ! is_preview() || empty( $post ) ) {
  6773 	if ( ! is_preview() || empty( $post ) ) {
  6327 		return;
  6774 		return;
  6328 	}
  6775 	}
  6329 
  6776 
  6330 	// Has to match the window name used in post_submit_meta_box()
  6777 	// Has to match the window name used in post_submit_meta_box().
  6331 	$name = 'wp-preview-' . (int) $post->ID;
  6778 	$name = 'wp-preview-' . (int) $post->ID;
  6332 
  6779 
  6333 	?>
  6780 	?>
  6334 	<script>
  6781 	<script>
  6335 	( function() {
  6782 	( function() {
  6382 	// Exit early if the limit cannot be changed.
  6829 	// Exit early if the limit cannot be changed.
  6383 	if ( false === wp_is_ini_value_changeable( 'memory_limit' ) ) {
  6830 	if ( false === wp_is_ini_value_changeable( 'memory_limit' ) ) {
  6384 		return false;
  6831 		return false;
  6385 	}
  6832 	}
  6386 
  6833 
  6387 	$current_limit     = @ini_get( 'memory_limit' );
  6834 	$current_limit     = ini_get( 'memory_limit' );
  6388 	$current_limit_int = wp_convert_hr_to_bytes( $current_limit );
  6835 	$current_limit_int = wp_convert_hr_to_bytes( $current_limit );
  6389 
  6836 
  6390 	if ( -1 === $current_limit_int ) {
  6837 	if ( -1 === $current_limit_int ) {
  6391 		return false;
  6838 		return false;
  6392 	}
  6839 	}
  6454 	}
  6901 	}
  6455 
  6902 
  6456 	$filtered_limit_int = wp_convert_hr_to_bytes( $filtered_limit );
  6903 	$filtered_limit_int = wp_convert_hr_to_bytes( $filtered_limit );
  6457 
  6904 
  6458 	if ( -1 === $filtered_limit_int || ( $filtered_limit_int > $wp_max_limit_int && $filtered_limit_int > $current_limit_int ) ) {
  6905 	if ( -1 === $filtered_limit_int || ( $filtered_limit_int > $wp_max_limit_int && $filtered_limit_int > $current_limit_int ) ) {
  6459 		if ( false !== @ini_set( 'memory_limit', $filtered_limit ) ) {
  6906 		if ( false !== ini_set( 'memory_limit', $filtered_limit ) ) {
  6460 			return $filtered_limit;
  6907 			return $filtered_limit;
  6461 		} else {
  6908 		} else {
  6462 			return false;
  6909 			return false;
  6463 		}
  6910 		}
  6464 	} elseif ( -1 === $wp_max_limit_int || $wp_max_limit_int > $current_limit_int ) {
  6911 	} elseif ( -1 === $wp_max_limit_int || $wp_max_limit_int > $current_limit_int ) {
  6465 		if ( false !== @ini_set( 'memory_limit', $wp_max_limit ) ) {
  6912 		if ( false !== ini_set( 'memory_limit', $wp_max_limit ) ) {
  6466 			return $wp_max_limit;
  6913 			return $wp_max_limit;
  6467 		} else {
  6914 		} else {
  6468 			return false;
  6915 			return false;
  6469 		}
  6916 		}
  6470 	}
  6917 	}
  6521 
  6968 
  6522 	return (bool) preg_match( $regex, $uuid );
  6969 	return (bool) preg_match( $regex, $uuid );
  6523 }
  6970 }
  6524 
  6971 
  6525 /**
  6972 /**
  6526  * Get unique ID.
  6973  * Gets unique ID.
  6527  *
  6974  *
  6528  * This is a PHP implementation of Underscore's uniqueId method. A static variable
  6975  * This is a PHP implementation of Underscore's uniqueId method. A static variable
  6529  * contains an integer that is incremented with each call. This number is returned
  6976  * contains an integer that is incremented with each call. This number is returned
  6530  * with the optional prefix. As such the returned value is not universally unique,
  6977  * with the optional prefix. As such the returned value is not universally unique,
  6531  * but it is unique across the life of the PHP process.
  6978  * but it is unique across the life of the PHP process.
  6532  *
  6979  *
  6533  * @since 5.0.3
  6980  * @since 5.0.3
  6534  *
  6981  *
  6535  * @staticvar int $id_counter
       
  6536  *
       
  6537  * @param string $prefix Prefix for the returned ID.
  6982  * @param string $prefix Prefix for the returned ID.
  6538  * @return string Unique ID.
  6983  * @return string Unique ID.
  6539  */
  6984  */
  6540 function wp_unique_id( $prefix = '' ) {
  6985 function wp_unique_id( $prefix = '' ) {
  6541 	static $id_counter = 0;
  6986 	static $id_counter = 0;
  6542 	return $prefix . (string) ++$id_counter;
  6987 	return $prefix . (string) ++$id_counter;
  6543 }
  6988 }
  6544 
  6989 
  6545 /**
  6990 /**
  6546  * Get last changed date for the specified cache group.
  6991  * Gets last changed date for the specified cache group.
  6547  *
  6992  *
  6548  * @since 4.7.0
  6993  * @since 4.7.0
  6549  *
  6994  *
  6550  * @param string $group Where the cache contents are grouped.
  6995  * @param string $group Where the cache contents are grouped.
  6551  *
  6996  * @return string UNIX timestamp with microseconds representing when the group was last changed.
  6552  * @return string $last_changed UNIX timestamp with microseconds representing when the group was last changed.
       
  6553  */
  6997  */
  6554 function wp_cache_get_last_changed( $group ) {
  6998 function wp_cache_get_last_changed( $group ) {
  6555 	$last_changed = wp_cache_get( 'last_changed', $group );
  6999 	$last_changed = wp_cache_get( 'last_changed', $group );
  6556 
  7000 
  6557 	if ( ! $last_changed ) {
  7001 	if ( ! $last_changed ) {
  6609 ###SITEURL###'
  7053 ###SITEURL###'
  6610 	);
  7054 	);
  6611 
  7055 
  6612 	$email_change_email = array(
  7056 	$email_change_email = array(
  6613 		'to'      => $old_email,
  7057 		'to'      => $old_email,
  6614 		/* translators: Site admin email change notification email subject. %s: Site title */
  7058 		/* translators: Site admin email change notification email subject. %s: Site title. */
  6615 		'subject' => __( '[%s] Admin Email Changed' ),
  7059 		'subject' => __( '[%s] Admin Email Changed' ),
  6616 		'message' => $email_change_text,
  7060 		'message' => $email_change_text,
  6617 		'headers' => '',
  7061 		'headers' => '',
  6618 	);
  7062 	);
  6619 	// get site name
  7063 
       
  7064 	// Get site name.
  6620 	$site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
  7065 	$site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
  6621 
  7066 
  6622 	/**
  7067 	/**
  6623 	 * Filters the contents of the email notification sent when the site admin email address is changed.
  7068 	 * Filters the contents of the email notification sent when the site admin email address is changed.
  6624 	 *
  7069 	 *
  6661 /**
  7106 /**
  6662  * Return an anonymized IPv4 or IPv6 address.
  7107  * Return an anonymized IPv4 or IPv6 address.
  6663  *
  7108  *
  6664  * @since 4.9.6 Abstracted from `WP_Community_Events::get_unsafe_client_ip()`.
  7109  * @since 4.9.6 Abstracted from `WP_Community_Events::get_unsafe_client_ip()`.
  6665  *
  7110  *
  6666  * @param  string $ip_addr        The IPv4 or IPv6 address to be anonymized.
  7111  * @param string $ip_addr       The IPv4 or IPv6 address to be anonymized.
  6667  * @param  bool   $ipv6_fallback  Optional. Whether to return the original IPv6 address if the needed functions
  7112  * @param bool   $ipv6_fallback Optional. Whether to return the original IPv6 address if the needed functions
  6668  *                                to anonymize it are not present. Default false, return `::` (unspecified address).
  7113  *                              to anonymize it are not present. Default false, return `::` (unspecified address).
  6669  * @return string  The anonymized IP address.
  7114  * @return string  The anonymized IP address.
  6670  */
  7115  */
  6671 function wp_privacy_anonymize_ip( $ip_addr, $ipv6_fallback = false ) {
  7116 function wp_privacy_anonymize_ip( $ip_addr, $ipv6_fallback = false ) {
  6672 	// Detect what kind of IP address this is.
  7117 	// Detect what kind of IP address this is.
  6673 	$ip_prefix = '';
  7118 	$ip_prefix = '';
  6731 /**
  7176 /**
  6732  * Return uniform "anonymous" data by type.
  7177  * Return uniform "anonymous" data by type.
  6733  *
  7178  *
  6734  * @since 4.9.6
  7179  * @since 4.9.6
  6735  *
  7180  *
  6736  * @param  string $type The type of data to be anonymized.
  7181  * @param string $type The type of data to be anonymized.
  6737  * @param  string $data Optional The data to be anonymized.
  7182  * @param string $data Optional The data to be anonymized.
  6738  * @return string The anonymous data for the requested type.
  7183  * @return string The anonymous data for the requested type.
  6739  */
  7184  */
  6740 function wp_privacy_anonymize_data( $type, $data = '' ) {
  7185 function wp_privacy_anonymize_data( $type, $data = '' ) {
  6741 
  7186 
  6742 	switch ( $type ) {
  7187 	switch ( $type ) {
  6751 			break;
  7196 			break;
  6752 		case 'date':
  7197 		case 'date':
  6753 			$anonymous = '0000-00-00 00:00:00';
  7198 			$anonymous = '0000-00-00 00:00:00';
  6754 			break;
  7199 			break;
  6755 		case 'text':
  7200 		case 'text':
  6756 			/* translators: deleted text */
  7201 			/* translators: Deleted text. */
  6757 			$anonymous = __( '[deleted]' );
  7202 			$anonymous = __( '[deleted]' );
  6758 			break;
  7203 			break;
  6759 		case 'longtext':
  7204 		case 'longtext':
  6760 			/* translators: deleted long text */
  7205 			/* translators: Deleted long text. */
  6761 			$anonymous = __( 'This content was deleted by the author.' );
  7206 			$anonymous = __( 'This content was deleted by the author.' );
  6762 			break;
  7207 			break;
  6763 		default:
  7208 		default:
  6764 			$anonymous = '';
  7209 			$anonymous = '';
       
  7210 			break;
  6765 	}
  7211 	}
  6766 
  7212 
  6767 	/**
  7213 	/**
  6768 	 * Filters the anonymous data for each type.
  7214 	 * Filters the anonymous data for each type.
  6769 	 *
  7215 	 *
  6852 	$exports_dir = wp_privacy_exports_dir();
  7298 	$exports_dir = wp_privacy_exports_dir();
  6853 	if ( ! is_dir( $exports_dir ) ) {
  7299 	if ( ! is_dir( $exports_dir ) ) {
  6854 		return;
  7300 		return;
  6855 	}
  7301 	}
  6856 
  7302 
  6857 	require_once( ABSPATH . 'wp-admin/includes/file.php' );
  7303 	require_once ABSPATH . 'wp-admin/includes/file.php';
  6858 	$export_files = list_files( $exports_dir, 100, array( 'index.html' ) );
  7304 	$export_files = list_files( $exports_dir, 100, array( 'index.html' ) );
  6859 
  7305 
  6860 	/**
  7306 	/**
  6861 	 * Filters the lifetime, in seconds, of a personal data export file.
  7307 	 * Filters the lifetime, in seconds, of a personal data export file.
  6862 	 *
  7308 	 *
  6959  * This function is to be used after {@see wp_get_update_php_url()} to return a consistent
  7405  * This function is to be used after {@see wp_get_update_php_url()} to return a consistent
  6960  * annotation if the web host has altered the default "Update PHP" page URL.
  7406  * annotation if the web host has altered the default "Update PHP" page URL.
  6961  *
  7407  *
  6962  * @since 5.2.0
  7408  * @since 5.2.0
  6963  *
  7409  *
  6964  * @return string $message Update PHP page annotation. An empty string if no custom URLs are provided.
  7410  * @return string Update PHP page annotation. An empty string if no custom URLs are provided.
  6965  */
  7411  */
  6966 function wp_get_update_php_annotation() {
  7412 function wp_get_update_php_annotation() {
  6967 	$update_url  = wp_get_update_php_url();
  7413 	$update_url  = wp_get_update_php_url();
  6968 	$default_url = wp_get_default_update_php_url();
  7414 	$default_url = wp_get_default_update_php_url();
  6969 
  7415 
  6970 	if ( $update_url === $default_url ) {
  7416 	if ( $update_url === $default_url ) {
  6971 		return '';
  7417 		return '';
  6972 	}
  7418 	}
  6973 
  7419 
  6974 	$annotation = sprintf(
  7420 	$annotation = sprintf(
  6975 		/* translators: %s: default Update PHP page URL */
  7421 		/* translators: %s: Default Update PHP page URL. */
  6976 		__( 'This resource is provided by your web host, and is specific to your site. For more information, <a href="%s" target="_blank">see the official WordPress documentation</a>.' ),
  7422 		__( 'This resource is provided by your web host, and is specific to your site. For more information, <a href="%s" target="_blank">see the official WordPress documentation</a>.' ),
  6977 		esc_url( $default_url )
  7423 		esc_url( $default_url )
  6978 	);
  7424 	);
  6979 
  7425 
  6980 	return $annotation;
  7426 	return $annotation;
  7029 	echo '<p class="button-container">';
  7475 	echo '<p class="button-container">';
  7030 	printf(
  7476 	printf(
  7031 		'<a class="button button-primary" href="%1$s" target="_blank" rel="noopener noreferrer">%2$s <span class="screen-reader-text">%3$s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a>',
  7477 		'<a class="button button-primary" href="%1$s" target="_blank" rel="noopener noreferrer">%2$s <span class="screen-reader-text">%3$s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a>',
  7032 		esc_url( $direct_update_url ),
  7478 		esc_url( $direct_update_url ),
  7033 		__( 'Update PHP' ),
  7479 		__( 'Update PHP' ),
  7034 		/* translators: accessibility text */
  7480 		/* translators: Accessibility text. */
  7035 		__( '(opens in a new tab)' )
  7481 		__( '(opens in a new tab)' )
  7036 	);
  7482 	);
  7037 	echo '</p>';
  7483 	echo '</p>';
  7038 }
  7484 }
  7039 
  7485 
  7060 
  7506 
  7061 	if ( ! is_array( $dirsize ) ) {
  7507 	if ( ! is_array( $dirsize ) ) {
  7062 		$dirsize = array();
  7508 		$dirsize = array();
  7063 	}
  7509 	}
  7064 
  7510 
  7065 	// Exclude individual site directories from the total when checking the main site of a network
  7511 	// Exclude individual site directories from the total when checking the main site of a network,
  7066 	// as they are subdirectories and should not be counted.
  7512 	// as they are subdirectories and should not be counted.
  7067 	if ( is_multisite() && is_main_site() ) {
  7513 	if ( is_multisite() && is_main_site() ) {
  7068 		$dirsize[ $directory ]['size'] = recurse_dirsize( $directory, $directory . '/sites', $max_execution_time );
  7514 		$dirsize[ $directory ]['size'] = recurse_dirsize( $directory, $directory . '/sites', $max_execution_time );
  7069 	} else {
  7515 	} else {
  7070 		$dirsize[ $directory ]['size'] = recurse_dirsize( $directory, null, $max_execution_time );
  7516 		$dirsize[ $directory ]['size'] = recurse_dirsize( $directory, null, $max_execution_time );
  7082  *
  7528  *
  7083  * @since MU (3.0.0)
  7529  * @since MU (3.0.0)
  7084  * @since 4.3.0 $exclude parameter added.
  7530  * @since 4.3.0 $exclude parameter added.
  7085  * @since 5.2.0 $max_execution_time parameter added.
  7531  * @since 5.2.0 $max_execution_time parameter added.
  7086  *
  7532  *
  7087  * @param string $directory       Full path of a directory.
  7533  * @param string       $directory          Full path of a directory.
  7088  * @param string|array $exclude   Optional. Full path of a subdirectory to exclude from the total, or array of paths.
  7534  * @param string|array $exclude            Optional. Full path of a subdirectory to exclude from the total,
  7089  *                                Expected without trailing slash(es).
  7535  *                                         or array of paths. Expected without trailing slash(es).
  7090  * @param int $max_execution_time Maximum time to run before giving up. In seconds.
  7536  * @param int          $max_execution_time Maximum time to run before giving up. In seconds. The timeout is global
  7091  *                                The timeout is global and is measured from the moment WordPress started to load.
  7537  *                                         and is measured from the moment WordPress started to load.
  7092  * @return int|false|null Size in bytes if a valid directory. False if not. Null if timeout.
  7538  * @return int|false|null Size in bytes if a valid directory. False if not. Null if timeout.
  7093  */
  7539  */
  7094 function recurse_dirsize( $directory, $exclude = null, $max_execution_time = null ) {
  7540 function recurse_dirsize( $directory, $exclude = null, $max_execution_time = null ) {
  7095 	$size = 0;
  7541 	$size = 0;
  7096 
  7542 
  7105 		( is_array( $exclude ) && in_array( $directory, $exclude, true ) )
  7551 		( is_array( $exclude ) && in_array( $directory, $exclude, true ) )
  7106 	) {
  7552 	) {
  7107 		return false;
  7553 		return false;
  7108 	}
  7554 	}
  7109 
  7555 
  7110 	if ( $max_execution_time === null ) {
  7556 	if ( null === $max_execution_time ) {
  7111 		// Keep the previous behavior but attempt to prevent fatal errors from timeout if possible.
  7557 		// Keep the previous behavior but attempt to prevent fatal errors from timeout if possible.
  7112 		if ( function_exists( 'ini_get' ) ) {
  7558 		if ( function_exists( 'ini_get' ) ) {
  7113 			$max_execution_time = ini_get( 'max_execution_time' );
  7559 			$max_execution_time = ini_get( 'max_execution_time' );
  7114 		} else {
  7560 		} else {
  7115 			// Disable...
  7561 			// Disable...
  7120 		if ( $max_execution_time > 10 ) {
  7566 		if ( $max_execution_time > 10 ) {
  7121 			$max_execution_time -= 1;
  7567 			$max_execution_time -= 1;
  7122 		}
  7568 		}
  7123 	}
  7569 	}
  7124 
  7570 
  7125 	if ( $handle = opendir( $directory ) ) {
  7571 	$handle = opendir( $directory );
       
  7572 	if ( $handle ) {
  7126 		while ( ( $file = readdir( $handle ) ) !== false ) {
  7573 		while ( ( $file = readdir( $handle ) ) !== false ) {
  7127 			$path = $directory . '/' . $file;
  7574 			$path = $directory . '/' . $file;
  7128 			if ( $file != '.' && $file != '..' ) {
  7575 			if ( '.' !== $file && '..' !== $file ) {
  7129 				if ( is_file( $path ) ) {
  7576 				if ( is_file( $path ) ) {
  7130 					$size += filesize( $path );
  7577 					$size += filesize( $path );
  7131 				} elseif ( is_dir( $path ) ) {
  7578 				} elseif ( is_dir( $path ) ) {
  7132 					$handlesize = recurse_dirsize( $path, $exclude, $max_execution_time );
  7579 					$handlesize = recurse_dirsize( $path, $exclude, $max_execution_time );
  7133 					if ( $handlesize > 0 ) {
  7580 					if ( $handlesize > 0 ) {
  7146 	}
  7593 	}
  7147 	return $size;
  7594 	return $size;
  7148 }
  7595 }
  7149 
  7596 
  7150 /**
  7597 /**
  7151 * Checks compatibility with the current WordPress version.
  7598  * Checks compatibility with the current WordPress version.
  7152 *
  7599  *
  7153 * @since 5.2.0
  7600  * @since 5.2.0
  7154 *
  7601  *
  7155 * @param string $required Minimum required WordPress version.
  7602  * @param string $required Minimum required WordPress version.
  7156 * @return bool True if required version is compatible or empty, false if not.
  7603  * @return bool True if required version is compatible or empty, false if not.
  7157 */
  7604  */
  7158 function is_wp_version_compatible( $required ) {
  7605 function is_wp_version_compatible( $required ) {
  7159 	return empty( $required ) || version_compare( get_bloginfo( 'version' ), $required, '>=' );
  7606 	return empty( $required ) || version_compare( get_bloginfo( 'version' ), $required, '>=' );
  7160 }
  7607 }
  7161 
  7608 
  7162 /**
  7609 /**
  7168  * @return bool True if required version is compatible or empty, false if not.
  7615  * @return bool True if required version is compatible or empty, false if not.
  7169  */
  7616  */
  7170 function is_php_version_compatible( $required ) {
  7617 function is_php_version_compatible( $required ) {
  7171 	return empty( $required ) || version_compare( phpversion(), $required, '>=' );
  7618 	return empty( $required ) || version_compare( phpversion(), $required, '>=' );
  7172 }
  7619 }
       
  7620 
       
  7621 /**
       
  7622  * Check if two numbers are nearly the same.
       
  7623  *
       
  7624  * This is similar to using `round()` but the precision is more fine-grained.
       
  7625  *
       
  7626  * @since 5.3.0
       
  7627  *
       
  7628  * @param int|float $expected  The expected value.
       
  7629  * @param int|float $actual    The actual number.
       
  7630  * @param int|float $precision The allowed variation.
       
  7631  * @return bool Whether the numbers match whithin the specified precision.
       
  7632  */
       
  7633 function wp_fuzzy_number_match( $expected, $actual, $precision = 1 ) {
       
  7634 	return abs( (float) $expected - (float) $actual ) <= $precision;
       
  7635 }