wp/wp-includes/functions.php
changeset 9 177826044cd9
parent 7 cf61fcea0001
child 13 d255fe9cd479
equal deleted inserted replaced
8:c7c34916027a 9:177826044cd9
    22  * @param string $date      Date string to convert.
    22  * @param string $date      Date string to convert.
    23  * @param bool   $translate Whether the return date should be translated. Default true.
    23  * @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.
    24  * @return string|int|bool Formatted date string or Unix timestamp. False if $date is empty.
    25  */
    25  */
    26 function mysql2date( $format, $date, $translate = true ) {
    26 function mysql2date( $format, $date, $translate = true ) {
    27 	if ( empty( $date ) )
    27 	if ( empty( $date ) ) {
    28 		return false;
    28 		return false;
    29 
    29 	}
    30 	if ( 'G' == $format )
    30 
       
    31 	if ( 'G' == $format ) {
    31 		return strtotime( $date . ' +0000' );
    32 		return strtotime( $date . ' +0000' );
       
    33 	}
    32 
    34 
    33 	$i = strtotime( $date );
    35 	$i = strtotime( $date );
    34 
    36 
    35 	if ( 'U' == $format )
    37 	if ( 'U' == $format ) {
    36 		return $i;
    38 		return $i;
    37 
    39 	}
    38 	if ( $translate )
    40 
       
    41 	if ( $translate ) {
    39 		return date_i18n( $format, $i );
    42 		return date_i18n( $format, $i );
    40 	else
    43 	} else {
    41 		return date( $format, $i );
    44 		return date( $format, $i );
       
    45 	}
    42 }
    46 }
    43 
    47 
    44 /**
    48 /**
    45  * Retrieve the current time based on specified type.
    49  * Retrieve the current time based on specified type.
    46  *
    50  *
    63 		case 'mysql':
    67 		case 'mysql':
    64 			return ( $gmt ) ? gmdate( 'Y-m-d H:i:s' ) : gmdate( 'Y-m-d H:i:s', ( time() + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ) ) );
    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 ) ) );
    65 		case 'timestamp':
    69 		case 'timestamp':
    66 			return ( $gmt ) ? time() : time() + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS );
    70 			return ( $gmt ) ? time() : time() + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS );
    67 		default:
    71 		default:
    68 			return ( $gmt ) ? date( $type ) : date( $type, time() + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ) );
    72 			return ( $gmt ) ? gmdate( $type ) : gmdate( $type, time() + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ) );
    69 	}
    73 	}
    70 }
    74 }
    71 
    75 
    72 /**
    76 /**
    73  * Retrieve the date in localized format, based on timestamp.
    77  * Retrieve the date in localized format, based on a sum of Unix timestamp and
       
    78  * timezone offset in seconds.
    74  *
    79  *
    75  * If the locale specifies the locale month and weekday, then the locale will
    80  * If the locale specifies the locale month and weekday, then the locale will
    76  * take over the format for the date. If it isn't, then the date format string
    81  * take over the format for the date. If it isn't, then the date format string
    77  * will be used instead.
    82  * will be used instead.
    78  *
    83  *
    79  * @since 0.71
    84  * @since 0.71
    80  *
    85  *
    81  * @global WP_Locale $wp_locale
    86  * @global WP_Locale $wp_locale
    82  *
    87  *
    83  * @param string   $dateformatstring Format to display the date.
    88  * @param string   $dateformatstring      Format to display the date.
    84  * @param bool|int $unixtimestamp    Optional. Unix timestamp. Default false.
    89  * @param int|bool $timestamp_with_offset Optional. A sum of Unix timestamp and timezone offset in seconds.
    85  * @param bool     $gmt              Optional. Whether to use GMT timezone. Default false.
    90  *                                        Default false.
       
    91  * @param bool     $gmt                   Optional. Whether to use GMT timezone. Only applies if timestamp is
       
    92  *                                        not provided. Default false.
    86  *
    93  *
    87  * @return string The date, translated if locale specifies it.
    94  * @return string The date, translated if locale specifies it.
    88  */
    95  */
    89 function date_i18n( $dateformatstring, $unixtimestamp = false, $gmt = false ) {
    96 function date_i18n( $dateformatstring, $timestamp_with_offset = false, $gmt = false ) {
    90 	global $wp_locale;
    97 	global $wp_locale;
    91 	$i = $unixtimestamp;
    98 	$i = $timestamp_with_offset;
    92 
    99 
    93 	if ( false === $i ) {
   100 	if ( false === $i ) {
    94 		$i = current_time( 'timestamp', $gmt );
   101 		$i = current_time( 'timestamp', $gmt );
    95 	}
   102 	}
    96 
   103 
    98 	 * Store original value for language with untypical grammars.
   105 	 * Store original value for language with untypical grammars.
    99 	 * See https://core.trac.wordpress.org/ticket/9396
   106 	 * See https://core.trac.wordpress.org/ticket/9396
   100 	 */
   107 	 */
   101 	$req_format = $dateformatstring;
   108 	$req_format = $dateformatstring;
   102 
   109 
   103 	if ( ( !empty( $wp_locale->month ) ) && ( !empty( $wp_locale->weekday ) ) ) {
   110 	$dateformatstring = preg_replace( '/(?<!\\\\)c/', DATE_W3C, $dateformatstring );
   104 		$datemonth = $wp_locale->get_month( date( 'm', $i ) );
   111 	$dateformatstring = preg_replace( '/(?<!\\\\)r/', DATE_RFC2822, $dateformatstring );
   105 		$datemonth_abbrev = $wp_locale->get_month_abbrev( $datemonth );
   112 
   106 		$dateweekday = $wp_locale->get_weekday( date( 'w', $i ) );
   113 	if ( ( ! empty( $wp_locale->month ) ) && ( ! empty( $wp_locale->weekday ) ) ) {
   107 		$dateweekday_abbrev = $wp_locale->get_weekday_abbrev( $dateweekday );
   114 		$datemonth            = $wp_locale->get_month( date( 'm', $i ) );
   108 		$datemeridiem = $wp_locale->get_meridiem( date( 'a', $i ) );
   115 		$datemonth_abbrev     = $wp_locale->get_month_abbrev( $datemonth );
       
   116 		$dateweekday          = $wp_locale->get_weekday( date( 'w', $i ) );
       
   117 		$dateweekday_abbrev   = $wp_locale->get_weekday_abbrev( $dateweekday );
       
   118 		$datemeridiem         = $wp_locale->get_meridiem( date( 'a', $i ) );
   109 		$datemeridiem_capital = $wp_locale->get_meridiem( date( 'A', $i ) );
   119 		$datemeridiem_capital = $wp_locale->get_meridiem( date( 'A', $i ) );
   110 		$dateformatstring = ' '.$dateformatstring;
   120 		$dateformatstring     = ' ' . $dateformatstring;
   111 		$dateformatstring = preg_replace( "/([^\\\])D/", "\\1" . backslashit( $dateweekday_abbrev ), $dateformatstring );
   121 		$dateformatstring     = preg_replace( '/([^\\\])D/', "\\1" . backslashit( $dateweekday_abbrev ), $dateformatstring );
   112 		$dateformatstring = preg_replace( "/([^\\\])F/", "\\1" . backslashit( $datemonth ), $dateformatstring );
   122 		$dateformatstring     = preg_replace( '/([^\\\])F/', "\\1" . backslashit( $datemonth ), $dateformatstring );
   113 		$dateformatstring = preg_replace( "/([^\\\])l/", "\\1" . backslashit( $dateweekday ), $dateformatstring );
   123 		$dateformatstring     = preg_replace( '/([^\\\])l/', "\\1" . backslashit( $dateweekday ), $dateformatstring );
   114 		$dateformatstring = preg_replace( "/([^\\\])M/", "\\1" . backslashit( $datemonth_abbrev ), $dateformatstring );
   124 		$dateformatstring     = preg_replace( '/([^\\\])M/', "\\1" . backslashit( $datemonth_abbrev ), $dateformatstring );
   115 		$dateformatstring = preg_replace( "/([^\\\])a/", "\\1" . backslashit( $datemeridiem ), $dateformatstring );
   125 		$dateformatstring     = preg_replace( '/([^\\\])a/', "\\1" . backslashit( $datemeridiem ), $dateformatstring );
   116 		$dateformatstring = preg_replace( "/([^\\\])A/", "\\1" . backslashit( $datemeridiem_capital ), $dateformatstring );
   126 		$dateformatstring     = preg_replace( '/([^\\\])A/', "\\1" . backslashit( $datemeridiem_capital ), $dateformatstring );
   117 
   127 
   118 		$dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) -1 );
   128 		$dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) - 1 );
   119 	}
   129 	}
   120 	$timezone_formats = array( 'P', 'I', 'O', 'T', 'Z', 'e' );
   130 	$timezone_formats    = array( 'P', 'I', 'O', 'T', 'Z', 'e' );
   121 	$timezone_formats_re = implode( '|', $timezone_formats );
   131 	$timezone_formats_re = implode( '|', $timezone_formats );
   122 	if ( preg_match( "/$timezone_formats_re/", $dateformatstring ) ) {
   132 	if ( preg_match( "/$timezone_formats_re/", $dateformatstring ) ) {
   123 		$timezone_string = get_option( 'timezone_string' );
   133 		$timezone_string = get_option( 'timezone_string' );
       
   134 		if ( false === $timestamp_with_offset && $gmt ) {
       
   135 			$timezone_string = 'UTC';
       
   136 		}
   124 		if ( $timezone_string ) {
   137 		if ( $timezone_string ) {
   125 			$timezone_object = timezone_open( $timezone_string );
   138 			$timezone_object = timezone_open( $timezone_string );
   126 			$date_object = date_create( null, $timezone_object );
   139 			$date_object     = date_create( null, $timezone_object );
   127 			foreach ( $timezone_formats as $timezone_format ) {
   140 			foreach ( $timezone_formats as $timezone_format ) {
   128 				if ( false !== strpos( $dateformatstring, $timezone_format ) ) {
   141 				if ( false !== strpos( $dateformatstring, $timezone_format ) ) {
   129 					$formatted = date_format( $date_object, $timezone_format );
   142 					$formatted        = date_format( $date_object, $timezone_format );
   130 					$dateformatstring = ' '.$dateformatstring;
   143 					$dateformatstring = ' ' . $dateformatstring;
   131 					$dateformatstring = preg_replace( "/([^\\\])$timezone_format/", "\\1" . backslashit( $formatted ), $dateformatstring );
   144 					$dateformatstring = preg_replace( "/([^\\\])$timezone_format/", "\\1" . backslashit( $formatted ), $dateformatstring );
   132 					$dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) -1 );
   145 					$dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) - 1 );
   133 				}
   146 				}
   134 			}
   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 			}
   135 		}
   178 		}
   136 	}
   179 	}
   137 	$j = @date( $dateformatstring, $i );
   180 	$j = @date( $dateformatstring, $i );
   138 
   181 
   139 	/**
   182 	/**
   141 	 *
   184 	 *
   142 	 * @since 2.8.0
   185 	 * @since 2.8.0
   143 	 *
   186 	 *
   144 	 * @param string $j          Formatted date string.
   187 	 * @param string $j          Formatted date string.
   145 	 * @param string $req_format Format to display the date.
   188 	 * @param string $req_format Format to display the date.
   146 	 * @param int    $i          Unix timestamp.
   189 	 * @param int    $i          A sum of Unix timestamp and timezone offset in seconds.
   147 	 * @param bool   $gmt        Whether to convert to GMT for time. Default false.
   190 	 * @param bool   $gmt        Whether to use GMT timezone. Only applies if timestamp was
       
   191 	 *                           not provided. Default false.
   148 	 */
   192 	 */
   149 	$j = apply_filters( 'date_i18n', $j, $req_format, $i, $gmt );
   193 	$j = apply_filters( 'date_i18n', $j, $req_format, $i, $gmt );
   150 	return $j;
   194 	return $j;
   151 }
   195 }
   152 
   196 
   225 
   269 
   226 	/**
   270 	/**
   227 	 * Filters the number formatted based on the locale.
   271 	 * Filters the number formatted based on the locale.
   228 	 *
   272 	 *
   229 	 * @since 2.8.0
   273 	 * @since 2.8.0
   230 	 * @since 4.9.0 The `$number` and `$decimals` arguments were added.
   274 	 * @since 4.9.0 The `$number` and `$decimals` parameters were added.
   231 	 *
   275 	 *
   232 	 * @param string $formatted Converted number in string format.
   276 	 * @param string $formatted Converted number in string format.
   233 	 * @param float  $number    The number to convert based on locale.
   277 	 * @param float  $number    The number to convert based on locale.
   234 	 * @param int    $decimals  Precision of the number of decimal places.
   278 	 * @param int    $decimals  Precision of the number of decimal places.
   235 	 */
   279 	 */
   277 
   321 
   278 	return false;
   322 	return false;
   279 }
   323 }
   280 
   324 
   281 /**
   325 /**
       
   326  * Convert a duration to human readable format.
       
   327  *
       
   328  * @since 5.1.0
       
   329  *
       
   330  * @param string $duration Duration will be in string format (HH:ii:ss) OR (ii:ss),
       
   331  *                         with a possible prepended negative sign (-).
       
   332  * @return string|false A human readable duration string, false on failure.
       
   333  */
       
   334 function human_readable_duration( $duration = '' ) {
       
   335 	if ( ( empty( $duration ) || ! is_string( $duration ) ) ) {
       
   336 		return false;
       
   337 	}
       
   338 
       
   339 	$duration = trim( $duration );
       
   340 
       
   341 	// Remove prepended negative sign.
       
   342 	if ( '-' === substr( $duration, 0, 1 ) ) {
       
   343 		$duration = substr( $duration, 1 );
       
   344 	}
       
   345 
       
   346 	// Extract duration parts.
       
   347 	$duration_parts = array_reverse( explode( ':', $duration ) );
       
   348 	$duration_count = count( $duration_parts );
       
   349 
       
   350 	$hour   = null;
       
   351 	$minute = null;
       
   352 	$second = null;
       
   353 
       
   354 	if ( 3 === $duration_count ) {
       
   355 		// Validate HH:ii:ss duration format.
       
   356 		if ( ! ( (bool) preg_match( '/^([0-9]+):([0-5]?[0-9]):([0-5]?[0-9])$/', $duration ) ) ) {
       
   357 			return false;
       
   358 		}
       
   359 		// Three parts: hours, minutes & seconds.
       
   360 		list( $second, $minute, $hour ) = $duration_parts;
       
   361 	} elseif ( 2 === $duration_count ) {
       
   362 		// Validate ii:ss duration format.
       
   363 		if ( ! ( (bool) preg_match( '/^([0-5]?[0-9]):([0-5]?[0-9])$/', $duration ) ) ) {
       
   364 			return false;
       
   365 		}
       
   366 		// Two parts: minutes & seconds.
       
   367 		list( $second, $minute ) = $duration_parts;
       
   368 	} else {
       
   369 		return false;
       
   370 	}
       
   371 
       
   372 	$human_readable_duration = array();
       
   373 
       
   374 	// Add the hour part to the string.
       
   375 	if ( is_numeric( $hour ) ) {
       
   376 		/* translators: Time duration in hour or hours. */
       
   377 		$human_readable_duration[] = sprintf( _n( '%s hour', '%s hours', $hour ), (int) $hour );
       
   378 	}
       
   379 
       
   380 	// Add the minute part to the string.
       
   381 	if ( is_numeric( $minute ) ) {
       
   382 		/* translators: Time duration in minute or minutes. */
       
   383 		$human_readable_duration[] = sprintf( _n( '%s minute', '%s minutes', $minute ), (int) $minute );
       
   384 	}
       
   385 
       
   386 	// Add the second part to the string.
       
   387 	if ( is_numeric( $second ) ) {
       
   388 		/* translators: Time duration in second or seconds. */
       
   389 		$human_readable_duration[] = sprintf( _n( '%s second', '%s seconds', $second ), (int) $second );
       
   390 	}
       
   391 
       
   392 	return implode( ', ', $human_readable_duration );
       
   393 }
       
   394 
       
   395 /**
   282  * Get the week start and end from the datetime or date string from MySQL.
   396  * Get the week start and end from the datetime or date string from MySQL.
   283  *
   397  *
   284  * @since 0.71
   398  * @since 0.71
   285  *
   399  *
   286  * @param string     $mysqlstring   Date or datetime field type from MySQL.
   400  * @param string     $mysqlstring   Date or datetime field type from MySQL.
   301 	$day = mktime( 0, 0, 0, $md, $mm, $my );
   415 	$day = mktime( 0, 0, 0, $md, $mm, $my );
   302 
   416 
   303 	// The day of the week from the timestamp.
   417 	// The day of the week from the timestamp.
   304 	$weekday = date( 'w', $day );
   418 	$weekday = date( 'w', $day );
   305 
   419 
   306 	if ( !is_numeric($start_of_week) )
   420 	if ( ! is_numeric( $start_of_week ) ) {
   307 		$start_of_week = get_option( 'start_of_week' );
   421 		$start_of_week = get_option( 'start_of_week' );
   308 
   422 	}
   309 	if ( $weekday < $start_of_week )
   423 
       
   424 	if ( $weekday < $start_of_week ) {
   310 		$weekday += 7;
   425 		$weekday += 7;
       
   426 	}
   311 
   427 
   312 	// The most recent week start day on or before $day.
   428 	// The most recent week start day on or before $day.
   313 	$start = $day - DAY_IN_SECONDS * ( $weekday - $start_of_week );
   429 	$start = $day - DAY_IN_SECONDS * ( $weekday - $start_of_week );
   314 
   430 
   315 	// $start + 1 week - 1 second.
   431 	// $start + 1 week - 1 second.
   324  *
   440  *
   325  * @param string $original Maybe unserialized original, if is needed.
   441  * @param string $original Maybe unserialized original, if is needed.
   326  * @return mixed Unserialized data can be any type.
   442  * @return mixed Unserialized data can be any type.
   327  */
   443  */
   328 function maybe_unserialize( $original ) {
   444 function maybe_unserialize( $original ) {
   329 	if ( is_serialized( $original ) ) // don't attempt to unserialize data that wasn't serialized going in
   445 	if ( is_serialized( $original ) ) { // don't attempt to unserialize data that wasn't serialized going in
   330 		return @unserialize( $original );
   446 		return @unserialize( $original );
       
   447 	}
   331 	return $original;
   448 	return $original;
   332 }
   449 }
   333 
   450 
   334 /**
   451 /**
   335  * Check value to find if it was serialized.
   452  * Check value to find if it was serialized.
   347 	// if it isn't a string, it isn't serialized.
   464 	// if it isn't a string, it isn't serialized.
   348 	if ( ! is_string( $data ) ) {
   465 	if ( ! is_string( $data ) ) {
   349 		return false;
   466 		return false;
   350 	}
   467 	}
   351 	$data = trim( $data );
   468 	$data = trim( $data );
   352  	if ( 'N;' == $data ) {
   469 	if ( 'N;' == $data ) {
   353 		return true;
   470 		return true;
   354 	}
   471 	}
   355 	if ( strlen( $data ) < 4 ) {
   472 	if ( strlen( $data ) < 4 ) {
   356 		return false;
   473 		return false;
   357 	}
   474 	}
   365 		}
   482 		}
   366 	} else {
   483 	} else {
   367 		$semicolon = strpos( $data, ';' );
   484 		$semicolon = strpos( $data, ';' );
   368 		$brace     = strpos( $data, '}' );
   485 		$brace     = strpos( $data, '}' );
   369 		// Either ; or } must exist.
   486 		// Either ; or } must exist.
   370 		if ( false === $semicolon && false === $brace )
   487 		if ( false === $semicolon && false === $brace ) {
   371 			return false;
   488 			return false;
       
   489 		}
   372 		// But neither must be in the first X characters.
   490 		// But neither must be in the first X characters.
   373 		if ( false !== $semicolon && $semicolon < 3 )
   491 		if ( false !== $semicolon && $semicolon < 3 ) {
   374 			return false;
   492 			return false;
   375 		if ( false !== $brace && $brace < 4 )
   493 		}
       
   494 		if ( false !== $brace && $brace < 4 ) {
   376 			return false;
   495 			return false;
       
   496 		}
   377 	}
   497 	}
   378 	$token = $data[0];
   498 	$token = $data[0];
   379 	switch ( $token ) {
   499 	switch ( $token ) {
   380 		case 's' :
   500 		case 's':
   381 			if ( $strict ) {
   501 			if ( $strict ) {
   382 				if ( '"' !== substr( $data, -2, 1 ) ) {
   502 				if ( '"' !== substr( $data, -2, 1 ) ) {
   383 					return false;
   503 					return false;
   384 				}
   504 				}
   385 			} elseif ( false === strpos( $data, '"' ) ) {
   505 			} elseif ( false === strpos( $data, '"' ) ) {
   386 				return false;
   506 				return false;
   387 			}
   507 			}
   388 			// or else fall through
   508 			// or else fall through
   389 		case 'a' :
   509 		case 'a':
   390 		case 'O' :
   510 		case 'O':
   391 			return (bool) preg_match( "/^{$token}:[0-9]+:/s", $data );
   511 			return (bool) preg_match( "/^{$token}:[0-9]+:/s", $data );
   392 		case 'b' :
   512 		case 'b':
   393 		case 'i' :
   513 		case 'i':
   394 		case 'd' :
   514 		case 'd':
   395 			$end = $strict ? '$' : '';
   515 			$end = $strict ? '$' : '';
   396 			return (bool) preg_match( "/^{$token}:[0-9.E-]+;$end/", $data );
   516 			return (bool) preg_match( "/^{$token}:[0-9.E-]+;$end/", $data );
   397 	}
   517 	}
   398 	return false;
   518 	return false;
   399 }
   519 }
   434  *
   554  *
   435  * @param string|array|object $data Data that might be serialized.
   555  * @param string|array|object $data Data that might be serialized.
   436  * @return mixed A scalar data
   556  * @return mixed A scalar data
   437  */
   557  */
   438 function maybe_serialize( $data ) {
   558 function maybe_serialize( $data ) {
   439 	if ( is_array( $data ) || is_object( $data ) )
   559 	if ( is_array( $data ) || is_object( $data ) ) {
   440 		return serialize( $data );
   560 		return serialize( $data );
       
   561 	}
   441 
   562 
   442 	// Double serialization is required for backward compatibility.
   563 	// Double serialization is required for backward compatibility.
   443 	// See https://core.trac.wordpress.org/ticket/12930
   564 	// See https://core.trac.wordpress.org/ticket/12930
   444 	// Also the world will end. See WP 3.6.1.
   565 	// Also the world will end. See WP 3.6.1.
   445 	if ( is_serialized( $data, false ) )
   566 	if ( is_serialized( $data, false ) ) {
   446 		return serialize( $data );
   567 		return serialize( $data );
       
   568 	}
   447 
   569 
   448 	return $data;
   570 	return $data;
   449 }
   571 }
   450 
   572 
   451 /**
   573 /**
   520  * @return array URLs found in passed string.
   642  * @return array URLs found in passed string.
   521  */
   643  */
   522 function wp_extract_urls( $content ) {
   644 function wp_extract_urls( $content ) {
   523 	preg_match_all(
   645 	preg_match_all(
   524 		"#([\"']?)("
   646 		"#([\"']?)("
   525 			. "(?:([\w-]+:)?//?)"
   647 			. '(?:([\w-]+:)?//?)'
   526 			. "[^\s()<>]+"
   648 			. '[^\s()<>]+'
   527 			. "[.]"
   649 			. '[.]'
   528 			. "(?:"
   650 			. '(?:'
   529 				. "\([\w\d]+\)|"
   651 				. '\([\w\d]+\)|'
   530 				. "(?:"
   652 				. '(?:'
   531 					. "[^`!()\[\]{};:'\".,<>«»“”‘’\s]|"
   653 					. "[^`!()\[\]{};:'\".,<>«»“”‘’\s]|"
   532 					. "(?:[:]\d+)?/?"
   654 					. '(?:[:]\d+)?/?'
   533 				. ")+"
   655 				. ')+'
   534 			. ")"
   656 			. ')'
   535 		. ")\\1#",
   657 		. ")\\1#",
   536 		$content,
   658 		$content,
   537 		$post_links
   659 		$post_links
   538 	);
   660 	);
   539 
   661 
   568 
   690 
   569 	$post_links_temp = wp_extract_urls( $content );
   691 	$post_links_temp = wp_extract_urls( $content );
   570 
   692 
   571 	foreach ( $pung as $link_test ) {
   693 	foreach ( $pung as $link_test ) {
   572 		if ( ! in_array( $link_test, $post_links_temp ) ) { // link no longer in post
   694 		if ( ! in_array( $link_test, $post_links_temp ) ) { // link no longer in post
   573 			$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 ) . '%') );
   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 ) . '%' ) );
   574 			foreach ( $mids as $mid )
   696 			foreach ( $mids as $mid ) {
   575 				delete_metadata_by_mid( 'post', $mid );
   697 				delete_metadata_by_mid( 'post', $mid );
       
   698 			}
   576 		}
   699 		}
   577 	}
   700 	}
   578 
   701 
   579 	foreach ( (array) $post_links_temp as $link_test ) {
   702 	foreach ( (array) $post_links_temp as $link_test ) {
   580 		if ( !in_array( $link_test, $pung ) ) { // If we haven't pung it already
   703 		if ( ! in_array( $link_test, $pung ) ) { // If we haven't pung it already
   581 			$test = @parse_url( $link_test );
   704 			$test = @parse_url( $link_test );
   582 			if ( false === $test )
   705 			if ( false === $test ) {
   583 				continue;
   706 				continue;
   584 			if ( isset( $test['query'] ) )
   707 			}
       
   708 			if ( isset( $test['query'] ) ) {
   585 				$post_links[] = $link_test;
   709 				$post_links[] = $link_test;
   586 			elseif ( isset($test['path']) && ( $test['path'] != '/' ) &&  ($test['path'] != '' ) )
   710 			} elseif ( isset( $test['path'] ) && ( $test['path'] != '/' ) && ( $test['path'] != '' ) ) {
   587 				$post_links[] = $link_test;
   711 				$post_links[] = $link_test;
       
   712 			}
   588 		}
   713 		}
   589 	}
   714 	}
   590 
   715 
   591 	/**
   716 	/**
   592 	 * Filters the list of enclosure links before querying the database.
   717 	 * Filters the list of enclosure links before querying the database.
   600 	 * @param int   $post_ID    Post ID.
   725 	 * @param int   $post_ID    Post ID.
   601 	 */
   726 	 */
   602 	$post_links = apply_filters( 'enclosure_links', $post_links, $post_ID );
   727 	$post_links = apply_filters( 'enclosure_links', $post_links, $post_ID );
   603 
   728 
   604 	foreach ( (array) $post_links as $url ) {
   729 	foreach ( (array) $post_links as $url ) {
   605 		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 ) . '%' ) ) ) {
   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 ) . '%' ) ) ) {
   606 
   731 
   607 			if ( $headers = wp_get_http_headers( $url) ) {
   732 			if ( $headers = wp_get_http_headers( $url ) ) {
   608 				$len = isset( $headers['content-length'] ) ? (int) $headers['content-length'] : 0;
   733 				$len           = isset( $headers['content-length'] ) ? (int) $headers['content-length'] : 0;
   609 				$type = isset( $headers['content-type'] ) ? $headers['content-type'] : '';
   734 				$type          = isset( $headers['content-type'] ) ? $headers['content-type'] : '';
   610 				$allowed_types = array( 'video', 'audio' );
   735 				$allowed_types = array( 'video', 'audio' );
   611 
   736 
   612 				// Check to see if we can figure out the mime type from
   737 				// Check to see if we can figure out the mime type from
   613 				// the extension
   738 				// the extension
   614 				$url_parts = @parse_url( $url );
   739 				$url_parts = @parse_url( $url );
   615 				if ( false !== $url_parts ) {
   740 				if ( false !== $url_parts ) {
   616 					$extension = pathinfo( $url_parts['path'], PATHINFO_EXTENSION );
   741 					$extension = pathinfo( $url_parts['path'], PATHINFO_EXTENSION );
   617 					if ( !empty( $extension ) ) {
   742 					if ( ! empty( $extension ) ) {
   618 						foreach ( wp_get_mime_types() as $exts => $mime ) {
   743 						foreach ( wp_get_mime_types() as $exts => $mime ) {
   619 							if ( preg_match( '!^(' . $exts . ')$!i', $extension ) ) {
   744 							if ( preg_match( '!^(' . $exts . ')$!i', $extension ) ) {
   620 								$type = $mime;
   745 								$type = $mime;
   621 								break;
   746 								break;
   622 							}
   747 							}
   623 						}
   748 						}
   624 					}
   749 					}
   625 				}
   750 				}
   626 
   751 
   627 				if ( in_array( substr( $type, 0, strpos( $type, "/" ) ), $allowed_types ) ) {
   752 				if ( in_array( substr( $type, 0, strpos( $type, '/' ) ), $allowed_types ) ) {
   628 					add_post_meta( $post_ID, 'enclosure', "$url\n$len\n$mime\n" );
   753 					add_post_meta( $post_ID, 'enclosure', "$url\n$len\n$mime\n" );
   629 				}
   754 				}
   630 			}
   755 			}
   631 		}
   756 		}
   632 	}
   757 	}
   640  * @param string $url        URL to retrieve HTTP headers from.
   765  * @param string $url        URL to retrieve HTTP headers from.
   641  * @param bool   $deprecated Not Used.
   766  * @param bool   $deprecated Not Used.
   642  * @return bool|string False on failure, headers on success.
   767  * @return bool|string False on failure, headers on success.
   643  */
   768  */
   644 function wp_get_http_headers( $url, $deprecated = false ) {
   769 function wp_get_http_headers( $url, $deprecated = false ) {
   645 	if ( !empty( $deprecated ) )
   770 	if ( ! empty( $deprecated ) ) {
   646 		_deprecated_argument( __FUNCTION__, '2.7.0' );
   771 		_deprecated_argument( __FUNCTION__, '2.7.0' );
       
   772 	}
   647 
   773 
   648 	$response = wp_safe_remote_head( $url );
   774 	$response = wp_safe_remote_head( $url );
   649 
   775 
   650 	if ( is_wp_error( $response ) )
   776 	if ( is_wp_error( $response ) ) {
   651 		return false;
   777 		return false;
       
   778 	}
   652 
   779 
   653 	return wp_remote_retrieve_headers( $response );
   780 	return wp_remote_retrieve_headers( $response );
   654 }
   781 }
   655 
   782 
   656 /**
   783 /**
   657  * Whether the publish date of the current post in the loop is different from the
   784  * Determines whether the publish date of the current post in the loop is different
   658  * publish date of the previous post in the loop.
   785  * from the publish date of the previous post in the loop.
       
   786  *
       
   787  * For more information on this and similar theme functions, check out
       
   788  * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
       
   789  * Conditional Tags} article in the Theme Developer Handbook.
   659  *
   790  *
   660  * @since 0.71
   791  * @since 0.71
   661  *
   792  *
   662  * @global string $currentday  The day of the current post in the loop.
   793  * @global string $currentday  The day of the current post in the loop.
   663  * @global string $previousday The day of the previous post in the loop.
   794  * @global string $previousday The day of the previous post in the loop.
   664  *
   795  *
   665  * @return int 1 when new day, 0 if not a new day.
   796  * @return int 1 when new day, 0 if not a new day.
   666  */
   797  */
   667 function is_new_day() {
   798 function is_new_day() {
   668 	global $currentday, $previousday;
   799 	global $currentday, $previousday;
   669 	if ( $currentday != $previousday )
   800 	if ( $currentday != $previousday ) {
   670 		return 1;
   801 		return 1;
   671 	else
   802 	} else {
   672 		return 0;
   803 		return 0;
       
   804 	}
   673 }
   805 }
   674 
   806 
   675 /**
   807 /**
   676  * Build URL query based on an associative and, or indexed array.
   808  * Build URL query based on an associative and, or indexed array.
   677  *
   809  *
   680  *
   812  *
   681  * @since 2.3.0
   813  * @since 2.3.0
   682  *
   814  *
   683  * @see _http_build_query() Used to build the query
   815  * @see _http_build_query() Used to build the query
   684  * @link https://secure.php.net/manual/en/function.http-build-query.php for more on what
   816  * @link https://secure.php.net/manual/en/function.http-build-query.php for more on what
   685  *		 http_build_query() does.
   817  *       http_build_query() does.
   686  *
   818  *
   687  * @param array $data URL-encode key/value pairs.
   819  * @param array $data URL-encode key/value pairs.
   688  * @return string URL-encoded string.
   820  * @return string URL-encoded string.
   689  */
   821  */
   690 function build_query( $data ) {
   822 function build_query( $data ) {
   711  */
   843  */
   712 function _http_build_query( $data, $prefix = null, $sep = null, $key = '', $urlencode = true ) {
   844 function _http_build_query( $data, $prefix = null, $sep = null, $key = '', $urlencode = true ) {
   713 	$ret = array();
   845 	$ret = array();
   714 
   846 
   715 	foreach ( (array) $data as $k => $v ) {
   847 	foreach ( (array) $data as $k => $v ) {
   716 		if ( $urlencode)
   848 		if ( $urlencode ) {
   717 			$k = urlencode($k);
   849 			$k = urlencode( $k );
   718 		if ( is_int($k) && $prefix != null )
   850 		}
   719 			$k = $prefix.$k;
   851 		if ( is_int( $k ) && $prefix != null ) {
   720 		if ( !empty($key) )
   852 			$k = $prefix . $k;
       
   853 		}
       
   854 		if ( ! empty( $key ) ) {
   721 			$k = $key . '%5B' . $k . '%5D';
   855 			$k = $key . '%5B' . $k . '%5D';
   722 		if ( $v === null )
   856 		}
       
   857 		if ( $v === null ) {
   723 			continue;
   858 			continue;
   724 		elseif ( $v === false )
   859 		} elseif ( $v === false ) {
   725 			$v = '0';
   860 			$v = '0';
   726 
   861 		}
   727 		if ( is_array($v) || is_object($v) )
   862 
   728 			array_push($ret,_http_build_query($v, '', $sep, $k, $urlencode));
   863 		if ( is_array( $v ) || is_object( $v ) ) {
   729 		elseif ( $urlencode )
   864 			array_push( $ret, _http_build_query( $v, '', $sep, $k, $urlencode ) );
   730 			array_push($ret, $k.'='.urlencode($v));
   865 		} elseif ( $urlencode ) {
   731 		else
   866 			array_push( $ret, $k . '=' . urlencode( $v ) );
   732 			array_push($ret, $k.'='.$v);
   867 		} else {
   733 	}
   868 			array_push( $ret, $k . '=' . $v );
   734 
   869 		}
   735 	if ( null === $sep )
   870 	}
   736 		$sep = ini_get('arg_separator.output');
   871 
   737 
   872 	if ( null === $sep ) {
   738 	return implode($sep, $ret);
   873 		$sep = ini_get( 'arg_separator.output' );
       
   874 	}
       
   875 
       
   876 	return implode( $sep, $ret );
   739 }
   877 }
   740 
   878 
   741 /**
   879 /**
   742  * Retrieves a modified URL query string.
   880  * Retrieves a modified URL query string.
   743  *
   881  *
   774  * @return string New URL query string (unescaped).
   912  * @return string New URL query string (unescaped).
   775  */
   913  */
   776 function add_query_arg() {
   914 function add_query_arg() {
   777 	$args = func_get_args();
   915 	$args = func_get_args();
   778 	if ( is_array( $args[0] ) ) {
   916 	if ( is_array( $args[0] ) ) {
   779 		if ( count( $args ) < 2 || false === $args[1] )
   917 		if ( count( $args ) < 2 || false === $args[1] ) {
   780 			$uri = $_SERVER['REQUEST_URI'];
   918 			$uri = $_SERVER['REQUEST_URI'];
   781 		else
   919 		} else {
   782 			$uri = $args[1];
   920 			$uri = $args[1];
       
   921 		}
   783 	} else {
   922 	} else {
   784 		if ( count( $args ) < 3 || false === $args[2] )
   923 		if ( count( $args ) < 3 || false === $args[2] ) {
   785 			$uri = $_SERVER['REQUEST_URI'];
   924 			$uri = $_SERVER['REQUEST_URI'];
   786 		else
   925 		} else {
   787 			$uri = $args[2];
   926 			$uri = $args[2];
   788 	}
   927 		}
   789 
   928 	}
   790 	if ( $frag = strstr( $uri, '#' ) )
   929 
       
   930 	if ( $frag = strstr( $uri, '#' ) ) {
   791 		$uri = substr( $uri, 0, -strlen( $frag ) );
   931 		$uri = substr( $uri, 0, -strlen( $frag ) );
   792 	else
   932 	} else {
   793 		$frag = '';
   933 		$frag = '';
       
   934 	}
   794 
   935 
   795 	if ( 0 === stripos( $uri, 'http://' ) ) {
   936 	if ( 0 === stripos( $uri, 'http://' ) ) {
   796 		$protocol = 'http://';
   937 		$protocol = 'http://';
   797 		$uri = substr( $uri, 7 );
   938 		$uri      = substr( $uri, 7 );
   798 	} elseif ( 0 === stripos( $uri, 'https://' ) ) {
   939 	} elseif ( 0 === stripos( $uri, 'https://' ) ) {
   799 		$protocol = 'https://';
   940 		$protocol = 'https://';
   800 		$uri = substr( $uri, 8 );
   941 		$uri      = substr( $uri, 8 );
   801 	} else {
   942 	} else {
   802 		$protocol = '';
   943 		$protocol = '';
   803 	}
   944 	}
   804 
   945 
   805 	if ( strpos( $uri, '?' ) !== false ) {
   946 	if ( strpos( $uri, '?' ) !== false ) {
   806 		list( $base, $query ) = explode( '?', $uri, 2 );
   947 		list( $base, $query ) = explode( '?', $uri, 2 );
   807 		$base .= '?';
   948 		$base                .= '?';
   808 	} elseif ( $protocol || strpos( $uri, '=' ) === false ) {
   949 	} elseif ( $protocol || strpos( $uri, '=' ) === false ) {
   809 		$base = $uri . '?';
   950 		$base  = $uri . '?';
   810 		$query = '';
   951 		$query = '';
   811 	} else {
   952 	} else {
   812 		$base = '';
   953 		$base  = '';
   813 		$query = $uri;
   954 		$query = $uri;
   814 	}
   955 	}
   815 
   956 
   816 	wp_parse_str( $query, $qs );
   957 	wp_parse_str( $query, $qs );
   817 	$qs = urlencode_deep( $qs ); // this re-URL-encodes things that were already in the query string
   958 	$qs = urlencode_deep( $qs ); // this re-URL-encodes things that were already in the query string
   822 	} else {
   963 	} else {
   823 		$qs[ $args[0] ] = $args[1];
   964 		$qs[ $args[0] ] = $args[1];
   824 	}
   965 	}
   825 
   966 
   826 	foreach ( $qs as $k => $v ) {
   967 	foreach ( $qs as $k => $v ) {
   827 		if ( $v === false )
   968 		if ( $v === false ) {
   828 			unset( $qs[$k] );
   969 			unset( $qs[ $k ] );
       
   970 		}
   829 	}
   971 	}
   830 
   972 
   831 	$ret = build_query( $qs );
   973 	$ret = build_query( $qs );
   832 	$ret = trim( $ret, '?' );
   974 	$ret = trim( $ret, '?' );
   833 	$ret = preg_replace( '#=(&|$)#', '$1', $ret );
   975 	$ret = preg_replace( '#=(&|$)#', '$1', $ret );
   845  * @param bool|string  $query Optional. When false uses the current URL. Default false.
   987  * @param bool|string  $query Optional. When false uses the current URL. Default false.
   846  * @return string New URL query string.
   988  * @return string New URL query string.
   847  */
   989  */
   848 function remove_query_arg( $key, $query = false ) {
   990 function remove_query_arg( $key, $query = false ) {
   849 	if ( is_array( $key ) ) { // removing multiple keys
   991 	if ( is_array( $key ) ) { // removing multiple keys
   850 		foreach ( $key as $k )
   992 		foreach ( $key as $k ) {
   851 			$query = add_query_arg( $k, false, $query );
   993 			$query = add_query_arg( $k, false, $query );
       
   994 		}
   852 		return $query;
   995 		return $query;
   853 	}
   996 	}
   854 	return add_query_arg( $key, false, $query );
   997 	return add_query_arg( $key, false, $query );
   855 }
   998 }
   856 
   999 
   907  * @return array Sanitized $array.
  1050  * @return array Sanitized $array.
   908  */
  1051  */
   909 function add_magic_quotes( $array ) {
  1052 function add_magic_quotes( $array ) {
   910 	foreach ( (array) $array as $k => $v ) {
  1053 	foreach ( (array) $array as $k => $v ) {
   911 		if ( is_array( $v ) ) {
  1054 		if ( is_array( $v ) ) {
   912 			$array[$k] = add_magic_quotes( $v );
  1055 			$array[ $k ] = add_magic_quotes( $v );
   913 		} else {
  1056 		} else {
   914 			$array[$k] = addslashes( $v );
  1057 			$array[ $k ] = addslashes( $v );
   915 		}
  1058 		}
   916 	}
  1059 	}
   917 	return $array;
  1060 	return $array;
   918 }
  1061 }
   919 
  1062 
   928  * @return false|string HTTP content. False on failure.
  1071  * @return false|string HTTP content. False on failure.
   929  */
  1072  */
   930 function wp_remote_fopen( $uri ) {
  1073 function wp_remote_fopen( $uri ) {
   931 	$parsed_url = @parse_url( $uri );
  1074 	$parsed_url = @parse_url( $uri );
   932 
  1075 
   933 	if ( !$parsed_url || !is_array( $parsed_url ) )
  1076 	if ( ! $parsed_url || ! is_array( $parsed_url ) ) {
   934 		return false;
  1077 		return false;
   935 
  1078 	}
   936 	$options = array();
  1079 
       
  1080 	$options            = array();
   937 	$options['timeout'] = 10;
  1081 	$options['timeout'] = 10;
   938 
  1082 
   939 	$response = wp_safe_remote_get( $uri, $options );
  1083 	$response = wp_safe_remote_get( $uri, $options );
   940 
  1084 
   941 	if ( is_wp_error( $response ) )
  1085 	if ( is_wp_error( $response ) ) {
   942 		return false;
  1086 		return false;
       
  1087 	}
   943 
  1088 
   944 	return wp_remote_retrieve_body( $response );
  1089 	return wp_remote_retrieve_body( $response );
   945 }
  1090 }
   946 
  1091 
   947 /**
  1092 /**
   957  */
  1102  */
   958 function wp( $query_vars = '' ) {
  1103 function wp( $query_vars = '' ) {
   959 	global $wp, $wp_query, $wp_the_query;
  1104 	global $wp, $wp_query, $wp_the_query;
   960 	$wp->main( $query_vars );
  1105 	$wp->main( $query_vars );
   961 
  1106 
   962 	if ( !isset($wp_the_query) )
  1107 	if ( ! isset( $wp_the_query ) ) {
   963 		$wp_the_query = $wp_query;
  1108 		$wp_the_query = $wp_query;
       
  1109 	}
   964 }
  1110 }
   965 
  1111 
   966 /**
  1112 /**
   967  * Retrieve the description for the HTTP status.
  1113  * Retrieve the description for the HTTP status.
   968  *
  1114  *
   969  * @since 2.3.0
  1115  * @since 2.3.0
       
  1116  * @since 3.9.0 Added status codes 418, 428, 429, 431, and 511.
       
  1117  * @since 4.5.0 Added status codes 308, 421, and 451.
       
  1118  * @since 5.1.0 Added status code 103.
   970  *
  1119  *
   971  * @global array $wp_header_to_desc
  1120  * @global array $wp_header_to_desc
   972  *
  1121  *
   973  * @param int $code HTTP status code.
  1122  * @param int $code HTTP status code.
   974  * @return string Empty string if not found, or description if found.
  1123  * @return string Empty string if not found, or description if found.
   976 function get_status_header_desc( $code ) {
  1125 function get_status_header_desc( $code ) {
   977 	global $wp_header_to_desc;
  1126 	global $wp_header_to_desc;
   978 
  1127 
   979 	$code = absint( $code );
  1128 	$code = absint( $code );
   980 
  1129 
   981 	if ( !isset( $wp_header_to_desc ) ) {
  1130 	if ( ! isset( $wp_header_to_desc ) ) {
   982 		$wp_header_to_desc = array(
  1131 		$wp_header_to_desc = array(
   983 			100 => 'Continue',
  1132 			100 => 'Continue',
   984 			101 => 'Switching Protocols',
  1133 			101 => 'Switching Protocols',
   985 			102 => 'Processing',
  1134 			102 => 'Processing',
       
  1135 			103 => 'Early Hints',
   986 
  1136 
   987 			200 => 'OK',
  1137 			200 => 'OK',
   988 			201 => 'Created',
  1138 			201 => 'Created',
   989 			202 => 'Accepted',
  1139 			202 => 'Accepted',
   990 			203 => 'Non-Authoritative Information',
  1140 			203 => 'Non-Authoritative Information',
  1044 			510 => 'Not Extended',
  1194 			510 => 'Not Extended',
  1045 			511 => 'Network Authentication Required',
  1195 			511 => 'Network Authentication Required',
  1046 		);
  1196 		);
  1047 	}
  1197 	}
  1048 
  1198 
  1049 	if ( isset( $wp_header_to_desc[$code] ) )
  1199 	if ( isset( $wp_header_to_desc[ $code ] ) ) {
  1050 		return $wp_header_to_desc[$code];
  1200 		return $wp_header_to_desc[ $code ];
  1051 	else
  1201 	} else {
  1052 		return '';
  1202 		return '';
       
  1203 	}
  1053 }
  1204 }
  1054 
  1205 
  1055 /**
  1206 /**
  1056  * Set HTTP status header.
  1207  * Set HTTP status header.
  1057  *
  1208  *
  1070 
  1221 
  1071 	if ( empty( $description ) ) {
  1222 	if ( empty( $description ) ) {
  1072 		return;
  1223 		return;
  1073 	}
  1224 	}
  1074 
  1225 
  1075 	$protocol = wp_get_server_protocol();
  1226 	$protocol      = wp_get_server_protocol();
  1076 	$status_header = "$protocol $code $description";
  1227 	$status_header = "$protocol $code $description";
  1077 	if ( function_exists( 'apply_filters' ) )
  1228 	if ( function_exists( 'apply_filters' ) ) {
  1078 
  1229 
  1079 		/**
  1230 		/**
  1080 		 * Filters an HTTP status header.
  1231 		 * Filters an HTTP status header.
  1081 		 *
  1232 		 *
  1082 		 * @since 2.2.0
  1233 		 * @since 2.2.0
  1085 		 * @param int    $code          HTTP status code.
  1236 		 * @param int    $code          HTTP status code.
  1086 		 * @param string $description   Description for the status code.
  1237 		 * @param string $description   Description for the status code.
  1087 		 * @param string $protocol      Server protocol.
  1238 		 * @param string $protocol      Server protocol.
  1088 		 */
  1239 		 */
  1089 		$status_header = apply_filters( 'status_header', $status_header, $code, $description, $protocol );
  1240 		$status_header = apply_filters( 'status_header', $status_header, $code, $description, $protocol );
       
  1241 	}
  1090 
  1242 
  1091 	@header( $status_header, true, $code );
  1243 	@header( $status_header, true, $code );
  1092 }
  1244 }
  1093 
  1245 
  1094 /**
  1246 /**
  1101  *
  1253  *
  1102  * @return array The associative array of header names and field values.
  1254  * @return array The associative array of header names and field values.
  1103  */
  1255  */
  1104 function wp_get_nocache_headers() {
  1256 function wp_get_nocache_headers() {
  1105 	$headers = array(
  1257 	$headers = array(
  1106 		'Expires' => 'Wed, 11 Jan 1984 05:00:00 GMT',
  1258 		'Expires'       => 'Wed, 11 Jan 1984 05:00:00 GMT',
  1107 		'Cache-Control' => 'no-cache, must-revalidate, max-age=0',
  1259 		'Cache-Control' => 'no-cache, must-revalidate, max-age=0',
  1108 	);
  1260 	);
  1109 
  1261 
  1110 	if ( function_exists('apply_filters') ) {
  1262 	if ( function_exists( 'apply_filters' ) ) {
  1111 		/**
  1263 		/**
  1112 		 * Filters the cache-controlling headers.
  1264 		 * Filters the cache-controlling headers.
  1113 		 *
  1265 		 *
  1114 		 * @since 2.8.0
  1266 		 * @since 2.8.0
  1115 		 *
  1267 		 *
  1156 				break;
  1308 				break;
  1157 			}
  1309 			}
  1158 		}
  1310 		}
  1159 	}
  1311 	}
  1160 
  1312 
  1161 	foreach ( $headers as $name => $field_value )
  1313 	foreach ( $headers as $name => $field_value ) {
  1162 		@header("{$name}: {$field_value}");
  1314 		@header( "{$name}: {$field_value}" );
       
  1315 	}
  1163 }
  1316 }
  1164 
  1317 
  1165 /**
  1318 /**
  1166  * Set the headers for caching for 10 days with JavaScript content type.
  1319  * Set the headers for caching for 10 days with JavaScript content type.
  1167  *
  1320  *
  1168  * @since 2.1.0
  1321  * @since 2.1.0
  1169  */
  1322  */
  1170 function cache_javascript_headers() {
  1323 function cache_javascript_headers() {
  1171 	$expiresOffset = 10 * DAY_IN_SECONDS;
  1324 	$expiresOffset = 10 * DAY_IN_SECONDS;
  1172 
  1325 
  1173 	header( "Content-Type: text/javascript; charset=" . get_bloginfo( 'charset' ) );
  1326 	header( 'Content-Type: text/javascript; charset=' . get_bloginfo( 'charset' ) );
  1174 	header( "Vary: Accept-Encoding" ); // Handle proxies
  1327 	header( 'Vary: Accept-Encoding' ); // Handle proxies
  1175 	header( "Expires: " . gmdate( "D, d M Y H:i:s", time() + $expiresOffset ) . " GMT" );
  1328 	header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', time() + $expiresOffset ) . ' GMT' );
  1176 }
  1329 }
  1177 
  1330 
  1178 /**
  1331 /**
  1179  * Retrieve the number of database queries during the WordPress execution.
  1332  * Retrieve the number of database queries during the WordPress execution.
  1180  *
  1333  *
  1221 	$feed = get_query_var( 'feed' );
  1374 	$feed = get_query_var( 'feed' );
  1222 
  1375 
  1223 	// Remove the pad, if present.
  1376 	// Remove the pad, if present.
  1224 	$feed = preg_replace( '/^_+/', '', $feed );
  1377 	$feed = preg_replace( '/^_+/', '', $feed );
  1225 
  1378 
  1226 	if ( $feed == '' || $feed == 'feed' )
  1379 	if ( $feed == '' || $feed == 'feed' ) {
  1227 		$feed = get_default_feed();
  1380 		$feed = get_default_feed();
       
  1381 	}
  1228 
  1382 
  1229 	if ( ! has_action( "do_feed_{$feed}" ) ) {
  1383 	if ( ! has_action( "do_feed_{$feed}" ) ) {
  1230 		wp_die( __( 'ERROR: This is not a valid feed template.' ), '', array( 'response' => 404 ) );
  1384 		wp_die( __( 'ERROR: This is not a valid feed template.' ), '', array( 'response' => 404 ) );
  1231 	}
  1385 	}
  1232 
  1386 
  1275  * @see load_template()
  1429  * @see load_template()
  1276  *
  1430  *
  1277  * @param bool $for_comments True for the comment feed, false for normal feed.
  1431  * @param bool $for_comments True for the comment feed, false for normal feed.
  1278  */
  1432  */
  1279 function do_feed_rss2( $for_comments ) {
  1433 function do_feed_rss2( $for_comments ) {
  1280 	if ( $for_comments )
  1434 	if ( $for_comments ) {
  1281 		load_template( ABSPATH . WPINC . '/feed-rss2-comments.php' );
  1435 		load_template( ABSPATH . WPINC . '/feed-rss2-comments.php' );
  1282 	else
  1436 	} else {
  1283 		load_template( ABSPATH . WPINC . '/feed-rss2.php' );
  1437 		load_template( ABSPATH . WPINC . '/feed-rss2.php' );
       
  1438 	}
  1284 }
  1439 }
  1285 
  1440 
  1286 /**
  1441 /**
  1287  * Load either Atom comment feed or Atom posts feed.
  1442  * Load either Atom comment feed or Atom posts feed.
  1288  *
  1443  *
  1291  * @see load_template()
  1446  * @see load_template()
  1292  *
  1447  *
  1293  * @param bool $for_comments True for the comment feed, false for normal feed.
  1448  * @param bool $for_comments True for the comment feed, false for normal feed.
  1294  */
  1449  */
  1295 function do_feed_atom( $for_comments ) {
  1450 function do_feed_atom( $for_comments ) {
  1296 	if ($for_comments)
  1451 	if ( $for_comments ) {
  1297 		load_template( ABSPATH . WPINC . '/feed-atom-comments.php');
  1452 		load_template( ABSPATH . WPINC . '/feed-atom-comments.php' );
  1298 	else
  1453 	} else {
  1299 		load_template( ABSPATH . WPINC . '/feed-atom.php' );
  1454 		load_template( ABSPATH . WPINC . '/feed-atom.php' );
       
  1455 	}
  1300 }
  1456 }
  1301 
  1457 
  1302 /**
  1458 /**
  1303  * Display the robots.txt file content.
  1459  * Display the robots.txt file content.
  1304  *
  1460  *
  1321 	$public = get_option( 'blog_public' );
  1477 	$public = get_option( 'blog_public' );
  1322 	if ( '0' == $public ) {
  1478 	if ( '0' == $public ) {
  1323 		$output .= "Disallow: /\n";
  1479 		$output .= "Disallow: /\n";
  1324 	} else {
  1480 	} else {
  1325 		$site_url = parse_url( site_url() );
  1481 		$site_url = parse_url( site_url() );
  1326 		$path = ( !empty( $site_url['path'] ) ) ? $site_url['path'] : '';
  1482 		$path     = ( ! empty( $site_url['path'] ) ) ? $site_url['path'] : '';
  1327 		$output .= "Disallow: $path/wp-admin/\n";
  1483 		$output  .= "Disallow: $path/wp-admin/\n";
  1328 		$output .= "Allow: $path/wp-admin/admin-ajax.php\n";
  1484 		$output  .= "Allow: $path/wp-admin/admin-ajax.php\n";
  1329 	}
  1485 	}
  1330 
  1486 
  1331 	/**
  1487 	/**
  1332 	 * Filters the robots.txt output.
  1488 	 * Filters the robots.txt output.
  1333 	 *
  1489 	 *
  1338 	 */
  1494 	 */
  1339 	echo apply_filters( 'robots_txt', $output, $public );
  1495 	echo apply_filters( 'robots_txt', $output, $public );
  1340 }
  1496 }
  1341 
  1497 
  1342 /**
  1498 /**
  1343  * Test whether WordPress is already installed.
  1499  * Determines whether WordPress is already installed.
  1344  *
  1500  *
  1345  * The cache will be checked first. If you have a cache plugin, which saves
  1501  * The cache will be checked first. If you have a cache plugin, which saves
  1346  * the cache values, then this will work. If you use the default WordPress
  1502  * the cache values, then this will work. If you use the default WordPress
  1347  * cache, and the database goes away, then you might have problems.
  1503  * cache, and the database goes away, then you might have problems.
  1348  *
  1504  *
  1349  * Checks for the 'siteurl' option for whether WordPress is installed.
  1505  * Checks for the 'siteurl' option for whether WordPress is installed.
       
  1506  *
       
  1507  * For more information on this and similar theme functions, check out
       
  1508  * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
       
  1509  * Conditional Tags} article in the Theme Developer Handbook.
  1350  *
  1510  *
  1351  * @since 2.1.0
  1511  * @since 2.1.0
  1352  *
  1512  *
  1353  * @global wpdb $wpdb WordPress database abstraction object.
  1513  * @global wpdb $wpdb WordPress database abstraction object.
  1354  *
  1514  *
  1359 
  1519 
  1360 	/*
  1520 	/*
  1361 	 * Check cache first. If options table goes away and we have true
  1521 	 * Check cache first. If options table goes away and we have true
  1362 	 * cached, oh well.
  1522 	 * cached, oh well.
  1363 	 */
  1523 	 */
  1364 	if ( wp_cache_get( 'is_blog_installed' ) )
  1524 	if ( wp_cache_get( 'is_blog_installed' ) ) {
  1365 		return true;
  1525 		return true;
       
  1526 	}
  1366 
  1527 
  1367 	$suppress = $wpdb->suppress_errors();
  1528 	$suppress = $wpdb->suppress_errors();
  1368 	if ( ! wp_installing() ) {
  1529 	if ( ! wp_installing() ) {
  1369 		$alloptions = wp_load_alloptions();
  1530 		$alloptions = wp_load_alloptions();
  1370 	}
  1531 	}
  1371 	// If siteurl is not set to autoload, check it specifically
  1532 	// If siteurl is not set to autoload, check it specifically
  1372 	if ( !isset( $alloptions['siteurl'] ) )
  1533 	if ( ! isset( $alloptions['siteurl'] ) ) {
  1373 		$installed = $wpdb->get_var( "SELECT option_value FROM $wpdb->options WHERE option_name = 'siteurl'" );
  1534 		$installed = $wpdb->get_var( "SELECT option_value FROM $wpdb->options WHERE option_name = 'siteurl'" );
  1374 	else
  1535 	} else {
  1375 		$installed = $alloptions['siteurl'];
  1536 		$installed = $alloptions['siteurl'];
       
  1537 	}
  1376 	$wpdb->suppress_errors( $suppress );
  1538 	$wpdb->suppress_errors( $suppress );
  1377 
  1539 
  1378 	$installed = !empty( $installed );
  1540 	$installed = ! empty( $installed );
  1379 	wp_cache_set( 'is_blog_installed', $installed );
  1541 	wp_cache_set( 'is_blog_installed', $installed );
  1380 
  1542 
  1381 	if ( $installed )
  1543 	if ( $installed ) {
  1382 		return true;
  1544 		return true;
       
  1545 	}
  1383 
  1546 
  1384 	// If visiting repair.php, return true and let it take over.
  1547 	// If visiting repair.php, return true and let it take over.
  1385 	if ( defined( 'WP_REPAIRING' ) )
  1548 	if ( defined( 'WP_REPAIRING' ) ) {
  1386 		return true;
  1549 		return true;
       
  1550 	}
  1387 
  1551 
  1388 	$suppress = $wpdb->suppress_errors();
  1552 	$suppress = $wpdb->suppress_errors();
  1389 
  1553 
  1390 	/*
  1554 	/*
  1391 	 * Loop over the WP tables. If none exist, then scratch installation is allowed.
  1555 	 * Loop over the WP tables. If none exist, then scratch installation is allowed.
  1393 	 * options table could not be accessed.
  1557 	 * options table could not be accessed.
  1394 	 */
  1558 	 */
  1395 	$wp_tables = $wpdb->tables();
  1559 	$wp_tables = $wpdb->tables();
  1396 	foreach ( $wp_tables as $table ) {
  1560 	foreach ( $wp_tables as $table ) {
  1397 		// The existence of custom user tables shouldn't suggest an insane state or prevent a clean installation.
  1561 		// The existence of custom user tables shouldn't suggest an insane state or prevent a clean installation.
  1398 		if ( defined( 'CUSTOM_USER_TABLE' ) && CUSTOM_USER_TABLE == $table )
  1562 		if ( defined( 'CUSTOM_USER_TABLE' ) && CUSTOM_USER_TABLE == $table ) {
  1399 			continue;
  1563 			continue;
  1400 		if ( defined( 'CUSTOM_USER_META_TABLE' ) && CUSTOM_USER_META_TABLE == $table )
  1564 		}
       
  1565 		if ( defined( 'CUSTOM_USER_META_TABLE' ) && CUSTOM_USER_META_TABLE == $table ) {
  1401 			continue;
  1566 			continue;
  1402 
  1567 		}
  1403 		if ( ! $wpdb->get_results( "DESCRIBE $table;" ) )
  1568 
       
  1569 		if ( ! $wpdb->get_results( "DESCRIBE $table;" ) ) {
  1404 			continue;
  1570 			continue;
       
  1571 		}
  1405 
  1572 
  1406 		// One or more tables exist. We are insane.
  1573 		// One or more tables exist. We are insane.
  1407 
  1574 
  1408 		wp_load_translations_early();
  1575 		wp_load_translations_early();
  1409 
  1576 
  1463  * @param string     $name    Optional. Nonce name. Default '_wpnonce'.
  1630  * @param string     $name    Optional. Nonce name. Default '_wpnonce'.
  1464  * @param bool       $referer Optional. Whether to set the referer field for validation. Default true.
  1631  * @param bool       $referer Optional. Whether to set the referer field for validation. Default true.
  1465  * @param bool       $echo    Optional. Whether to display or return hidden form field. Default true.
  1632  * @param bool       $echo    Optional. Whether to display or return hidden form field. Default true.
  1466  * @return string Nonce field HTML markup.
  1633  * @return string Nonce field HTML markup.
  1467  */
  1634  */
  1468 function wp_nonce_field( $action = -1, $name = "_wpnonce", $referer = true , $echo = true ) {
  1635 function wp_nonce_field( $action = -1, $name = '_wpnonce', $referer = true, $echo = true ) {
  1469 	$name = esc_attr( $name );
  1636 	$name        = esc_attr( $name );
  1470 	$nonce_field = '<input type="hidden" id="' . $name . '" name="' . $name . '" value="' . wp_create_nonce( $action ) . '" />';
  1637 	$nonce_field = '<input type="hidden" id="' . $name . '" name="' . $name . '" value="' . wp_create_nonce( $action ) . '" />';
  1471 
  1638 
  1472 	if ( $referer )
  1639 	if ( $referer ) {
  1473 		$nonce_field .= wp_referer_field( false );
  1640 		$nonce_field .= wp_referer_field( false );
  1474 
  1641 	}
  1475 	if ( $echo )
  1642 
       
  1643 	if ( $echo ) {
  1476 		echo $nonce_field;
  1644 		echo $nonce_field;
       
  1645 	}
  1477 
  1646 
  1478 	return $nonce_field;
  1647 	return $nonce_field;
  1479 }
  1648 }
  1480 
  1649 
  1481 /**
  1650 /**
  1488  *
  1657  *
  1489  * @param bool $echo Optional. Whether to echo or return the referer field. Default true.
  1658  * @param bool $echo Optional. Whether to echo or return the referer field. Default true.
  1490  * @return string Referer field HTML markup.
  1659  * @return string Referer field HTML markup.
  1491  */
  1660  */
  1492 function wp_referer_field( $echo = true ) {
  1661 function wp_referer_field( $echo = true ) {
  1493 	$referer_field = '<input type="hidden" name="_wp_http_referer" value="'. esc_attr( wp_unslash( $_SERVER['REQUEST_URI'] ) ) . '" />';
  1662 	$referer_field = '<input type="hidden" name="_wp_http_referer" value="' . esc_attr( wp_unslash( $_SERVER['REQUEST_URI'] ) ) . '" />';
  1494 
  1663 
  1495 	if ( $echo )
  1664 	if ( $echo ) {
  1496 		echo $referer_field;
  1665 		echo $referer_field;
       
  1666 	}
  1497 	return $referer_field;
  1667 	return $referer_field;
  1498 }
  1668 }
  1499 
  1669 
  1500 /**
  1670 /**
  1501  * Retrieve or display original referer hidden field for forms.
  1671  * Retrieve or display original referer hidden field for forms.
  1514 function wp_original_referer_field( $echo = true, $jump_back_to = 'current' ) {
  1684 function wp_original_referer_field( $echo = true, $jump_back_to = 'current' ) {
  1515 	if ( ! $ref = wp_get_original_referer() ) {
  1685 	if ( ! $ref = wp_get_original_referer() ) {
  1516 		$ref = 'previous' == $jump_back_to ? wp_get_referer() : wp_unslash( $_SERVER['REQUEST_URI'] );
  1686 		$ref = 'previous' == $jump_back_to ? wp_get_referer() : wp_unslash( $_SERVER['REQUEST_URI'] );
  1517 	}
  1687 	}
  1518 	$orig_referer_field = '<input type="hidden" name="_wp_original_http_referer" value="' . esc_attr( $ref ) . '" />';
  1688 	$orig_referer_field = '<input type="hidden" name="_wp_original_http_referer" value="' . esc_attr( $ref ) . '" />';
  1519 	if ( $echo )
  1689 	if ( $echo ) {
  1520 		echo $orig_referer_field;
  1690 		echo $orig_referer_field;
       
  1691 	}
  1521 	return $orig_referer_field;
  1692 	return $orig_referer_field;
  1522 }
  1693 }
  1523 
  1694 
  1524 /**
  1695 /**
  1525  * Retrieve referer from '_wp_http_referer' or HTTP referer.
  1696  * Retrieve referer from '_wp_http_referer' or HTTP referer.
  1554  * @return string|false Referer URL on success, false on failure.
  1725  * @return string|false Referer URL on success, false on failure.
  1555  */
  1726  */
  1556 function wp_get_raw_referer() {
  1727 function wp_get_raw_referer() {
  1557 	if ( ! empty( $_REQUEST['_wp_http_referer'] ) ) {
  1728 	if ( ! empty( $_REQUEST['_wp_http_referer'] ) ) {
  1558 		return wp_unslash( $_REQUEST['_wp_http_referer'] );
  1729 		return wp_unslash( $_REQUEST['_wp_http_referer'] );
  1559 	} else if ( ! empty( $_SERVER['HTTP_REFERER'] ) ) {
  1730 	} elseif ( ! empty( $_SERVER['HTTP_REFERER'] ) ) {
  1560 		return wp_unslash( $_SERVER['HTTP_REFERER'] );
  1731 		return wp_unslash( $_SERVER['HTTP_REFERER'] );
  1561 	}
  1732 	}
  1562 
  1733 
  1563 	return false;
  1734 	return false;
  1564 }
  1735 }
  1569  * @since 2.0.4
  1740  * @since 2.0.4
  1570  *
  1741  *
  1571  * @return string|false False if no original referer or original referer if set.
  1742  * @return string|false False if no original referer or original referer if set.
  1572  */
  1743  */
  1573 function wp_get_original_referer() {
  1744 function wp_get_original_referer() {
  1574 	if ( ! empty( $_REQUEST['_wp_original_http_referer'] ) && function_exists( 'wp_validate_redirect' ) )
  1745 	if ( ! empty( $_REQUEST['_wp_original_http_referer'] ) && function_exists( 'wp_validate_redirect' ) ) {
  1575 		return wp_validate_redirect( wp_unslash( $_REQUEST['_wp_original_http_referer'] ), false );
  1746 		return wp_validate_redirect( wp_unslash( $_REQUEST['_wp_original_http_referer'] ), false );
       
  1747 	}
  1576 	return false;
  1748 	return false;
  1577 }
  1749 }
  1578 
  1750 
  1579 /**
  1751 /**
  1580  * Recursive directory creation based on full path.
  1752  * Recursive directory creation based on full path.
  1604 
  1776 
  1605 	/*
  1777 	/*
  1606 	 * Safe mode fails with a trailing slash under certain PHP versions.
  1778 	 * Safe mode fails with a trailing slash under certain PHP versions.
  1607 	 * Use rtrim() instead of untrailingslashit to avoid formatting.php dependency.
  1779 	 * Use rtrim() instead of untrailingslashit to avoid formatting.php dependency.
  1608 	 */
  1780 	 */
  1609 	$target = rtrim($target, '/');
  1781 	$target = rtrim( $target, '/' );
  1610 	if ( empty($target) )
  1782 	if ( empty( $target ) ) {
  1611 		$target = '/';
  1783 		$target = '/';
  1612 
  1784 	}
  1613 	if ( file_exists( $target ) )
  1785 
       
  1786 	if ( file_exists( $target ) ) {
  1614 		return @is_dir( $target );
  1787 		return @is_dir( $target );
       
  1788 	}
  1615 
  1789 
  1616 	// We need to find the permissions of the parent folder that exists and inherit that.
  1790 	// We need to find the permissions of the parent folder that exists and inherit that.
  1617 	$target_parent = dirname( $target );
  1791 	$target_parent = dirname( $target );
  1618 	while ( '.' != $target_parent && ! is_dir( $target_parent ) && dirname( $target_parent ) !== $target_parent ) {
  1792 	while ( '.' != $target_parent && ! is_dir( $target_parent ) && dirname( $target_parent ) !== $target_parent ) {
  1619 		$target_parent = dirname( $target_parent );
  1793 		$target_parent = dirname( $target_parent );
  1655  * @param string $path File path.
  1829  * @param string $path File path.
  1656  * @return bool True if path is absolute, false is not absolute.
  1830  * @return bool True if path is absolute, false is not absolute.
  1657  */
  1831  */
  1658 function path_is_absolute( $path ) {
  1832 function path_is_absolute( $path ) {
  1659 	/*
  1833 	/*
       
  1834 	 * Check to see if the path is a stream and check to see if its an actual
       
  1835 	 * path or file as realpath() does not support stream wrappers.
       
  1836 	 */
       
  1837 	if ( wp_is_stream( $path ) && ( is_dir( $path ) || is_file( $path ) ) ) {
       
  1838 		return true;
       
  1839 	}
       
  1840 
       
  1841 	/*
  1660 	 * This is definitive if true but fails if $path does not exist or contains
  1842 	 * This is definitive if true but fails if $path does not exist or contains
  1661 	 * a symbolic link.
  1843 	 * a symbolic link.
  1662 	 */
  1844 	 */
  1663 	if ( realpath($path) == $path )
  1845 	if ( realpath( $path ) == $path ) {
  1664 		return true;
  1846 		return true;
  1665 
  1847 	}
  1666 	if ( strlen($path) == 0 || $path[0] == '.' )
  1848 
       
  1849 	if ( strlen( $path ) == 0 || $path[0] == '.' ) {
  1667 		return false;
  1850 		return false;
       
  1851 	}
  1668 
  1852 
  1669 	// Windows allows absolute paths like this.
  1853 	// Windows allows absolute paths like this.
  1670 	if ( preg_match('#^[a-zA-Z]:\\\\#', $path) )
  1854 	if ( preg_match( '#^[a-zA-Z]:\\\\#', $path ) ) {
  1671 		return true;
  1855 		return true;
       
  1856 	}
  1672 
  1857 
  1673 	// A path starting with / or \ is absolute; anything else is relative.
  1858 	// A path starting with / or \ is absolute; anything else is relative.
  1674 	return ( $path[0] == '/' || $path[0] == '\\' );
  1859 	return ( $path[0] == '/' || $path[0] == '\\' );
  1675 }
  1860 }
  1676 
  1861 
  1685  * @param string $base Base path.
  1870  * @param string $base Base path.
  1686  * @param string $path Path relative to $base.
  1871  * @param string $path Path relative to $base.
  1687  * @return string The path with the base or absolute path.
  1872  * @return string The path with the base or absolute path.
  1688  */
  1873  */
  1689 function path_join( $base, $path ) {
  1874 function path_join( $base, $path ) {
  1690 	if ( path_is_absolute($path) )
  1875 	if ( path_is_absolute( $path ) ) {
  1691 		return $path;
  1876 		return $path;
  1692 
  1877 	}
  1693 	return rtrim($base, '/') . '/' . ltrim($path, '/');
  1878 
       
  1879 	return rtrim( $base, '/' ) . '/' . ltrim( $path, '/' );
  1694 }
  1880 }
  1695 
  1881 
  1696 /**
  1882 /**
  1697  * Normalize a filesystem path.
  1883  * Normalize a filesystem path.
  1698  *
  1884  *
  1711  */
  1897  */
  1712 function wp_normalize_path( $path ) {
  1898 function wp_normalize_path( $path ) {
  1713 	$wrapper = '';
  1899 	$wrapper = '';
  1714 	if ( wp_is_stream( $path ) ) {
  1900 	if ( wp_is_stream( $path ) ) {
  1715 		list( $wrapper, $path ) = explode( '://', $path, 2 );
  1901 		list( $wrapper, $path ) = explode( '://', $path, 2 );
  1716 		$wrapper .= '://';
  1902 		$wrapper               .= '://';
  1717 	}
  1903 	}
  1718 
  1904 
  1719 	// Standardise all paths to use /
  1905 	// Standardise all paths to use /
  1720 	$path = str_replace( '\\', '/', $path );
  1906 	$path = str_replace( '\\', '/', $path );
  1721 
  1907 
  1746  *
  1932  *
  1747  * @return string Writable temporary directory.
  1933  * @return string Writable temporary directory.
  1748  */
  1934  */
  1749 function get_temp_dir() {
  1935 function get_temp_dir() {
  1750 	static $temp = '';
  1936 	static $temp = '';
  1751 	if ( defined('WP_TEMP_DIR') )
  1937 	if ( defined( 'WP_TEMP_DIR' ) ) {
  1752 		return trailingslashit(WP_TEMP_DIR);
  1938 		return trailingslashit( WP_TEMP_DIR );
  1753 
  1939 	}
  1754 	if ( $temp )
  1940 
       
  1941 	if ( $temp ) {
  1755 		return trailingslashit( $temp );
  1942 		return trailingslashit( $temp );
  1756 
  1943 	}
  1757 	if ( function_exists('sys_get_temp_dir') ) {
  1944 
       
  1945 	if ( function_exists( 'sys_get_temp_dir' ) ) {
  1758 		$temp = sys_get_temp_dir();
  1946 		$temp = sys_get_temp_dir();
  1759 		if ( @is_dir( $temp ) && wp_is_writable( $temp ) )
  1947 		if ( @is_dir( $temp ) && wp_is_writable( $temp ) ) {
  1760 			return trailingslashit( $temp );
  1948 			return trailingslashit( $temp );
  1761 	}
  1949 		}
  1762 
  1950 	}
  1763 	$temp = ini_get('upload_tmp_dir');
  1951 
  1764 	if ( @is_dir( $temp ) && wp_is_writable( $temp ) )
  1952 	$temp = ini_get( 'upload_tmp_dir' );
       
  1953 	if ( @is_dir( $temp ) && wp_is_writable( $temp ) ) {
  1765 		return trailingslashit( $temp );
  1954 		return trailingslashit( $temp );
       
  1955 	}
  1766 
  1956 
  1767 	$temp = WP_CONTENT_DIR . '/';
  1957 	$temp = WP_CONTENT_DIR . '/';
  1768 	if ( is_dir( $temp ) && wp_is_writable( $temp ) )
  1958 	if ( is_dir( $temp ) && wp_is_writable( $temp ) ) {
  1769 		return $temp;
  1959 		return $temp;
       
  1960 	}
  1770 
  1961 
  1771 	return '/tmp/';
  1962 	return '/tmp/';
  1772 }
  1963 }
  1773 
  1964 
  1774 /**
  1965 /**
  1783  *
  1974  *
  1784  * @param string $path Path to check for write-ability.
  1975  * @param string $path Path to check for write-ability.
  1785  * @return bool Whether the path is writable.
  1976  * @return bool Whether the path is writable.
  1786  */
  1977  */
  1787 function wp_is_writable( $path ) {
  1978 function wp_is_writable( $path ) {
  1788 	if ( 'WIN' === strtoupper( substr( PHP_OS, 0, 3 ) ) )
  1979 	if ( 'WIN' === strtoupper( substr( PHP_OS, 0, 3 ) ) ) {
  1789 		return win_is_writable( $path );
  1980 		return win_is_writable( $path );
  1790 	else
  1981 	} else {
  1791 		return @is_writable( $path );
  1982 		return @is_writable( $path );
       
  1983 	}
  1792 }
  1984 }
  1793 
  1985 
  1794 /**
  1986 /**
  1795  * Workaround for Windows bug in is_writable() function
  1987  * Workaround for Windows bug in is_writable() function
  1796  *
  1988  *
  1807  * @param string $path Windows path to check for write-ability.
  1999  * @param string $path Windows path to check for write-ability.
  1808  * @return bool Whether the path is writable.
  2000  * @return bool Whether the path is writable.
  1809  */
  2001  */
  1810 function win_is_writable( $path ) {
  2002 function win_is_writable( $path ) {
  1811 
  2003 
  1812 	if ( $path[strlen( $path ) - 1] == '/' ) { // if it looks like a directory, check a random file within the directory
  2004 	if ( $path[ strlen( $path ) - 1 ] == '/' ) { // if it looks like a directory, check a random file within the directory
  1813 		return win_is_writable( $path . uniqid( mt_rand() ) . '.tmp');
  2005 		return win_is_writable( $path . uniqid( mt_rand() ) . '.tmp' );
  1814 	} elseif ( is_dir( $path ) ) { // If it's a directory (and not a file) check a random file within the directory
  2006 	} elseif ( is_dir( $path ) ) { // If it's a directory (and not a file) check a random file within the directory
  1815 		return win_is_writable( $path . '/' . uniqid( mt_rand() ) . '.tmp' );
  2007 		return win_is_writable( $path . '/' . uniqid( mt_rand() ) . '.tmp' );
  1816 	}
  2008 	}
  1817 	// check tmp file for read/write capabilities
  2009 	// check tmp file for read/write capabilities
  1818 	$should_delete_tmp_file = !file_exists( $path );
  2010 	$should_delete_tmp_file = ! file_exists( $path );
  1819 	$f = @fopen( $path, 'a' );
  2011 	$f                      = @fopen( $path, 'a' );
  1820 	if ( $f === false )
  2012 	if ( $f === false ) {
  1821 		return false;
  2013 		return false;
       
  2014 	}
  1822 	fclose( $f );
  2015 	fclose( $f );
  1823 	if ( $should_delete_tmp_file )
  2016 	if ( $should_delete_tmp_file ) {
  1824 		unlink( $path );
  2017 		unlink( $path );
       
  2018 	}
  1825 	return true;
  2019 	return true;
  1826 }
  2020 }
  1827 
  2021 
  1828 /**
  2022 /**
  1829  * Retrieves uploads directory information.
  2023  * Retrieves uploads directory information.
  1908 		} else {
  2102 		} else {
  1909 			if ( ! wp_mkdir_p( $path ) ) {
  2103 			if ( ! wp_mkdir_p( $path ) ) {
  1910 				if ( 0 === strpos( $uploads['basedir'], ABSPATH ) ) {
  2104 				if ( 0 === strpos( $uploads['basedir'], ABSPATH ) ) {
  1911 					$error_path = str_replace( ABSPATH, '', $uploads['basedir'] ) . $uploads['subdir'];
  2105 					$error_path = str_replace( ABSPATH, '', $uploads['basedir'] ) . $uploads['subdir'];
  1912 				} else {
  2106 				} else {
  1913 					$error_path = basename( $uploads['basedir'] ) . $uploads['subdir'];
  2107 					$error_path = wp_basename( $uploads['basedir'] ) . $uploads['subdir'];
  1914 				}
  2108 				}
  1915 
  2109 
  1916 				$uploads['error'] = sprintf(
  2110 				$uploads['error'] = sprintf(
  1917 					/* translators: %s: directory path */
  2111 					/* translators: %s: directory path */
  1918 					__( 'Unable to create directory %s. Is its parent directory writable by the server?' ),
  2112 					__( 'Unable to create directory %s. Is its parent directory writable by the server?' ),
  1935  *
  2129  *
  1936  * @param string $time Optional. Time formatted in 'yyyy/mm'. Default null.
  2130  * @param string $time Optional. Time formatted in 'yyyy/mm'. Default null.
  1937  * @return array See wp_upload_dir()
  2131  * @return array See wp_upload_dir()
  1938  */
  2132  */
  1939 function _wp_upload_dir( $time = null ) {
  2133 function _wp_upload_dir( $time = null ) {
  1940 	$siteurl = get_option( 'siteurl' );
  2134 	$siteurl     = get_option( 'siteurl' );
  1941 	$upload_path = trim( get_option( 'upload_path' ) );
  2135 	$upload_path = trim( get_option( 'upload_path' ) );
  1942 
  2136 
  1943 	if ( empty( $upload_path ) || 'wp-content/uploads' == $upload_path ) {
  2137 	if ( empty( $upload_path ) || 'wp-content/uploads' == $upload_path ) {
  1944 		$dir = WP_CONTENT_DIR . '/uploads';
  2138 		$dir = WP_CONTENT_DIR . '/uploads';
  1945 	} elseif ( 0 !== strpos( $upload_path, ABSPATH ) ) {
  2139 	} elseif ( 0 !== strpos( $upload_path, ABSPATH ) ) {
  1947 		$dir = path_join( ABSPATH, $upload_path );
  2141 		$dir = path_join( ABSPATH, $upload_path );
  1948 	} else {
  2142 	} else {
  1949 		$dir = $upload_path;
  2143 		$dir = $upload_path;
  1950 	}
  2144 	}
  1951 
  2145 
  1952 	if ( !$url = get_option( 'upload_url_path' ) ) {
  2146 	if ( ! $url = get_option( 'upload_url_path' ) ) {
  1953 		if ( empty($upload_path) || ( 'wp-content/uploads' == $upload_path ) || ( $upload_path == $dir ) )
  2147 		if ( empty( $upload_path ) || ( 'wp-content/uploads' == $upload_path ) || ( $upload_path == $dir ) ) {
  1954 			$url = WP_CONTENT_URL . '/uploads';
  2148 			$url = WP_CONTENT_URL . '/uploads';
  1955 		else
  2149 		} else {
  1956 			$url = trailingslashit( $siteurl ) . $upload_path;
  2150 			$url = trailingslashit( $siteurl ) . $upload_path;
       
  2151 		}
  1957 	}
  2152 	}
  1958 
  2153 
  1959 	/*
  2154 	/*
  1960 	 * Honor the value of UPLOADS. This happens as long as ms-files rewriting is disabled.
  2155 	 * Honor the value of UPLOADS. This happens as long as ms-files rewriting is disabled.
  1961 	 * We also sometimes obey UPLOADS when rewriting is enabled -- see the next block.
  2156 	 * We also sometimes obey UPLOADS when rewriting is enabled -- see the next block.
  1976 			 * a year-based directory for the main site. But if a MU-era network has disabled
  2171 			 * a year-based directory for the main site. But if a MU-era network has disabled
  1977 			 * ms-files rewriting manually, they don't need the extra directory, as they never
  2172 			 * ms-files rewriting manually, they don't need the extra directory, as they never
  1978 			 * had wp-content/uploads for the main site.)
  2173 			 * had wp-content/uploads for the main site.)
  1979 			 */
  2174 			 */
  1980 
  2175 
  1981 			if ( defined( 'MULTISITE' ) )
  2176 			if ( defined( 'MULTISITE' ) ) {
  1982 				$ms_dir = '/sites/' . get_current_blog_id();
  2177 				$ms_dir = '/sites/' . get_current_blog_id();
  1983 			else
  2178 			} else {
  1984 				$ms_dir = '/' . get_current_blog_id();
  2179 				$ms_dir = '/' . get_current_blog_id();
       
  2180 			}
  1985 
  2181 
  1986 			$dir .= $ms_dir;
  2182 			$dir .= $ms_dir;
  1987 			$url .= $ms_dir;
  2183 			$url .= $ms_dir;
  1988 
  2184 
  1989 		} elseif ( defined( 'UPLOADS' ) && ! ms_is_switched() ) {
  2185 		} elseif ( defined( 'UPLOADS' ) && ! ms_is_switched() ) {
  1999 			 * (And it will be set, see ms_upload_constants().) Otherwise, UPLOADS can be used, as
  2195 			 * (And it will be set, see ms_upload_constants().) Otherwise, UPLOADS can be used, as
  2000 			 * as it is relative to ABSPATH. For the final piece: when UPLOADS is used with ms-files
  2196 			 * as it is relative to ABSPATH. For the final piece: when UPLOADS is used with ms-files
  2001 			 * rewriting in multisite, the resulting URL is /files. (#WP22702 for background.)
  2197 			 * rewriting in multisite, the resulting URL is /files. (#WP22702 for background.)
  2002 			 */
  2198 			 */
  2003 
  2199 
  2004 			if ( defined( 'BLOGUPLOADDIR' ) )
  2200 			if ( defined( 'BLOGUPLOADDIR' ) ) {
  2005 				$dir = untrailingslashit( BLOGUPLOADDIR );
  2201 				$dir = untrailingslashit( BLOGUPLOADDIR );
  2006 			else
  2202 			} else {
  2007 				$dir = ABSPATH . UPLOADS;
  2203 				$dir = ABSPATH . UPLOADS;
       
  2204 			}
  2008 			$url = trailingslashit( $siteurl ) . 'files';
  2205 			$url = trailingslashit( $siteurl ) . 'files';
  2009 		}
  2206 		}
  2010 	}
  2207 	}
  2011 
  2208 
  2012 	$basedir = $dir;
  2209 	$basedir = $dir;
  2013 	$baseurl = $url;
  2210 	$baseurl = $url;
  2014 
  2211 
  2015 	$subdir = '';
  2212 	$subdir = '';
  2016 	if ( get_option( 'uploads_use_yearmonth_folders' ) ) {
  2213 	if ( get_option( 'uploads_use_yearmonth_folders' ) ) {
  2017 		// Generate the yearly and monthly dirs
  2214 		// Generate the yearly and monthly dirs
  2018 		if ( !$time )
  2215 		if ( ! $time ) {
  2019 			$time = current_time( 'mysql' );
  2216 			$time = current_time( 'mysql' );
  2020 		$y = substr( $time, 0, 4 );
  2217 		}
  2021 		$m = substr( $time, 5, 2 );
  2218 		$y      = substr( $time, 0, 4 );
       
  2219 		$m      = substr( $time, 5, 2 );
  2022 		$subdir = "/$y/$m";
  2220 		$subdir = "/$y/$m";
  2023 	}
  2221 	}
  2024 
  2222 
  2025 	$dir .= $subdir;
  2223 	$dir .= $subdir;
  2026 	$url .= $subdir;
  2224 	$url .= $subdir;
  2052  * @param callable $unique_filename_callback Callback. Default null.
  2250  * @param callable $unique_filename_callback Callback. Default null.
  2053  * @return string New filename, if given wasn't unique.
  2251  * @return string New filename, if given wasn't unique.
  2054  */
  2252  */
  2055 function wp_unique_filename( $dir, $filename, $unique_filename_callback = null ) {
  2253 function wp_unique_filename( $dir, $filename, $unique_filename_callback = null ) {
  2056 	// Sanitize the file name before we begin processing.
  2254 	// Sanitize the file name before we begin processing.
  2057 	$filename = sanitize_file_name($filename);
  2255 	$filename = sanitize_file_name( $filename );
  2058 
  2256 
  2059 	// Separate the filename into a name and extension.
  2257 	// Separate the filename into a name and extension.
  2060 	$ext = pathinfo( $filename, PATHINFO_EXTENSION );
  2258 	$ext  = pathinfo( $filename, PATHINFO_EXTENSION );
  2061 	$name = pathinfo( $filename, PATHINFO_BASENAME );
  2259 	$name = pathinfo( $filename, PATHINFO_BASENAME );
  2062 	if ( $ext ) {
  2260 	if ( $ext ) {
  2063 		$ext = '.' . $ext;
  2261 		$ext = '.' . $ext;
  2064 	}
  2262 	}
  2065 
  2263 
  2076 		$filename = call_user_func( $unique_filename_callback, $dir, $name, $ext );
  2274 		$filename = call_user_func( $unique_filename_callback, $dir, $name, $ext );
  2077 	} else {
  2275 	} else {
  2078 		$number = '';
  2276 		$number = '';
  2079 
  2277 
  2080 		// Change '.ext' to lower case.
  2278 		// Change '.ext' to lower case.
  2081 		if ( $ext && strtolower($ext) != $ext ) {
  2279 		if ( $ext && strtolower( $ext ) != $ext ) {
  2082 			$ext2 = strtolower($ext);
  2280 			$ext2      = strtolower( $ext );
  2083 			$filename2 = preg_replace( '|' . preg_quote($ext) . '$|', $ext2, $filename );
  2281 			$filename2 = preg_replace( '|' . preg_quote( $ext ) . '$|', $ext2, $filename );
  2084 
  2282 
  2085 			// Check for both lower and upper case extension or image sub-sizes may be overwritten.
  2283 			// Check for both lower and upper case extension or image sub-sizes may be overwritten.
  2086 			while ( file_exists($dir . "/$filename") || file_exists($dir . "/$filename2") ) {
  2284 			while ( file_exists( $dir . "/$filename" ) || file_exists( $dir . "/$filename2" ) ) {
  2087 				$new_number = (int) $number + 1;
  2285 				$new_number = (int) $number + 1;
  2088 				$filename = str_replace( array( "-$number$ext", "$number$ext" ), "-$new_number$ext", $filename );
  2286 				$filename   = str_replace( array( "-$number$ext", "$number$ext" ), "-$new_number$ext", $filename );
  2089 				$filename2 = str_replace( array( "-$number$ext2", "$number$ext2" ), "-$new_number$ext2", $filename2 );
  2287 				$filename2  = str_replace( array( "-$number$ext2", "$number$ext2" ), "-$new_number$ext2", $filename2 );
  2090 				$number = $new_number;
  2288 				$number     = $new_number;
  2091 			}
  2289 			}
  2092 
  2290 
  2093 			/**
  2291 			/**
  2094 			 * Filters the result when generating a unique file name.
  2292 			 * Filters the result when generating a unique file name.
  2095 			 *
  2293 			 *
  2106 		while ( file_exists( $dir . "/$filename" ) ) {
  2304 		while ( file_exists( $dir . "/$filename" ) ) {
  2107 			$new_number = (int) $number + 1;
  2305 			$new_number = (int) $number + 1;
  2108 			if ( '' == "$number$ext" ) {
  2306 			if ( '' == "$number$ext" ) {
  2109 				$filename = "$filename-" . $new_number;
  2307 				$filename = "$filename-" . $new_number;
  2110 			} else {
  2308 			} else {
  2111 				$filename = str_replace( array( "-$number$ext", "$number$ext" ), "-" . $new_number . $ext, $filename );
  2309 				$filename = str_replace( array( "-$number$ext", "$number$ext" ), '-' . $new_number . $ext, $filename );
  2112 			}
  2310 			}
  2113 			$number = $new_number;
  2311 			$number = $new_number;
  2114 		}
  2312 		}
  2115 	}
  2313 	}
  2116 
  2314 
  2140  * @param mixed        $bits       File content
  2338  * @param mixed        $bits       File content
  2141  * @param string       $time       Optional. Time formatted in 'yyyy/mm'. Default null.
  2339  * @param string       $time       Optional. Time formatted in 'yyyy/mm'. Default null.
  2142  * @return array
  2340  * @return array
  2143  */
  2341  */
  2144 function wp_upload_bits( $name, $deprecated, $bits, $time = null ) {
  2342 function wp_upload_bits( $name, $deprecated, $bits, $time = null ) {
  2145 	if ( !empty( $deprecated ) )
  2343 	if ( ! empty( $deprecated ) ) {
  2146 		_deprecated_argument( __FUNCTION__, '2.0.0' );
  2344 		_deprecated_argument( __FUNCTION__, '2.0.0' );
  2147 
  2345 	}
  2148 	if ( empty( $name ) )
  2346 
       
  2347 	if ( empty( $name ) ) {
  2149 		return array( 'error' => __( 'Empty filename' ) );
  2348 		return array( 'error' => __( 'Empty filename' ) );
       
  2349 	}
  2150 
  2350 
  2151 	$wp_filetype = wp_check_filetype( $name );
  2351 	$wp_filetype = wp_check_filetype( $name );
  2152 	if ( ! $wp_filetype['ext'] && ! current_user_can( 'unfiltered_upload' ) )
  2352 	if ( ! $wp_filetype['ext'] && ! current_user_can( 'unfiltered_upload' ) ) {
  2153 		return array( 'error' => __( 'Sorry, this file type is not permitted for security reasons.' ) );
  2353 		return array( 'error' => __( 'Sorry, this file type is not permitted for security reasons.' ) );
       
  2354 	}
  2154 
  2355 
  2155 	$upload = wp_upload_dir( $time );
  2356 	$upload = wp_upload_dir( $time );
  2156 
  2357 
  2157 	if ( $upload['error'] !== false )
  2358 	if ( $upload['error'] !== false ) {
  2158 		return $upload;
  2359 		return $upload;
       
  2360 	}
  2159 
  2361 
  2160 	/**
  2362 	/**
  2161 	 * Filters whether to treat the upload bits as an error.
  2363 	 * Filters whether to treat the upload bits as an error.
  2162 	 *
  2364 	 *
  2163 	 * Passing a non-array to the filter will effectively short-circuit preparing
  2365 	 * Passing a non-array to the filter will effectively short-circuit preparing
  2165 	 *
  2367 	 *
  2166 	 * @since 3.0.0
  2368 	 * @since 3.0.0
  2167 	 *
  2369 	 *
  2168 	 * @param mixed $upload_bits_error An array of upload bits data, or a non-array error to return.
  2370 	 * @param mixed $upload_bits_error An array of upload bits data, or a non-array error to return.
  2169 	 */
  2371 	 */
  2170 	$upload_bits_error = apply_filters( 'wp_upload_bits', array( 'name' => $name, 'bits' => $bits, 'time' => $time ) );
  2372 	$upload_bits_error = apply_filters(
  2171 	if ( !is_array( $upload_bits_error ) ) {
  2373 		'wp_upload_bits',
  2172 		$upload[ 'error' ] = $upload_bits_error;
  2374 		array(
       
  2375 			'name' => $name,
       
  2376 			'bits' => $bits,
       
  2377 			'time' => $time,
       
  2378 		)
       
  2379 	);
       
  2380 	if ( ! is_array( $upload_bits_error ) ) {
       
  2381 		$upload['error'] = $upload_bits_error;
  2173 		return $upload;
  2382 		return $upload;
  2174 	}
  2383 	}
  2175 
  2384 
  2176 	$filename = wp_unique_filename( $upload['path'], $name );
  2385 	$filename = wp_unique_filename( $upload['path'], $name );
  2177 
  2386 
  2178 	$new_file = $upload['path'] . "/$filename";
  2387 	$new_file = $upload['path'] . "/$filename";
  2179 	if ( ! wp_mkdir_p( dirname( $new_file ) ) ) {
  2388 	if ( ! wp_mkdir_p( dirname( $new_file ) ) ) {
  2180 		if ( 0 === strpos( $upload['basedir'], ABSPATH ) )
  2389 		if ( 0 === strpos( $upload['basedir'], ABSPATH ) ) {
  2181 			$error_path = str_replace( ABSPATH, '', $upload['basedir'] ) . $upload['subdir'];
  2390 			$error_path = str_replace( ABSPATH, '', $upload['basedir'] ) . $upload['subdir'];
  2182 		else
  2391 		} else {
  2183 			$error_path = basename( $upload['basedir'] ) . $upload['subdir'];
  2392 			$error_path = wp_basename( $upload['basedir'] ) . $upload['subdir'];
       
  2393 		}
  2184 
  2394 
  2185 		$message = sprintf(
  2395 		$message = sprintf(
  2186 			/* translators: %s: directory path */
  2396 			/* translators: %s: directory path */
  2187 			__( 'Unable to create directory %s. Is its parent directory writable by the server?' ),
  2397 			__( 'Unable to create directory %s. Is its parent directory writable by the server?' ),
  2188 			$error_path
  2398 			$error_path
  2189 		);
  2399 		);
  2190 		return array( 'error' => $message );
  2400 		return array( 'error' => $message );
  2191 	}
  2401 	}
  2192 
  2402 
  2193 	$ifp = @ fopen( $new_file, 'wb' );
  2403 	$ifp = @ fopen( $new_file, 'wb' );
  2194 	if ( ! $ifp )
  2404 	if ( ! $ifp ) {
  2195 		return array( 'error' => sprintf( __( 'Could not write file %s' ), $new_file ) );
  2405 		return array( 'error' => sprintf( __( 'Could not write file %s' ), $new_file ) );
       
  2406 	}
  2196 
  2407 
  2197 	@fwrite( $ifp, $bits );
  2408 	@fwrite( $ifp, $bits );
  2198 	fclose( $ifp );
  2409 	fclose( $ifp );
  2199 	clearstatcache();
  2410 	clearstatcache();
  2200 
  2411 
  2201 	// Set correct file permissions
  2412 	// Set correct file permissions
  2202 	$stat = @ stat( dirname( $new_file ) );
  2413 	$stat  = @ stat( dirname( $new_file ) );
  2203 	$perms = $stat['mode'] & 0007777;
  2414 	$perms = $stat['mode'] & 0007777;
  2204 	$perms = $perms & 0000666;
  2415 	$perms = $perms & 0000666;
  2205 	@ chmod( $new_file, $perms );
  2416 	@ chmod( $new_file, $perms );
  2206 	clearstatcache();
  2417 	clearstatcache();
  2207 
  2418 
  2208 	// Compute the URL
  2419 	// Compute the URL
  2209 	$url = $upload['url'] . "/$filename";
  2420 	$url = $upload['url'] . "/$filename";
  2210 
  2421 
  2211 	/** This filter is documented in wp-admin/includes/file.php */
  2422 	/** This filter is documented in wp-admin/includes/file.php */
  2212 	return apply_filters( 'wp_handle_upload', array( 'file' => $new_file, 'url' => $url, 'type' => $wp_filetype['type'], 'error' => false ), 'sideload' );
  2423 	return apply_filters(
       
  2424 		'wp_handle_upload',
       
  2425 		array(
       
  2426 			'file'  => $new_file,
       
  2427 			'url'   => $url,
       
  2428 			'type'  => $wp_filetype['type'],
       
  2429 			'error' => false,
       
  2430 		),
       
  2431 		'sideload'
       
  2432 	);
  2213 }
  2433 }
  2214 
  2434 
  2215 /**
  2435 /**
  2216  * Retrieve the file type based on the extension name.
  2436  * Retrieve the file type based on the extension name.
  2217  *
  2437  *
  2222  */
  2442  */
  2223 function wp_ext2type( $ext ) {
  2443 function wp_ext2type( $ext ) {
  2224 	$ext = strtolower( $ext );
  2444 	$ext = strtolower( $ext );
  2225 
  2445 
  2226 	$ext2type = wp_get_ext_types();
  2446 	$ext2type = wp_get_ext_types();
  2227 	foreach ( $ext2type as $type => $exts )
  2447 	foreach ( $ext2type as $type => $exts ) {
  2228 		if ( in_array( $ext, $exts ) )
  2448 		if ( in_array( $ext, $exts ) ) {
  2229 			return $type;
  2449 			return $type;
       
  2450 		}
       
  2451 	}
  2230 }
  2452 }
  2231 
  2453 
  2232 /**
  2454 /**
  2233  * Retrieve the file type from the file name.
  2455  * Retrieve the file type from the file name.
  2234  *
  2456  *
  2239  * @param string $filename File name or path.
  2461  * @param string $filename File name or path.
  2240  * @param array  $mimes    Optional. Key is the file extension with value as the mime type.
  2462  * @param array  $mimes    Optional. Key is the file extension with value as the mime type.
  2241  * @return array Values with extension first and mime type.
  2463  * @return array Values with extension first and mime type.
  2242  */
  2464  */
  2243 function wp_check_filetype( $filename, $mimes = null ) {
  2465 function wp_check_filetype( $filename, $mimes = null ) {
  2244 	if ( empty($mimes) )
  2466 	if ( empty( $mimes ) ) {
  2245 		$mimes = get_allowed_mime_types();
  2467 		$mimes = get_allowed_mime_types();
       
  2468 	}
  2246 	$type = false;
  2469 	$type = false;
  2247 	$ext = false;
  2470 	$ext  = false;
  2248 
  2471 
  2249 	foreach ( $mimes as $ext_preg => $mime_match ) {
  2472 	foreach ( $mimes as $ext_preg => $mime_match ) {
  2250 		$ext_preg = '!\.(' . $ext_preg . ')$!i';
  2473 		$ext_preg = '!\.(' . $ext_preg . ')$!i';
  2251 		if ( preg_match( $ext_preg, $filename, $ext_matches ) ) {
  2474 		if ( preg_match( $ext_preg, $filename, $ext_matches ) ) {
  2252 			$type = $mime_match;
  2475 			$type = $mime_match;
  2253 			$ext = $ext_matches[1];
  2476 			$ext  = $ext_matches[1];
  2254 			break;
  2477 			break;
  2255 		}
  2478 		}
  2256 	}
  2479 	}
  2257 
  2480 
  2258 	return compact( 'ext', 'type' );
  2481 	return compact( 'ext', 'type' );
  2280 function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
  2503 function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
  2281 	$proper_filename = false;
  2504 	$proper_filename = false;
  2282 
  2505 
  2283 	// Do basic extension validation and MIME mapping
  2506 	// Do basic extension validation and MIME mapping
  2284 	$wp_filetype = wp_check_filetype( $filename, $mimes );
  2507 	$wp_filetype = wp_check_filetype( $filename, $mimes );
  2285 	$ext = $wp_filetype['ext'];
  2508 	$ext         = $wp_filetype['ext'];
  2286 	$type = $wp_filetype['type'];
  2509 	$type        = $wp_filetype['type'];
  2287 
  2510 
  2288 	// We can't do any further validation without a file to work with
  2511 	// We can't do any further validation without a file to work with
  2289 	if ( ! file_exists( $file ) ) {
  2512 	if ( ! file_exists( $file ) ) {
  2290 		return compact( 'ext', 'type', 'proper_filename' );
  2513 		return compact( 'ext', 'type', 'proper_filename' );
  2291 	}
  2514 	}
  2304 			 *
  2527 			 *
  2305 			 * @since 3.0.0
  2528 			 * @since 3.0.0
  2306 			 *
  2529 			 *
  2307 			 * @param  array $mime_to_ext Array of image mime types and their matching extensions.
  2530 			 * @param  array $mime_to_ext Array of image mime types and their matching extensions.
  2308 			 */
  2531 			 */
  2309 			$mime_to_ext = apply_filters( 'getimagesize_mimes_to_exts', array(
  2532 			$mime_to_ext = apply_filters(
  2310 				'image/jpeg' => 'jpg',
  2533 				'getimagesize_mimes_to_exts',
  2311 				'image/png'  => 'png',
  2534 				array(
  2312 				'image/gif'  => 'gif',
  2535 					'image/jpeg' => 'jpg',
  2313 				'image/bmp'  => 'bmp',
  2536 					'image/png'  => 'png',
  2314 				'image/tiff' => 'tif',
  2537 					'image/gif'  => 'gif',
  2315 			) );
  2538 					'image/bmp'  => 'bmp',
       
  2539 					'image/tiff' => 'tif',
       
  2540 				)
       
  2541 			);
  2316 
  2542 
  2317 			// Replace whatever is after the last period in the filename with the correct extension
  2543 			// Replace whatever is after the last period in the filename with the correct extension
  2318 			if ( ! empty( $mime_to_ext[ $real_mime ] ) ) {
  2544 			if ( ! empty( $mime_to_ext[ $real_mime ] ) ) {
  2319 				$filename_parts = explode( '.', $filename );
  2545 				$filename_parts = explode( '.', $filename );
  2320 				array_pop( $filename_parts );
  2546 				array_pop( $filename_parts );
  2321 				$filename_parts[] = $mime_to_ext[ $real_mime ];
  2547 				$filename_parts[] = $mime_to_ext[ $real_mime ];
  2322 				$new_filename = implode( '.', $filename_parts );
  2548 				$new_filename     = implode( '.', $filename_parts );
  2323 
  2549 
  2324 				if ( $new_filename != $filename ) {
  2550 				if ( $new_filename != $filename ) {
  2325 					$proper_filename = $new_filename; // Mark that it changed
  2551 					$proper_filename = $new_filename; // Mark that it changed
  2326 				}
  2552 				}
  2327 				// Redefine the extension / MIME
  2553 				// Redefine the extension / MIME
  2328 				$wp_filetype = wp_check_filetype( $new_filename, $mimes );
  2554 				$wp_filetype = wp_check_filetype( $new_filename, $mimes );
  2329 				$ext = $wp_filetype['ext'];
  2555 				$ext         = $wp_filetype['ext'];
  2330 				$type = $wp_filetype['type'];
  2556 				$type        = $wp_filetype['type'];
  2331 			} else {
  2557 			} else {
  2332 				// Reset $real_mime and try validating again.
  2558 				// Reset $real_mime and try validating again.
  2333 				$real_mime = false;
  2559 				$real_mime = false;
  2334 			}
  2560 			}
  2335 		}
  2561 		}
  2336 	}
  2562 	}
  2337 
  2563 
  2338 	// Validate files that didn't get validated during previous checks.
  2564 	// Validate files that didn't get validated during previous checks.
  2339 	if ( $type && ! $real_mime && extension_loaded( 'fileinfo' ) ) {
  2565 	if ( $type && ! $real_mime && extension_loaded( 'fileinfo' ) ) {
  2340 		$finfo = finfo_open( FILEINFO_MIME_TYPE );
  2566 		$finfo     = finfo_open( FILEINFO_MIME_TYPE );
  2341 		$real_mime = finfo_file( $finfo, $file );
  2567 		$real_mime = finfo_file( $finfo, $file );
  2342 		finfo_close( $finfo );
  2568 		finfo_close( $finfo );
  2343 
  2569 
       
  2570 		// fileinfo often misidentifies obscure files as one of these types
       
  2571 		$nonspecific_types = array(
       
  2572 			'application/octet-stream',
       
  2573 			'application/encrypted',
       
  2574 			'application/CDFV2-encrypted',
       
  2575 			'application/zip',
       
  2576 		);
       
  2577 
  2344 		/*
  2578 		/*
  2345 		 * If $real_mime doesn't match what we're expecting, we need to do some extra
  2579 		 * If $real_mime doesn't match the content type we're expecting from the file's extension,
  2346 		 * vetting of application mime types to make sure this type of file is allowed.
  2580 		 * we need to do some additional vetting. Media types and those listed in $nonspecific_types are
  2347 		 * Other mime types are assumed to be safe, but should be considered unverified.
  2581 		 * allowed some leeway, but anything else must exactly match the real content type.
  2348 		 */
  2582 		 */
  2349 		if ( $real_mime && ( $real_mime !== $type ) && ( 0 === strpos( $real_mime, 'application' ) ) ) {
  2583 		if ( in_array( $real_mime, $nonspecific_types, true ) ) {
  2350 			$allowed = get_allowed_mime_types();
  2584 			// File is a non-specific binary type. That's ok if it's a type that generally tends to be binary.
  2351 
  2585 			if ( ! in_array( substr( $type, 0, strcspn( $type, '/' ) ), array( 'application', 'video', 'audio' ) ) ) {
  2352 			if ( ! in_array( $real_mime, $allowed ) ) {
       
  2353 				$type = $ext = false;
  2586 				$type = $ext = false;
  2354 			}
  2587 			}
       
  2588 		} elseif ( 0 === strpos( $real_mime, 'video/' ) || 0 === strpos( $real_mime, 'audio/' ) ) {
       
  2589 			/*
       
  2590 			 * For these types, only the major type must match the real value.
       
  2591 			 * This means that common mismatches are forgiven: application/vnd.apple.numbers is often misidentified as application/zip,
       
  2592 			 * and some media files are commonly named with the wrong extension (.mov instead of .mp4)
       
  2593 			 */
       
  2594 			if ( substr( $real_mime, 0, strcspn( $real_mime, '/' ) ) !== substr( $type, 0, strcspn( $type, '/' ) ) ) {
       
  2595 				$type = $ext = false;
       
  2596 			}
       
  2597 		} elseif ( 'text/plain' === $real_mime ) {
       
  2598 			// A few common file types are occasionally detected as text/plain; allow those.
       
  2599 			if ( ! in_array(
       
  2600 				$type,
       
  2601 				array(
       
  2602 					'text/plain',
       
  2603 					'text/csv',
       
  2604 					'text/richtext',
       
  2605 					'text/tsv',
       
  2606 					'text/vtt',
       
  2607 				)
       
  2608 			)
       
  2609 			) {
       
  2610 				$type = $ext = false;
       
  2611 			}
       
  2612 		} elseif ( 'text/rtf' === $real_mime ) {
       
  2613 			// Special casing for RTF files.
       
  2614 			if ( ! in_array(
       
  2615 				$type,
       
  2616 				array(
       
  2617 					'text/rtf',
       
  2618 					'text/plain',
       
  2619 					'application/rtf',
       
  2620 				)
       
  2621 			)
       
  2622 			) {
       
  2623 				$type = $ext = false;
       
  2624 			}
       
  2625 		} else {
       
  2626 			if ( $type !== $real_mime ) {
       
  2627 				/*
       
  2628 				 * Everything else including image/* and application/*:
       
  2629 				 * If the real content type doesn't match the file extension, assume it's dangerous.
       
  2630 				 */
       
  2631 				$type = $ext = false;
       
  2632 			}
       
  2633 		}
       
  2634 	}
       
  2635 
       
  2636 	// The mime type must be allowed
       
  2637 	if ( $type ) {
       
  2638 		$allowed = get_allowed_mime_types();
       
  2639 
       
  2640 		if ( ! in_array( $type, $allowed ) ) {
       
  2641 			$type = $ext = false;
  2355 		}
  2642 		}
  2356 	}
  2643 	}
  2357 
  2644 
  2358 	/**
  2645 	/**
  2359 	 * Filters the "real" file type of the given file.
  2646 	 * Filters the "real" file type of the given file.
  2360 	 *
  2647 	 *
  2361 	 * @since 3.0.0
  2648 	 * @since 3.0.0
  2362 	 *
  2649 	 * @since 5.1.0 The $real_mime parameter was added.
  2363 	 * @param array  $wp_check_filetype_and_ext File data array containing 'ext', 'type', and
  2650 	 *
  2364 	 *                                          'proper_filename' keys.
  2651 	 * @param array       $wp_check_filetype_and_ext File data array containing 'ext', 'type', and
  2365 	 * @param string $file                      Full path to the file.
  2652 	 *                                               'proper_filename' keys.
  2366 	 * @param string $filename                  The name of the file (may differ from $file due to
  2653 	 * @param string      $file                      Full path to the file.
  2367 	 *                                          $file being in a tmp directory).
  2654 	 * @param string      $filename                  The name of the file (may differ from $file due to
  2368 	 * @param array  $mimes                     Key is the file extension with value as the mime type.
  2655 	 *                                               $file being in a tmp directory).
       
  2656 	 * @param array       $mimes                     Key is the file extension with value as the mime type.
       
  2657 	 * @param string|bool $real_mime                 The actual mime type or false if the type cannot be determined.
  2369 	 */
  2658 	 */
  2370 	return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes );
  2659 	return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes, $real_mime );
  2371 }
  2660 }
  2372 
  2661 
  2373 /**
  2662 /**
  2374  * Returns the real mime type of an image file.
  2663  * Returns the real mime type of an image file.
  2375  *
  2664  *
  2387 	 * we assume the file could not be validated.
  2676 	 * we assume the file could not be validated.
  2388 	 */
  2677 	 */
  2389 	try {
  2678 	try {
  2390 		if ( is_callable( 'exif_imagetype' ) ) {
  2679 		if ( is_callable( 'exif_imagetype' ) ) {
  2391 			$imagetype = exif_imagetype( $file );
  2680 			$imagetype = exif_imagetype( $file );
  2392 			$mime = ( $imagetype ) ? image_type_to_mime_type( $imagetype ) : false;
  2681 			$mime      = ( $imagetype ) ? image_type_to_mime_type( $imagetype ) : false;
  2393 		} elseif ( function_exists( 'getimagesize' ) ) {
  2682 		} elseif ( function_exists( 'getimagesize' ) ) {
  2394 			$imagesize = getimagesize( $file );
  2683 			$imagesize = getimagesize( $file );
  2395 			$mime = ( isset( $imagesize['mime'] ) ) ? $imagesize['mime'] : false;
  2684 			$mime      = ( isset( $imagesize['mime'] ) ) ? $imagesize['mime'] : false;
  2396 		} else {
  2685 		} else {
  2397 			$mime = false;
  2686 			$mime = false;
  2398 		}
  2687 		}
  2399 	} catch ( Exception $e ) {
  2688 	} catch ( Exception $e ) {
  2400 		$mime = false;
  2689 		$mime = false;
  2421 	 * @since 3.5.0
  2710 	 * @since 3.5.0
  2422 	 *
  2711 	 *
  2423 	 * @param array $wp_get_mime_types Mime types keyed by the file extension regex
  2712 	 * @param array $wp_get_mime_types Mime types keyed by the file extension regex
  2424 	 *                                 corresponding to those types.
  2713 	 *                                 corresponding to those types.
  2425 	 */
  2714 	 */
  2426 	return apply_filters( 'mime_types', array(
  2715 	return apply_filters(
  2427 	// Image formats.
  2716 		'mime_types',
  2428 	'jpg|jpeg|jpe' => 'image/jpeg',
  2717 		array(
  2429 	'gif' => 'image/gif',
  2718 			// Image formats.
  2430 	'png' => 'image/png',
  2719 			'jpg|jpeg|jpe'                 => 'image/jpeg',
  2431 	'bmp' => 'image/bmp',
  2720 			'gif'                          => 'image/gif',
  2432 	'tiff|tif' => 'image/tiff',
  2721 			'png'                          => 'image/png',
  2433 	'ico' => 'image/x-icon',
  2722 			'bmp'                          => 'image/bmp',
  2434 	// Video formats.
  2723 			'tiff|tif'                     => 'image/tiff',
  2435 	'asf|asx' => 'video/x-ms-asf',
  2724 			'ico'                          => 'image/x-icon',
  2436 	'wmv' => 'video/x-ms-wmv',
  2725 			// Video formats.
  2437 	'wmx' => 'video/x-ms-wmx',
  2726 			'asf|asx'                      => 'video/x-ms-asf',
  2438 	'wm' => 'video/x-ms-wm',
  2727 			'wmv'                          => 'video/x-ms-wmv',
  2439 	'avi' => 'video/avi',
  2728 			'wmx'                          => 'video/x-ms-wmx',
  2440 	'divx' => 'video/divx',
  2729 			'wm'                           => 'video/x-ms-wm',
  2441 	'flv' => 'video/x-flv',
  2730 			'avi'                          => 'video/avi',
  2442 	'mov|qt' => 'video/quicktime',
  2731 			'divx'                         => 'video/divx',
  2443 	'mpeg|mpg|mpe' => 'video/mpeg',
  2732 			'flv'                          => 'video/x-flv',
  2444 	'mp4|m4v' => 'video/mp4',
  2733 			'mov|qt'                       => 'video/quicktime',
  2445 	'ogv' => 'video/ogg',
  2734 			'mpeg|mpg|mpe'                 => 'video/mpeg',
  2446 	'webm' => 'video/webm',
  2735 			'mp4|m4v'                      => 'video/mp4',
  2447 	'mkv' => 'video/x-matroska',
  2736 			'ogv'                          => 'video/ogg',
  2448 	'3gp|3gpp' => 'video/3gpp', // Can also be audio
  2737 			'webm'                         => 'video/webm',
  2449 	'3g2|3gp2' => 'video/3gpp2', // Can also be audio
  2738 			'mkv'                          => 'video/x-matroska',
  2450 	// Text formats.
  2739 			'3gp|3gpp'                     => 'video/3gpp', // Can also be audio
  2451 	'txt|asc|c|cc|h|srt' => 'text/plain',
  2740 			'3g2|3gp2'                     => 'video/3gpp2', // Can also be audio
  2452 	'csv' => 'text/csv',
  2741 			// Text formats.
  2453 	'tsv' => 'text/tab-separated-values',
  2742 			'txt|asc|c|cc|h|srt'           => 'text/plain',
  2454 	'ics' => 'text/calendar',
  2743 			'csv'                          => 'text/csv',
  2455 	'rtx' => 'text/richtext',
  2744 			'tsv'                          => 'text/tab-separated-values',
  2456 	'css' => 'text/css',
  2745 			'ics'                          => 'text/calendar',
  2457 	'htm|html' => 'text/html',
  2746 			'rtx'                          => 'text/richtext',
  2458 	'vtt' => 'text/vtt',
  2747 			'css'                          => 'text/css',
  2459 	'dfxp' => 'application/ttaf+xml',
  2748 			'htm|html'                     => 'text/html',
  2460 	// Audio formats.
  2749 			'vtt'                          => 'text/vtt',
  2461 	'mp3|m4a|m4b' => 'audio/mpeg',
  2750 			'dfxp'                         => 'application/ttaf+xml',
  2462 	'aac' => 'audio/aac',
  2751 			// Audio formats.
  2463 	'ra|ram' => 'audio/x-realaudio',
  2752 			'mp3|m4a|m4b'                  => 'audio/mpeg',
  2464 	'wav' => 'audio/wav',
  2753 			'aac'                          => 'audio/aac',
  2465 	'ogg|oga' => 'audio/ogg',
  2754 			'ra|ram'                       => 'audio/x-realaudio',
  2466 	'flac' => 'audio/flac',
  2755 			'wav'                          => 'audio/wav',
  2467 	'mid|midi' => 'audio/midi',
  2756 			'ogg|oga'                      => 'audio/ogg',
  2468 	'wma' => 'audio/x-ms-wma',
  2757 			'flac'                         => 'audio/flac',
  2469 	'wax' => 'audio/x-ms-wax',
  2758 			'mid|midi'                     => 'audio/midi',
  2470 	'mka' => 'audio/x-matroska',
  2759 			'wma'                          => 'audio/x-ms-wma',
  2471 	// Misc application formats.
  2760 			'wax'                          => 'audio/x-ms-wax',
  2472 	'rtf' => 'application/rtf',
  2761 			'mka'                          => 'audio/x-matroska',
  2473 	'js' => 'application/javascript',
  2762 			// Misc application formats.
  2474 	'pdf' => 'application/pdf',
  2763 			'rtf'                          => 'application/rtf',
  2475 	'swf' => 'application/x-shockwave-flash',
  2764 			'js'                           => 'application/javascript',
  2476 	'class' => 'application/java',
  2765 			'pdf'                          => 'application/pdf',
  2477 	'tar' => 'application/x-tar',
  2766 			'swf'                          => 'application/x-shockwave-flash',
  2478 	'zip' => 'application/zip',
  2767 			'class'                        => 'application/java',
  2479 	'gz|gzip' => 'application/x-gzip',
  2768 			'tar'                          => 'application/x-tar',
  2480 	'rar' => 'application/rar',
  2769 			'zip'                          => 'application/zip',
  2481 	'7z' => 'application/x-7z-compressed',
  2770 			'gz|gzip'                      => 'application/x-gzip',
  2482 	'exe' => 'application/x-msdownload',
  2771 			'rar'                          => 'application/rar',
  2483 	'psd' => 'application/octet-stream',
  2772 			'7z'                           => 'application/x-7z-compressed',
  2484 	'xcf' => 'application/octet-stream',
  2773 			'exe'                          => 'application/x-msdownload',
  2485 	// MS Office formats.
  2774 			'psd'                          => 'application/octet-stream',
  2486 	'doc' => 'application/msword',
  2775 			'xcf'                          => 'application/octet-stream',
  2487 	'pot|pps|ppt' => 'application/vnd.ms-powerpoint',
  2776 			// MS Office formats.
  2488 	'wri' => 'application/vnd.ms-write',
  2777 			'doc'                          => 'application/msword',
  2489 	'xla|xls|xlt|xlw' => 'application/vnd.ms-excel',
  2778 			'pot|pps|ppt'                  => 'application/vnd.ms-powerpoint',
  2490 	'mdb' => 'application/vnd.ms-access',
  2779 			'wri'                          => 'application/vnd.ms-write',
  2491 	'mpp' => 'application/vnd.ms-project',
  2780 			'xla|xls|xlt|xlw'              => 'application/vnd.ms-excel',
  2492 	'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
  2781 			'mdb'                          => 'application/vnd.ms-access',
  2493 	'docm' => 'application/vnd.ms-word.document.macroEnabled.12',
  2782 			'mpp'                          => 'application/vnd.ms-project',
  2494 	'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
  2783 			'docx'                         => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
  2495 	'dotm' => 'application/vnd.ms-word.template.macroEnabled.12',
  2784 			'docm'                         => 'application/vnd.ms-word.document.macroEnabled.12',
  2496 	'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  2785 			'dotx'                         => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
  2497 	'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12',
  2786 			'dotm'                         => 'application/vnd.ms-word.template.macroEnabled.12',
  2498 	'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
  2787 			'xlsx'                         => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  2499 	'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
  2788 			'xlsm'                         => 'application/vnd.ms-excel.sheet.macroEnabled.12',
  2500 	'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12',
  2789 			'xlsb'                         => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
  2501 	'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',
  2790 			'xltx'                         => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
  2502 	'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
  2791 			'xltm'                         => 'application/vnd.ms-excel.template.macroEnabled.12',
  2503 	'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12',
  2792 			'xlam'                         => 'application/vnd.ms-excel.addin.macroEnabled.12',
  2504 	'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
  2793 			'pptx'                         => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
  2505 	'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12',
  2794 			'pptm'                         => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12',
  2506 	'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
  2795 			'ppsx'                         => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
  2507 	'potm' => 'application/vnd.ms-powerpoint.template.macroEnabled.12',
  2796 			'ppsm'                         => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12',
  2508 	'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12',
  2797 			'potx'                         => 'application/vnd.openxmlformats-officedocument.presentationml.template',
  2509 	'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
  2798 			'potm'                         => 'application/vnd.ms-powerpoint.template.macroEnabled.12',
  2510 	'sldm' => 'application/vnd.ms-powerpoint.slide.macroEnabled.12',
  2799 			'ppam'                         => 'application/vnd.ms-powerpoint.addin.macroEnabled.12',
  2511 	'onetoc|onetoc2|onetmp|onepkg' => 'application/onenote',
  2800 			'sldx'                         => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
  2512 	'oxps' => 'application/oxps',
  2801 			'sldm'                         => 'application/vnd.ms-powerpoint.slide.macroEnabled.12',
  2513 	'xps' => 'application/vnd.ms-xpsdocument',
  2802 			'onetoc|onetoc2|onetmp|onepkg' => 'application/onenote',
  2514 	// OpenOffice formats.
  2803 			'oxps'                         => 'application/oxps',
  2515 	'odt' => 'application/vnd.oasis.opendocument.text',
  2804 			'xps'                          => 'application/vnd.ms-xpsdocument',
  2516 	'odp' => 'application/vnd.oasis.opendocument.presentation',
  2805 			// OpenOffice formats.
  2517 	'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
  2806 			'odt'                          => 'application/vnd.oasis.opendocument.text',
  2518 	'odg' => 'application/vnd.oasis.opendocument.graphics',
  2807 			'odp'                          => 'application/vnd.oasis.opendocument.presentation',
  2519 	'odc' => 'application/vnd.oasis.opendocument.chart',
  2808 			'ods'                          => 'application/vnd.oasis.opendocument.spreadsheet',
  2520 	'odb' => 'application/vnd.oasis.opendocument.database',
  2809 			'odg'                          => 'application/vnd.oasis.opendocument.graphics',
  2521 	'odf' => 'application/vnd.oasis.opendocument.formula',
  2810 			'odc'                          => 'application/vnd.oasis.opendocument.chart',
  2522 	// WordPerfect formats.
  2811 			'odb'                          => 'application/vnd.oasis.opendocument.database',
  2523 	'wp|wpd' => 'application/wordperfect',
  2812 			'odf'                          => 'application/vnd.oasis.opendocument.formula',
  2524 	// iWork formats.
  2813 			// WordPerfect formats.
  2525 	'key' => 'application/vnd.apple.keynote',
  2814 			'wp|wpd'                       => 'application/wordperfect',
  2526 	'numbers' => 'application/vnd.apple.numbers',
  2815 			// iWork formats.
  2527 	'pages' => 'application/vnd.apple.pages',
  2816 			'key'                          => 'application/vnd.apple.keynote',
  2528 	) );
  2817 			'numbers'                      => 'application/vnd.apple.numbers',
       
  2818 			'pages'                        => 'application/vnd.apple.pages',
       
  2819 		)
       
  2820 	);
  2529 }
  2821 }
  2530 
  2822 
  2531 /**
  2823 /**
  2532  * Retrieves the list of common file extensions and their types.
  2824  * Retrieves the list of common file extensions and their types.
  2533  *
  2825  *
  2545 	 * @see wp_ext2type()
  2837 	 * @see wp_ext2type()
  2546 	 *
  2838 	 *
  2547 	 * @param array $ext2type Multi-dimensional array with extensions for a default set
  2839 	 * @param array $ext2type Multi-dimensional array with extensions for a default set
  2548 	 *                        of file types.
  2840 	 *                        of file types.
  2549 	 */
  2841 	 */
  2550 	return apply_filters( 'ext2type', array(
  2842 	return apply_filters(
  2551 		'image'       => array( 'jpg', 'jpeg', 'jpe',  'gif',  'png',  'bmp',   'tif',  'tiff', 'ico' ),
  2843 		'ext2type',
  2552 		'audio'       => array( 'aac', 'ac3',  'aif',  'aiff', 'flac', 'm3a',  'm4a',   'm4b',  'mka',  'mp1',  'mp2',  'mp3', 'ogg', 'oga', 'ram', 'wav', 'wma' ),
  2844 		array(
  2553 		'video'       => array( '3g2',  '3gp', '3gpp', 'asf', 'avi',  'divx', 'dv',   'flv',  'm4v',   'mkv',  'mov',  'mp4',  'mpeg', 'mpg', 'mpv', 'ogm', 'ogv', 'qt',  'rm', 'vob', 'wmv' ),
  2845 			'image'       => array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'bmp', 'tif', 'tiff', 'ico' ),
  2554 		'document'    => array( 'doc', 'docx', 'docm', 'dotm', 'odt',  'pages', 'pdf',  'xps',  'oxps', 'rtf',  'wp', 'wpd', 'psd', 'xcf' ),
  2846 			'audio'       => array( 'aac', 'ac3', 'aif', 'aiff', 'flac', 'm3a', 'm4a', 'm4b', 'mka', 'mp1', 'mp2', 'mp3', 'ogg', 'oga', 'ram', 'wav', 'wma' ),
  2555 		'spreadsheet' => array( 'numbers',     'ods',  'xls',  'xlsx', 'xlsm',  'xlsb' ),
  2847 			'video'       => array( '3g2', '3gp', '3gpp', 'asf', 'avi', 'divx', 'dv', 'flv', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'mpv', 'ogm', 'ogv', 'qt', 'rm', 'vob', 'wmv' ),
  2556 		'interactive' => array( 'swf', 'key',  'ppt',  'pptx', 'pptm', 'pps',   'ppsx', 'ppsm', 'sldx', 'sldm', 'odp' ),
  2848 			'document'    => array( 'doc', 'docx', 'docm', 'dotm', 'odt', 'pages', 'pdf', 'xps', 'oxps', 'rtf', 'wp', 'wpd', 'psd', 'xcf' ),
  2557 		'text'        => array( 'asc', 'csv',  'tsv',  'txt' ),
  2849 			'spreadsheet' => array( 'numbers', 'ods', 'xls', 'xlsx', 'xlsm', 'xlsb' ),
  2558 		'archive'     => array( 'bz2', 'cab',  'dmg',  'gz',   'rar',  'sea',   'sit',  'sqx',  'tar',  'tgz',  'zip', '7z' ),
  2850 			'interactive' => array( 'swf', 'key', 'ppt', 'pptx', 'pptm', 'pps', 'ppsx', 'ppsm', 'sldx', 'sldm', 'odp' ),
  2559 		'code'        => array( 'css', 'htm',  'html', 'php',  'js' ),
  2851 			'text'        => array( 'asc', 'csv', 'tsv', 'txt' ),
  2560 	) );
  2852 			'archive'     => array( 'bz2', 'cab', 'dmg', 'gz', 'rar', 'sea', 'sit', 'sqx', 'tar', 'tgz', 'zip', '7z' ),
       
  2853 			'code'        => array( 'css', 'htm', 'html', 'php', 'js' ),
       
  2854 		)
       
  2855 	);
  2561 }
  2856 }
  2562 
  2857 
  2563 /**
  2858 /**
  2564  * Retrieve list of allowed mime types and file extensions.
  2859  * Retrieve list of allowed mime types and file extensions.
  2565  *
  2860  *
  2571  */
  2866  */
  2572 function get_allowed_mime_types( $user = null ) {
  2867 function get_allowed_mime_types( $user = null ) {
  2573 	$t = wp_get_mime_types();
  2868 	$t = wp_get_mime_types();
  2574 
  2869 
  2575 	unset( $t['swf'], $t['exe'] );
  2870 	unset( $t['swf'], $t['exe'] );
  2576 	if ( function_exists( 'current_user_can' ) )
  2871 	if ( function_exists( 'current_user_can' ) ) {
  2577 		$unfiltered = $user ? user_can( $user, 'unfiltered_html' ) : current_user_can( 'unfiltered_html' );
  2872 		$unfiltered = $user ? user_can( $user, 'unfiltered_html' ) : current_user_can( 'unfiltered_html' );
       
  2873 	}
  2578 
  2874 
  2579 	if ( empty( $unfiltered ) ) {
  2875 	if ( empty( $unfiltered ) ) {
  2580 		unset( $t['htm|html'], $t['js'] );
  2876 		unset( $t['htm|html'], $t['js'] );
  2581 	}
  2877 	}
  2582 
  2878 
  2608 		$html = sprintf(
  2904 		$html = sprintf(
  2609 			/* translators: %s: site name */
  2905 			/* translators: %s: site name */
  2610 			__( 'You are attempting to log out of %s' ),
  2906 			__( 'You are attempting to log out of %s' ),
  2611 			get_bloginfo( 'name' )
  2907 			get_bloginfo( 'name' )
  2612 		);
  2908 		);
  2613 		$html .= '</p><p>';
  2909 		$html       .= '</p><p>';
  2614 		$redirect_to = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '';
  2910 		$redirect_to = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '';
  2615 		$html .= sprintf(
  2911 		$html       .= sprintf(
  2616 			/* translators: %s: logout URL */
  2912 			/* translators: %s: logout URL */
  2617 			__( 'Do you really want to <a href="%s">log out</a>?' ),
  2913 			__( 'Do you really want to <a href="%s">log out</a>?' ),
  2618 			wp_logout_url( $redirect_to )
  2914 			wp_logout_url( $redirect_to )
  2619 		);
  2915 		);
  2620 	} else {
  2916 	} else {
  2621 		$html = __( 'The link you followed has expired.' );
  2917 		$html = __( 'The link you followed has expired.' );
  2622 		if ( wp_get_referer() ) {
  2918 		if ( wp_get_referer() ) {
  2623 			$html .= '</p><p>';
  2919 			$html .= '</p><p>';
  2624 			$html .= sprintf( '<a href="%s">%s</a>',
  2920 			$html .= sprintf(
       
  2921 				'<a href="%s">%s</a>',
  2625 				esc_url( remove_query_arg( 'updated', wp_get_referer() ) ),
  2922 				esc_url( remove_query_arg( 'updated', wp_get_referer() ) ),
  2626 				__( 'Please try again.' )
  2923 				__( 'Please try again.' )
  2627 			);
  2924 			);
  2628 		}
  2925 		}
  2629 	}
  2926 	}
  2630 
  2927 
  2631 	wp_die( $html, __( 'Something went wrong.' ), 403 );
  2928 	wp_die( $html, __( 'Something went wrong.' ), 403 );
  2632 }
  2929 }
  2633 
  2930 
  2634 /**
  2931 /**
  2635  * Kill WordPress execution and display HTML message with error message.
  2932  * Kills WordPress execution and displays HTML page with an error message.
  2636  *
  2933  *
  2637  * This function complements the `die()` PHP function. The difference is that
  2934  * This function complements the `die()` PHP function. The difference is that
  2638  * HTML will be displayed to the user. It is recommended to use this function
  2935  * HTML will be displayed to the user. It is recommended to use this function
  2639  * only when the execution should not continue any further. It is not recommended
  2936  * only when the execution should not continue any further. It is not recommended
  2640  * to call this function very often, and try to handle as many errors as possible
  2937  * to call this function very often, and try to handle as many errors as possible
  2644  * the `$title` parameter (the default title would apply) or the `$args` parameter.
  2941  * the `$title` parameter (the default title would apply) or the `$args` parameter.
  2645  *
  2942  *
  2646  * @since 2.0.4
  2943  * @since 2.0.4
  2647  * @since 4.1.0 The `$title` and `$args` parameters were changed to optionally accept
  2944  * @since 4.1.0 The `$title` and `$args` parameters were changed to optionally accept
  2648  *              an integer to be used as the response code.
  2945  *              an integer to be used as the response code.
       
  2946  * @since 5.1.0 The `$link_url`, `$link_text`, and `$exit` arguments were added.
       
  2947  *
       
  2948  * @global WP_Query $wp_query Global WP_Query instance.
  2649  *
  2949  *
  2650  * @param string|WP_Error  $message Optional. Error message. If this is a WP_Error object,
  2950  * @param string|WP_Error  $message Optional. Error message. If this is a WP_Error object,
  2651  *                                  and not an Ajax or XML-RPC request, the error's messages are used.
  2951  *                                  and not an Ajax or XML-RPC request, the error's messages are used.
  2652  *                                  Default empty.
  2952  *                                  Default empty.
  2653  * @param string|int       $title   Optional. Error title. If `$message` is a `WP_Error` object,
  2953  * @param string|int       $title   Optional. Error title. If `$message` is a `WP_Error` object,
  2657  * @param string|array|int $args {
  2957  * @param string|array|int $args {
  2658  *     Optional. Arguments to control behavior. If `$args` is an integer, then it is treated
  2958  *     Optional. Arguments to control behavior. If `$args` is an integer, then it is treated
  2659  *     as the response code. Default empty array.
  2959  *     as the response code. Default empty array.
  2660  *
  2960  *
  2661  *     @type int    $response       The HTTP response code. Default 200 for Ajax requests, 500 otherwise.
  2961  *     @type int    $response       The HTTP response code. Default 200 for Ajax requests, 500 otherwise.
       
  2962  *     @type string $link_url       A URL to include a link to. Only works in combination with $link_text.
       
  2963  *                                  Default empty string.
       
  2964  *     @type string $link_text      A label for the link to include. Only works in combination with $link_url.
       
  2965  *                                  Default empty string.
  2662  *     @type bool   $back_link      Whether to include a link to go back. Default false.
  2966  *     @type bool   $back_link      Whether to include a link to go back. Default false.
  2663  *     @type string $text_direction The text direction. This is only useful internally, when WordPress
  2967  *     @type string $text_direction The text direction. This is only useful internally, when WordPress
  2664  *                                  is still loading and the site's locale is not set up yet. Accepts 'rtl'.
  2968  *                                  is still loading and the site's locale is not set up yet. Accepts 'rtl'.
  2665  *                                  Default is the value of is_rtl().
  2969  *                                  Default is the value of is_rtl().
       
  2970  *     @type string $code           Error code to use. Default is 'wp_die', or the main error code if $message
       
  2971  *                                  is a WP_Error.
       
  2972  *     @type bool   $exit           Whether to exit the process after completion. Default true.
  2666  * }
  2973  * }
  2667  */
  2974  */
  2668 function wp_die( $message = '', $title = '', $args = array() ) {
  2975 function wp_die( $message = '', $title = '', $args = array() ) {
       
  2976 	global $wp_query;
  2669 
  2977 
  2670 	if ( is_int( $args ) ) {
  2978 	if ( is_int( $args ) ) {
  2671 		$args = array( 'response' => $args );
  2979 		$args = array( 'response' => $args );
  2672 	} elseif ( is_int( $title ) ) {
  2980 	} elseif ( is_int( $title ) ) {
  2673 		$args  = array( 'response' => $title );
  2981 		$args  = array( 'response' => $title );
  2681 		 * @since 3.4.0
  2989 		 * @since 3.4.0
  2682 		 *
  2990 		 *
  2683 		 * @param callable $function Callback function name.
  2991 		 * @param callable $function Callback function name.
  2684 		 */
  2992 		 */
  2685 		$function = apply_filters( 'wp_die_ajax_handler', '_ajax_wp_die_handler' );
  2993 		$function = apply_filters( 'wp_die_ajax_handler', '_ajax_wp_die_handler' );
       
  2994 	} elseif ( wp_is_json_request() ) {
       
  2995 		/**
       
  2996 		 * Filters the callback for killing WordPress execution for JSON requests.
       
  2997 		 *
       
  2998 		 * @since 5.1.0
       
  2999 		 *
       
  3000 		 * @param callable $function Callback function name.
       
  3001 		 */
       
  3002 		$function = apply_filters( 'wp_die_json_handler', '_json_wp_die_handler' );
       
  3003 	} elseif ( wp_is_jsonp_request() ) {
       
  3004 		/**
       
  3005 		 * Filters the callback for killing WordPress execution for JSONP requests.
       
  3006 		 *
       
  3007 		 * @since 5.2.0
       
  3008 		 *
       
  3009 		 * @param callable $function Callback function name.
       
  3010 		 */
       
  3011 		$function = apply_filters( 'wp_die_jsonp_handler', '_jsonp_wp_die_handler' );
  2686 	} elseif ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) {
  3012 	} elseif ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) {
  2687 		/**
  3013 		/**
  2688 		 * Filters the callback for killing WordPress execution for XML-RPC requests.
  3014 		 * Filters the callback for killing WordPress execution for XML-RPC requests.
  2689 		 *
  3015 		 *
  2690 		 * @since 3.4.0
  3016 		 * @since 3.4.0
  2691 		 *
  3017 		 *
  2692 		 * @param callable $function Callback function name.
  3018 		 * @param callable $function Callback function name.
  2693 		 */
  3019 		 */
  2694 		$function = apply_filters( 'wp_die_xmlrpc_handler', '_xmlrpc_wp_die_handler' );
  3020 		$function = apply_filters( 'wp_die_xmlrpc_handler', '_xmlrpc_wp_die_handler' );
       
  3021 	} elseif ( wp_is_xml_request()
       
  3022 		|| isset( $wp_query ) &&
       
  3023 			( function_exists( 'is_feed' ) && is_feed()
       
  3024 			|| function_exists( 'is_comment_feed' ) && is_comment_feed()
       
  3025 			|| function_exists( 'is_trackback' ) && is_trackback() ) ) {
       
  3026 		/**
       
  3027 		 * Filters the callback for killing WordPress execution for XML requests.
       
  3028 		 *
       
  3029 		 * @since 5.2.0
       
  3030 		 *
       
  3031 		 * @param callable $function Callback function name.
       
  3032 		 */
       
  3033 		$function = apply_filters( 'wp_die_xml_handler', '_xml_wp_die_handler' );
  2695 	} else {
  3034 	} else {
  2696 		/**
  3035 		/**
  2697 		 * Filters the callback for killing WordPress execution for all non-Ajax, non-XML-RPC requests.
  3036 		 * Filters the callback for killing WordPress execution for all non-Ajax, non-JSON, non-XML requests.
  2698 		 *
  3037 		 *
  2699 		 * @since 3.0.0
  3038 		 * @since 3.0.0
  2700 		 *
  3039 		 *
  2701 		 * @param callable $function Callback function name.
  3040 		 * @param callable $function Callback function name.
  2702 		 */
  3041 		 */
  2705 
  3044 
  2706 	call_user_func( $function, $message, $title, $args );
  3045 	call_user_func( $function, $message, $title, $args );
  2707 }
  3046 }
  2708 
  3047 
  2709 /**
  3048 /**
  2710  * Kills WordPress execution and display HTML message with error message.
  3049  * Kills WordPress execution and displays HTML page with an error message.
  2711  *
  3050  *
  2712  * This is the default handler for wp_die if you want a custom one for your
  3051  * This is the default handler for wp_die(). If you want a custom one,
  2713  * site then you can overload using the {@see 'wp_die_handler'} filter in wp_die().
  3052  * you can override this using the {@see 'wp_die_handler'} filter in wp_die().
  2714  *
  3053  *
  2715  * @since 3.0.0
  3054  * @since 3.0.0
  2716  * @access private
  3055  * @access private
  2717  *
  3056  *
  2718  * @param string|WP_Error $message Error message or WP_Error object.
  3057  * @param string|WP_Error $message Error message or WP_Error object.
  2719  * @param string          $title   Optional. Error title. Default empty.
  3058  * @param string          $title   Optional. Error title. Default empty.
  2720  * @param string|array    $args    Optional. Arguments to control behavior. Default empty array.
  3059  * @param string|array    $args    Optional. Arguments to control behavior. Default empty array.
  2721  */
  3060  */
  2722 function _default_wp_die_handler( $message, $title = '', $args = array() ) {
  3061 function _default_wp_die_handler( $message, $title = '', $args = array() ) {
  2723 	$defaults = array( 'response' => 500 );
  3062 	list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args );
  2724 	$r = wp_parse_args($args, $defaults);
  3063 
  2725 
  3064 	if ( is_string( $message ) ) {
  2726 	$have_gettext = function_exists('__');
  3065 		if ( ! empty( $r['additional_errors'] ) ) {
  2727 
  3066 			$message = array_merge(
  2728 	if ( function_exists( 'is_wp_error' ) && is_wp_error( $message ) ) {
  3067 				array( $message ),
  2729 		if ( empty( $title ) ) {
  3068 				wp_list_pluck( $r['additional_errors'], 'message' )
  2730 			$error_data = $message->get_error_data();
  3069 			);
  2731 			if ( is_array( $error_data ) && isset( $error_data['title'] ) )
  3070 			$message = "<ul>\n\t\t<li>" . join( "</li>\n\t\t<li>", $message ) . "</li>\n\t</ul>";
  2732 				$title = $error_data['title'];
  3071 		} else {
  2733 		}
  3072 			$message = "<p>$message</p>";
  2734 		$errors = $message->get_error_messages();
  3073 		}
  2735 		switch ( count( $errors ) ) {
  3074 	}
  2736 		case 0 :
  3075 
  2737 			$message = '';
  3076 	$have_gettext = function_exists( '__' );
  2738 			break;
  3077 
  2739 		case 1 :
  3078 	if ( ! empty( $r['link_url'] ) && ! empty( $r['link_text'] ) ) {
  2740 			$message = "<p>{$errors[0]}</p>";
  3079 		$link_url = $r['link_url'];
  2741 			break;
  3080 		if ( function_exists( 'esc_url' ) ) {
  2742 		default :
  3081 			$link_url = esc_url( $link_url );
  2743 			$message = "<ul>\n\t\t<li>" . join( "</li>\n\t\t<li>", $errors ) . "</li>\n\t</ul>";
  3082 		}
  2744 			break;
  3083 		$link_text = $r['link_text'];
  2745 		}
  3084 		$message  .= "\n<p><a href='{$link_url}'>{$link_text}</a></p>";
  2746 	} elseif ( is_string( $message ) ) {
       
  2747 		$message = "<p>$message</p>";
       
  2748 	}
  3085 	}
  2749 
  3086 
  2750 	if ( isset( $r['back_link'] ) && $r['back_link'] ) {
  3087 	if ( isset( $r['back_link'] ) && $r['back_link'] ) {
  2751 		$back_text = $have_gettext? __('&laquo; Back') : '&laquo; Back';
  3088 		$back_text = $have_gettext ? __( '&laquo; Back' ) : '&laquo; Back';
  2752 		$message .= "\n<p><a href='javascript:history.back()'>$back_text</a></p>";
  3089 		$message  .= "\n<p><a href='javascript:history.back()'>$back_text</a></p>";
  2753 	}
  3090 	}
  2754 
  3091 
  2755 	if ( ! did_action( 'admin_head' ) ) :
  3092 	if ( ! did_action( 'admin_head' ) ) :
  2756 		if ( !headers_sent() ) {
  3093 		if ( ! headers_sent() ) {
       
  3094 			header( 'Content-Type: text/html; charset=utf-8' );
  2757 			status_header( $r['response'] );
  3095 			status_header( $r['response'] );
  2758 			nocache_headers();
  3096 			nocache_headers();
  2759 			header( 'Content-Type: text/html; charset=utf-8' );
  3097 		}
  2760 		}
  3098 
  2761 
  3099 		$text_direction = $r['text_direction'];
  2762 		if ( empty($title) )
  3100 		if ( function_exists( 'language_attributes' ) && function_exists( 'is_rtl' ) ) {
  2763 			$title = $have_gettext ? __('WordPress &rsaquo; Error') : 'WordPress &rsaquo; Error';
  3101 			$dir_attr = get_language_attributes();
  2764 
  3102 		} else {
  2765 		$text_direction = 'ltr';
  3103 			$dir_attr = "dir='$text_direction'";
  2766 		if ( isset($r['text_direction']) && 'rtl' == $r['text_direction'] )
  3104 		}
  2767 			$text_direction = 'rtl';
  3105 		?>
  2768 		elseif ( function_exists( 'is_rtl' ) && is_rtl() )
       
  2769 			$text_direction = 'rtl';
       
  2770 ?>
       
  2771 <!DOCTYPE html>
  3106 <!DOCTYPE html>
  2772 <html xmlns="http://www.w3.org/1999/xhtml" <?php if ( function_exists( 'language_attributes' ) && function_exists( 'is_rtl' ) ) language_attributes(); else echo "dir='$text_direction'"; ?>>
  3107 <html xmlns="http://www.w3.org/1999/xhtml" <?php echo $dir_attr; ?>>
  2773 <head>
  3108 <head>
  2774 	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  3109 	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  2775 	<meta name="viewport" content="width=device-width">
  3110 	<meta name="viewport" content="width=device-width">
  2776 	<?php
  3111 		<?php
  2777 	if ( function_exists( 'wp_no_robots' ) ) {
  3112 		if ( function_exists( 'wp_no_robots' ) ) {
  2778 		wp_no_robots();
  3113 			wp_no_robots();
  2779 	}
  3114 		}
  2780 	?>
  3115 		?>
  2781 	<title><?php echo $title ?></title>
  3116 	<title><?php echo $title; ?></title>
  2782 	<style type="text/css">
  3117 	<style type="text/css">
  2783 		html {
  3118 		html {
  2784 			background: #f1f1f1;
  3119 			background: #f1f1f1;
  2785 		}
  3120 		}
  2786 		body {
  3121 		body {
  2788 			color: #444;
  3123 			color: #444;
  2789 			font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
  3124 			font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
  2790 			margin: 2em auto;
  3125 			margin: 2em auto;
  2791 			padding: 1em 2em;
  3126 			padding: 1em 2em;
  2792 			max-width: 700px;
  3127 			max-width: 700px;
  2793 			-webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.13);
  3128 			-webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.13);
  2794 			box-shadow: 0 1px 3px rgba(0,0,0,0.13);
  3129 			box-shadow: 0 1px 3px rgba(0, 0, 0, 0.13);
  2795 		}
  3130 		}
  2796 		h1 {
  3131 		h1 {
  2797 			border-bottom: 1px solid #dadada;
  3132 			border-bottom: 1px solid #dadada;
  2798 			clear: both;
  3133 			clear: both;
  2799 			color: #666;
  3134 			color: #666;
  2824 		a:active {
  3159 		a:active {
  2825 			color: #00a0d2;
  3160 			color: #00a0d2;
  2826 		}
  3161 		}
  2827 		a:focus {
  3162 		a:focus {
  2828 			color: #124964;
  3163 			color: #124964;
  2829 		    -webkit-box-shadow:
  3164 			-webkit-box-shadow:
  2830 		    	0 0 0 1px #5b9dd9,
  3165 				0 0 0 1px #5b9dd9,
  2831 				0 0 2px 1px rgba(30, 140, 190, .8);
  3166 				0 0 2px 1px rgba(30, 140, 190, 0.8);
  2832 		    box-shadow:
  3167 			box-shadow:
  2833 		    	0 0 0 1px #5b9dd9,
  3168 				0 0 0 1px #5b9dd9,
  2834 				0 0 2px 1px rgba(30, 140, 190, .8);
  3169 				0 0 2px 1px rgba(30, 140, 190, 0.8);
  2835 			outline: none;
  3170 			outline: none;
  2836 		}
  3171 		}
  2837 		.button {
  3172 		.button {
  2838 			background: #f7f7f7;
  3173 			background: #f7f7f7;
  2839 			border: 1px solid #ccc;
  3174 			border: 1px solid #ccc;
  2854 			-moz-box-sizing:    border-box;
  3189 			-moz-box-sizing:    border-box;
  2855 			box-sizing:         border-box;
  3190 			box-sizing:         border-box;
  2856 
  3191 
  2857 			-webkit-box-shadow: 0 1px 0 #ccc;
  3192 			-webkit-box-shadow: 0 1px 0 #ccc;
  2858 			box-shadow: 0 1px 0 #ccc;
  3193 			box-shadow: 0 1px 0 #ccc;
  2859 		 	vertical-align: top;
  3194 			 vertical-align: top;
  2860 		}
  3195 		}
  2861 
  3196 
  2862 		.button.button-large {
  3197 		.button.button-large {
  2863 			height: 30px;
  3198 			height: 30px;
  2864 			line-height: 28px;
  3199 			line-height: 28px;
  2870 			background: #fafafa;
  3205 			background: #fafafa;
  2871 			border-color: #999;
  3206 			border-color: #999;
  2872 			color: #23282d;
  3207 			color: #23282d;
  2873 		}
  3208 		}
  2874 
  3209 
  2875 		.button:focus  {
  3210 		.button:focus {
  2876 			border-color: #5b9dd9;
  3211 			border-color: #5b9dd9;
  2877 			-webkit-box-shadow: 0 0 3px rgba( 0, 115, 170, .8 );
  3212 			-webkit-box-shadow: 0 0 3px rgba(0, 115, 170, 0.8);
  2878 			box-shadow: 0 0 3px rgba( 0, 115, 170, .8 );
  3213 			box-shadow: 0 0 3px rgba(0, 115, 170, 0.8);
  2879 			outline: none;
  3214 			outline: none;
  2880 		}
  3215 		}
  2881 
  3216 
  2882 		.button:active {
  3217 		.button:active {
  2883 			background: #eee;
  3218 			background: #eee;
  2884 			border-color: #999;
  3219 			border-color: #999;
  2885 		 	-webkit-box-shadow: inset 0 2px 5px -3px rgba( 0, 0, 0, 0.5 );
  3220 			 -webkit-box-shadow: inset 0 2px 5px -3px rgba(0, 0, 0, 0.5);
  2886 		 	box-shadow: inset 0 2px 5px -3px rgba( 0, 0, 0, 0.5 );
  3221 			 box-shadow: inset 0 2px 5px -3px rgba(0, 0, 0, 0.5);
  2887 		 	-webkit-transform: translateY(1px);
  3222 			 -webkit-transform: translateY(1px);
  2888 		 	-ms-transform: translateY(1px);
  3223 			 -ms-transform: translateY(1px);
  2889 		 	transform: translateY(1px);
  3224 			 transform: translateY(1px);
  2890 		}
  3225 		}
  2891 
  3226 
  2892 		<?php
  3227 		<?php
  2893 		if ( 'rtl' == $text_direction ) {
  3228 		if ( 'rtl' == $text_direction ) {
  2894 			echo 'body { font-family: Tahoma, Arial; }';
  3229 			echo 'body { font-family: Tahoma, Arial; }';
  2899 <body id="error-page">
  3234 <body id="error-page">
  2900 <?php endif; // ! did_action( 'admin_head' ) ?>
  3235 <?php endif; // ! did_action( 'admin_head' ) ?>
  2901 	<?php echo $message; ?>
  3236 	<?php echo $message; ?>
  2902 </body>
  3237 </body>
  2903 </html>
  3238 </html>
  2904 <?php
  3239 	<?php
  2905 	die();
  3240 	if ( $r['exit'] ) {
  2906 }
  3241 		die();
  2907 
  3242 	}
  2908 /**
  3243 }
  2909  * Kill WordPress execution and display XML message with error message.
  3244 
  2910  *
  3245 /**
  2911  * This is the handler for wp_die when processing XMLRPC requests.
  3246  * Kills WordPress execution and displays Ajax response with an error message.
  2912  *
  3247  *
  2913  * @since 3.2.0
  3248  * This is the handler for wp_die() when processing Ajax requests.
       
  3249  *
       
  3250  * @since 3.4.0
  2914  * @access private
  3251  * @access private
  2915  *
  3252  *
  2916  * @global wp_xmlrpc_server $wp_xmlrpc_server
  3253  * @param string       $message Error message.
       
  3254  * @param string       $title   Optional. Error title (unused). Default empty.
       
  3255  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
       
  3256  */
       
  3257 function _ajax_wp_die_handler( $message, $title = '', $args = array() ) {
       
  3258 	// Set default 'response' to 200 for AJAX requests.
       
  3259 	$args = wp_parse_args(
       
  3260 		$args,
       
  3261 		array( 'response' => 200 )
       
  3262 	);
       
  3263 
       
  3264 	list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args );
       
  3265 
       
  3266 	if ( ! headers_sent() ) {
       
  3267 		// This is intentional. For backward-compatibility, support passing null here.
       
  3268 		if ( null !== $args['response'] ) {
       
  3269 			status_header( $r['response'] );
       
  3270 		}
       
  3271 		nocache_headers();
       
  3272 	}
       
  3273 
       
  3274 	if ( is_scalar( $message ) ) {
       
  3275 		$message = (string) $message;
       
  3276 	} else {
       
  3277 		$message = '0';
       
  3278 	}
       
  3279 
       
  3280 	if ( $r['exit'] ) {
       
  3281 		die( $message );
       
  3282 	}
       
  3283 
       
  3284 	echo $message;
       
  3285 }
       
  3286 
       
  3287 /**
       
  3288  * Kills WordPress execution and displays JSON response with an error message.
       
  3289  *
       
  3290  * This is the handler for wp_die() when processing JSON requests.
       
  3291  *
       
  3292  * @since 5.1.0
       
  3293  * @access private
  2917  *
  3294  *
  2918  * @param string       $message Error message.
  3295  * @param string       $message Error message.
  2919  * @param string       $title   Optional. Error title. Default empty.
  3296  * @param string       $title   Optional. Error title. Default empty.
  2920  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  3297  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  2921  */
  3298  */
       
  3299 function _json_wp_die_handler( $message, $title = '', $args = array() ) {
       
  3300 	list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args );
       
  3301 
       
  3302 	$data = array(
       
  3303 		'code'              => $r['code'],
       
  3304 		'message'           => $message,
       
  3305 		'data'              => array(
       
  3306 			'status' => $r['response'],
       
  3307 		),
       
  3308 		'additional_errors' => $r['additional_errors'],
       
  3309 	);
       
  3310 
       
  3311 	if ( ! headers_sent() ) {
       
  3312 		header( 'Content-Type: application/json; charset=utf-8' );
       
  3313 		if ( null !== $r['response'] ) {
       
  3314 			status_header( $r['response'] );
       
  3315 		}
       
  3316 		nocache_headers();
       
  3317 	}
       
  3318 
       
  3319 	echo wp_json_encode( $data );
       
  3320 	if ( $r['exit'] ) {
       
  3321 		die();
       
  3322 	}
       
  3323 }
       
  3324 
       
  3325 /**
       
  3326  * Kills WordPress execution and displays JSONP response with an error message.
       
  3327  *
       
  3328  * This is the handler for wp_die() when processing JSONP requests.
       
  3329  *
       
  3330  * @since 5.2.0
       
  3331  * @access private
       
  3332  *
       
  3333  * @param string       $message Error message.
       
  3334  * @param string       $title   Optional. Error title. Default empty.
       
  3335  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
       
  3336  */
       
  3337 function _jsonp_wp_die_handler( $message, $title = '', $args = array() ) {
       
  3338 	list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args );
       
  3339 
       
  3340 	$data = array(
       
  3341 		'code'              => $r['code'],
       
  3342 		'message'           => $message,
       
  3343 		'data'              => array(
       
  3344 			'status' => $r['response'],
       
  3345 		),
       
  3346 		'additional_errors' => $r['additional_errors'],
       
  3347 	);
       
  3348 
       
  3349 	if ( ! headers_sent() ) {
       
  3350 		header( 'Content-Type: application/javascript; charset=utf-8' );
       
  3351 		header( 'X-Content-Type-Options: nosniff' );
       
  3352 		header( 'X-Robots-Tag: noindex' );
       
  3353 		if ( null !== $r['response'] ) {
       
  3354 			status_header( $r['response'] );
       
  3355 		}
       
  3356 		nocache_headers();
       
  3357 	}
       
  3358 
       
  3359 	$result         = wp_json_encode( $data );
       
  3360 	$jsonp_callback = $_GET['_jsonp'];
       
  3361 	echo '/**/' . $jsonp_callback . '(' . $result . ')';
       
  3362 	if ( $r['exit'] ) {
       
  3363 		die();
       
  3364 	}
       
  3365 }
       
  3366 
       
  3367 /**
       
  3368  * Kills WordPress execution and displays XML response with an error message.
       
  3369  *
       
  3370  * This is the handler for wp_die() when processing XMLRPC requests.
       
  3371  *
       
  3372  * @since 3.2.0
       
  3373  * @access private
       
  3374  *
       
  3375  * @global wp_xmlrpc_server $wp_xmlrpc_server
       
  3376  *
       
  3377  * @param string       $message Error message.
       
  3378  * @param string       $title   Optional. Error title. Default empty.
       
  3379  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
       
  3380  */
  2922 function _xmlrpc_wp_die_handler( $message, $title = '', $args = array() ) {
  3381 function _xmlrpc_wp_die_handler( $message, $title = '', $args = array() ) {
  2923 	global $wp_xmlrpc_server;
  3382 	global $wp_xmlrpc_server;
  2924 	$defaults = array( 'response' => 500 );
  3383 
  2925 
  3384 	list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args );
  2926 	$r = wp_parse_args($args, $defaults);
  3385 
       
  3386 	if ( ! headers_sent() ) {
       
  3387 		nocache_headers();
       
  3388 	}
  2927 
  3389 
  2928 	if ( $wp_xmlrpc_server ) {
  3390 	if ( $wp_xmlrpc_server ) {
  2929 		$error = new IXR_Error( $r['response'] , $message);
  3391 		$error = new IXR_Error( $r['response'], $message );
  2930 		$wp_xmlrpc_server->output( $error->getXml() );
  3392 		$wp_xmlrpc_server->output( $error->getXml() );
  2931 	}
  3393 	}
  2932 	die();
  3394 	if ( $r['exit'] ) {
  2933 }
  3395 		die();
  2934 
  3396 	}
  2935 /**
  3397 }
  2936  * Kill WordPress ajax execution.
  3398 
  2937  *
  3399 /**
  2938  * This is the handler for wp_die when processing Ajax requests.
  3400  * Kills WordPress execution and displays XML response with an error message.
       
  3401  *
       
  3402  * This is the handler for wp_die() when processing XML requests.
       
  3403  *
       
  3404  * @since 5.2.0
       
  3405  * @access private
       
  3406  *
       
  3407  * @param string       $message Error message.
       
  3408  * @param string       $title   Optional. Error title. Default empty.
       
  3409  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
       
  3410  */
       
  3411 function _xml_wp_die_handler( $message, $title = '', $args = array() ) {
       
  3412 	list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args );
       
  3413 
       
  3414 	$message = htmlspecialchars( $message );
       
  3415 	$title   = htmlspecialchars( $title );
       
  3416 
       
  3417 	$xml = <<<EOD
       
  3418 <error>
       
  3419     <code>{$r['code']}</code>
       
  3420     <title><![CDATA[{$title}]]></title>
       
  3421     <message><![CDATA[{$message}]]></message>
       
  3422     <data>
       
  3423         <status>{$r['response']}</status>
       
  3424     </data>
       
  3425 </error>
       
  3426 
       
  3427 EOD;
       
  3428 
       
  3429 	if ( ! headers_sent() ) {
       
  3430 		header( 'Content-Type: text/xml; charset=utf-8' );
       
  3431 		if ( null !== $r['response'] ) {
       
  3432 			status_header( $r['response'] );
       
  3433 		}
       
  3434 		nocache_headers();
       
  3435 	}
       
  3436 
       
  3437 	echo $xml;
       
  3438 	if ( $r['exit'] ) {
       
  3439 		die();
       
  3440 	}
       
  3441 }
       
  3442 
       
  3443 /**
       
  3444  * Kills WordPress execution and displays an error message.
       
  3445  *
       
  3446  * This is the handler for wp_die() when processing APP requests.
  2939  *
  3447  *
  2940  * @since 3.4.0
  3448  * @since 3.4.0
       
  3449  * @since 5.1.0 Added the $title and $args parameters.
  2941  * @access private
  3450  * @access private
  2942  *
  3451  *
  2943  * @param string       $message Error message.
  3452  * @param string       $message Optional. Response to print. Default empty.
  2944  * @param string       $title   Optional. Error title (unused). Default empty.
  3453  * @param string       $title   Optional. Error title (unused). Default empty.
  2945  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  3454  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
  2946  */
  3455  */
  2947 function _ajax_wp_die_handler( $message, $title = '', $args = array() ) {
  3456 function _scalar_wp_die_handler( $message = '', $title = '', $args = array() ) {
       
  3457 	list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args );
       
  3458 
       
  3459 	if ( $r['exit'] ) {
       
  3460 		if ( is_scalar( $message ) ) {
       
  3461 			die( (string) $message );
       
  3462 		}
       
  3463 		die();
       
  3464 	}
       
  3465 
       
  3466 	if ( is_scalar( $message ) ) {
       
  3467 		echo (string) $message;
       
  3468 	}
       
  3469 }
       
  3470 
       
  3471 /**
       
  3472  * Processes arguments passed to wp_die() consistently for its handlers.
       
  3473  *
       
  3474  * @since 5.1.0
       
  3475  * @access private
       
  3476  *
       
  3477  * @param string       $message Error message.
       
  3478  * @param string       $title   Optional. Error title. Default empty.
       
  3479  * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
       
  3480  * @return array List of processed $message string, $title string, and $args array.
       
  3481  */
       
  3482 function _wp_die_process_input( $message, $title = '', $args = array() ) {
  2948 	$defaults = array(
  3483 	$defaults = array(
  2949 		'response' => 200,
  3484 		'response'          => 0,
       
  3485 		'code'              => '',
       
  3486 		'exit'              => true,
       
  3487 		'back_link'         => false,
       
  3488 		'link_url'          => '',
       
  3489 		'link_text'         => '',
       
  3490 		'text_direction'    => '',
       
  3491 		'additional_errors' => array(),
  2950 	);
  3492 	);
  2951 	$r = wp_parse_args( $args, $defaults );
  3493 
  2952 
  3494 	$args = wp_parse_args( $args, $defaults );
  2953 	if ( ! headers_sent() && null !== $r['response'] ) {
  3495 
  2954 		status_header( $r['response'] );
  3496 	if ( function_exists( 'is_wp_error' ) && is_wp_error( $message ) ) {
  2955 	}
  3497 		if ( ! empty( $message->errors ) ) {
  2956 
  3498 			$errors = array();
  2957 	if ( is_scalar( $message ) )
  3499 			foreach ( (array) $message->errors as $error_code => $error_messages ) {
  2958 		die( (string) $message );
  3500 				foreach ( (array) $error_messages as $error_message ) {
  2959 	die( '0' );
  3501 					$errors[] = array(
  2960 }
  3502 						'code'    => $error_code,
  2961 
  3503 						'message' => $error_message,
  2962 /**
  3504 						'data'    => $message->get_error_data( $error_code ),
  2963  * Kill WordPress execution.
  3505 					);
  2964  *
  3506 				}
  2965  * This is the handler for wp_die when processing APP requests.
  3507 			}
  2966  *
  3508 
  2967  * @since 3.4.0
  3509 			$message = $errors[0]['message'];
  2968  * @access private
  3510 			if ( empty( $args['code'] ) ) {
  2969  *
  3511 				$args['code'] = $errors[0]['code'];
  2970  * @param string $message Optional. Response to print. Default empty.
  3512 			}
  2971  */
  3513 			if ( empty( $args['response'] ) && is_array( $errors[0]['data'] ) && ! empty( $errors[0]['data']['status'] ) ) {
  2972 function _scalar_wp_die_handler( $message = '' ) {
  3514 				$args['response'] = $errors[0]['data']['status'];
  2973 	if ( is_scalar( $message ) )
  3515 			}
  2974 		die( (string) $message );
  3516 			if ( empty( $title ) && is_array( $errors[0]['data'] ) && ! empty( $errors[0]['data']['title'] ) ) {
  2975 	die();
  3517 				$title = $errors[0]['data']['title'];
       
  3518 			}
       
  3519 
       
  3520 			unset( $errors[0] );
       
  3521 			$args['additional_errors'] = array_values( $errors );
       
  3522 		} else {
       
  3523 			$message = '';
       
  3524 		}
       
  3525 	}
       
  3526 
       
  3527 	$have_gettext = function_exists( '__' );
       
  3528 
       
  3529 	// The $title and these specific $args must always have a non-empty value.
       
  3530 	if ( empty( $args['code'] ) ) {
       
  3531 		$args['code'] = 'wp_die';
       
  3532 	}
       
  3533 	if ( empty( $args['response'] ) ) {
       
  3534 		$args['response'] = 500;
       
  3535 	}
       
  3536 	if ( empty( $title ) ) {
       
  3537 		$title = $have_gettext ? __( 'WordPress &rsaquo; Error' ) : 'WordPress &rsaquo; Error';
       
  3538 	}
       
  3539 	if ( empty( $args['text_direction'] ) || ! in_array( $args['text_direction'], array( 'ltr', 'rtl' ), true ) ) {
       
  3540 		$args['text_direction'] = 'ltr';
       
  3541 		if ( function_exists( 'is_rtl' ) && is_rtl() ) {
       
  3542 			$args['text_direction'] = 'rtl';
       
  3543 		}
       
  3544 	}
       
  3545 
       
  3546 	return array( $message, $title, $args );
  2976 }
  3547 }
  2977 
  3548 
  2978 /**
  3549 /**
  2979  * Encode a variable into JSON, with some sanity checks.
  3550  * Encode a variable into JSON, with some sanity checks.
  2980  *
  3551  *
  3006 	$json = @call_user_func_array( 'json_encode', $args );
  3577 	$json = @call_user_func_array( 'json_encode', $args );
  3007 
  3578 
  3008 	// If json_encode() was successful, no need to do more sanity checking.
  3579 	// If json_encode() was successful, no need to do more sanity checking.
  3009 	// ... unless we're in an old version of PHP, and json_encode() returned
  3580 	// ... unless we're in an old version of PHP, and json_encode() returned
  3010 	// a string containing 'null'. Then we need to do more sanity checking.
  3581 	// a string containing 'null'. Then we need to do more sanity checking.
  3011 	if ( false !== $json && ( version_compare( PHP_VERSION, '5.5', '>=' ) || false === strpos( $json, 'null' ) ) )  {
  3582 	if ( false !== $json && ( version_compare( PHP_VERSION, '5.5', '>=' ) || false === strpos( $json, 'null' ) ) ) {
  3012 		return $json;
  3583 		return $json;
  3013 	}
  3584 	}
  3014 
  3585 
  3015 	try {
  3586 	try {
  3016 		$args[0] = _wp_json_sanity_check( $data, $depth );
  3587 		$args[0] = _wp_json_sanity_check( $data, $depth );
  3182 		status_header( $status_code );
  3753 		status_header( $status_code );
  3183 	}
  3754 	}
  3184 	echo wp_json_encode( $response );
  3755 	echo wp_json_encode( $response );
  3185 
  3756 
  3186 	if ( wp_doing_ajax() ) {
  3757 	if ( wp_doing_ajax() ) {
  3187 		wp_die( '', '', array(
  3758 		wp_die(
  3188 			'response' => null,
  3759 			'',
  3189 		) );
  3760 			'',
       
  3761 			array(
       
  3762 				'response' => null,
       
  3763 			)
       
  3764 		);
  3190 	} else {
  3765 	} else {
  3191 		die;
  3766 		die;
  3192 	}
  3767 	}
  3193 }
  3768 }
  3194 
  3769 
  3202  * @param int   $status_code The HTTP status code to output.
  3777  * @param int   $status_code The HTTP status code to output.
  3203  */
  3778  */
  3204 function wp_send_json_success( $data = null, $status_code = null ) {
  3779 function wp_send_json_success( $data = null, $status_code = null ) {
  3205 	$response = array( 'success' => true );
  3780 	$response = array( 'success' => true );
  3206 
  3781 
  3207 	if ( isset( $data ) )
  3782 	if ( isset( $data ) ) {
  3208 		$response['data'] = $data;
  3783 		$response['data'] = $data;
       
  3784 	}
  3209 
  3785 
  3210 	wp_send_json( $response, $status_code );
  3786 	wp_send_json( $response, $status_code );
  3211 }
  3787 }
  3212 
  3788 
  3213 /**
  3789 /**
  3231 	if ( isset( $data ) ) {
  3807 	if ( isset( $data ) ) {
  3232 		if ( is_wp_error( $data ) ) {
  3808 		if ( is_wp_error( $data ) ) {
  3233 			$result = array();
  3809 			$result = array();
  3234 			foreach ( $data->errors as $code => $messages ) {
  3810 			foreach ( $data->errors as $code => $messages ) {
  3235 				foreach ( $messages as $message ) {
  3811 				foreach ( $messages as $message ) {
  3236 					$result[] = array( 'code' => $code, 'message' => $message );
  3812 					$result[] = array(
       
  3813 						'code'    => $code,
       
  3814 						'message' => $message,
       
  3815 					);
  3237 				}
  3816 				}
  3238 			}
  3817 			}
  3239 
  3818 
  3240 			$response['data'] = $result;
  3819 			$response['data'] = $result;
  3241 		} else {
  3820 		} else {
  3282  *
  3861  *
  3283  * @param string $url URL for the home location.
  3862  * @param string $url URL for the home location.
  3284  * @return string Homepage location.
  3863  * @return string Homepage location.
  3285  */
  3864  */
  3286 function _config_wp_home( $url = '' ) {
  3865 function _config_wp_home( $url = '' ) {
  3287 	if ( defined( 'WP_HOME' ) )
  3866 	if ( defined( 'WP_HOME' ) ) {
  3288 		return untrailingslashit( WP_HOME );
  3867 		return untrailingslashit( WP_HOME );
       
  3868 	}
  3289 	return $url;
  3869 	return $url;
  3290 }
  3870 }
  3291 
  3871 
  3292 /**
  3872 /**
  3293  * Retrieve the WordPress site URL.
  3873  * Retrieve the WordPress site URL.
  3303  *
  3883  *
  3304  * @param string $url URL to set the WordPress site location.
  3884  * @param string $url URL to set the WordPress site location.
  3305  * @return string The WordPress Site URL.
  3885  * @return string The WordPress Site URL.
  3306  */
  3886  */
  3307 function _config_wp_siteurl( $url = '' ) {
  3887 function _config_wp_siteurl( $url = '' ) {
  3308 	if ( defined( 'WP_SITEURL' ) )
  3888 	if ( defined( 'WP_SITEURL' ) ) {
  3309 		return untrailingslashit( WP_SITEURL );
  3889 		return untrailingslashit( WP_SITEURL );
       
  3890 	}
  3310 	return $url;
  3891 	return $url;
  3311 }
  3892 }
  3312 
  3893 
  3313 /**
  3894 /**
  3314  * Delete the fresh site option.
  3895  * Delete the fresh site option.
  3338  * @return array Direction set for 'rtl', if needed by locale.
  3919  * @return array Direction set for 'rtl', if needed by locale.
  3339  */
  3920  */
  3340 function _mce_set_direction( $mce_init ) {
  3921 function _mce_set_direction( $mce_init ) {
  3341 	if ( is_rtl() ) {
  3922 	if ( is_rtl() ) {
  3342 		$mce_init['directionality'] = 'rtl';
  3923 		$mce_init['directionality'] = 'rtl';
  3343 		$mce_init['rtl_ui'] = true;
  3924 		$mce_init['rtl_ui']         = true;
  3344 
  3925 
  3345 		if ( ! empty( $mce_init['plugins'] ) && strpos( $mce_init['plugins'], 'directionality' ) === false ) {
  3926 		if ( ! empty( $mce_init['plugins'] ) && strpos( $mce_init['plugins'], 'directionality' ) === false ) {
  3346 			$mce_init['plugins'] .= ',directionality';
  3927 			$mce_init['plugins'] .= ',directionality';
  3347 		}
  3928 		}
  3348 
  3929 
  3379  */
  3960  */
  3380 function smilies_init() {
  3961 function smilies_init() {
  3381 	global $wpsmiliestrans, $wp_smiliessearch;
  3962 	global $wpsmiliestrans, $wp_smiliessearch;
  3382 
  3963 
  3383 	// don't bother setting up smilies if they are disabled
  3964 	// don't bother setting up smilies if they are disabled
  3384 	if ( !get_option( 'use_smilies' ) )
  3965 	if ( ! get_option( 'use_smilies' ) ) {
  3385 		return;
  3966 		return;
  3386 
  3967 	}
  3387 	if ( !isset( $wpsmiliestrans ) ) {
  3968 
       
  3969 	if ( ! isset( $wpsmiliestrans ) ) {
  3388 		$wpsmiliestrans = array(
  3970 		$wpsmiliestrans = array(
  3389 		':mrgreen:' => 'mrgreen.png',
  3971 			':mrgreen:' => 'mrgreen.png',
  3390 		':neutral:' => "\xf0\x9f\x98\x90",
  3972 			':neutral:' => "\xf0\x9f\x98\x90",
  3391 		':twisted:' => "\xf0\x9f\x98\x88",
  3973 			':twisted:' => "\xf0\x9f\x98\x88",
  3392 		  ':arrow:' => "\xe2\x9e\xa1",
  3974 			':arrow:'   => "\xe2\x9e\xa1",
  3393 		  ':shock:' => "\xf0\x9f\x98\xaf",
  3975 			':shock:'   => "\xf0\x9f\x98\xaf",
  3394 		  ':smile:' => "\xf0\x9f\x99\x82",
  3976 			':smile:'   => "\xf0\x9f\x99\x82",
  3395 		    ':???:' => "\xf0\x9f\x98\x95",
  3977 			':???:'     => "\xf0\x9f\x98\x95",
  3396 		   ':cool:' => "\xf0\x9f\x98\x8e",
  3978 			':cool:'    => "\xf0\x9f\x98\x8e",
  3397 		   ':evil:' => "\xf0\x9f\x91\xbf",
  3979 			':evil:'    => "\xf0\x9f\x91\xbf",
  3398 		   ':grin:' => "\xf0\x9f\x98\x80",
  3980 			':grin:'    => "\xf0\x9f\x98\x80",
  3399 		   ':idea:' => "\xf0\x9f\x92\xa1",
  3981 			':idea:'    => "\xf0\x9f\x92\xa1",
  3400 		   ':oops:' => "\xf0\x9f\x98\xb3",
  3982 			':oops:'    => "\xf0\x9f\x98\xb3",
  3401 		   ':razz:' => "\xf0\x9f\x98\x9b",
  3983 			':razz:'    => "\xf0\x9f\x98\x9b",
  3402 		   ':roll:' => "\xf0\x9f\x99\x84",
  3984 			':roll:'    => "\xf0\x9f\x99\x84",
  3403 		   ':wink:' => "\xf0\x9f\x98\x89",
  3985 			':wink:'    => "\xf0\x9f\x98\x89",
  3404 		    ':cry:' => "\xf0\x9f\x98\xa5",
  3986 			':cry:'     => "\xf0\x9f\x98\xa5",
  3405 		    ':eek:' => "\xf0\x9f\x98\xae",
  3987 			':eek:'     => "\xf0\x9f\x98\xae",
  3406 		    ':lol:' => "\xf0\x9f\x98\x86",
  3988 			':lol:'     => "\xf0\x9f\x98\x86",
  3407 		    ':mad:' => "\xf0\x9f\x98\xa1",
  3989 			':mad:'     => "\xf0\x9f\x98\xa1",
  3408 		    ':sad:' => "\xf0\x9f\x99\x81",
  3990 			':sad:'     => "\xf0\x9f\x99\x81",
  3409 		      '8-)' => "\xf0\x9f\x98\x8e",
  3991 			'8-)'       => "\xf0\x9f\x98\x8e",
  3410 		      '8-O' => "\xf0\x9f\x98\xaf",
  3992 			'8-O'       => "\xf0\x9f\x98\xaf",
  3411 		      ':-(' => "\xf0\x9f\x99\x81",
  3993 			':-('       => "\xf0\x9f\x99\x81",
  3412 		      ':-)' => "\xf0\x9f\x99\x82",
  3994 			':-)'       => "\xf0\x9f\x99\x82",
  3413 		      ':-?' => "\xf0\x9f\x98\x95",
  3995 			':-?'       => "\xf0\x9f\x98\x95",
  3414 		      ':-D' => "\xf0\x9f\x98\x80",
  3996 			':-D'       => "\xf0\x9f\x98\x80",
  3415 		      ':-P' => "\xf0\x9f\x98\x9b",
  3997 			':-P'       => "\xf0\x9f\x98\x9b",
  3416 		      ':-o' => "\xf0\x9f\x98\xae",
  3998 			':-o'       => "\xf0\x9f\x98\xae",
  3417 		      ':-x' => "\xf0\x9f\x98\xa1",
  3999 			':-x'       => "\xf0\x9f\x98\xa1",
  3418 		      ':-|' => "\xf0\x9f\x98\x90",
  4000 			':-|'       => "\xf0\x9f\x98\x90",
  3419 		      ';-)' => "\xf0\x9f\x98\x89",
  4001 			';-)'       => "\xf0\x9f\x98\x89",
  3420 		// This one transformation breaks regular text with frequency.
  4002 			// This one transformation breaks regular text with frequency.
  3421 		//     '8)' => "\xf0\x9f\x98\x8e",
  4003 			//     '8)' => "\xf0\x9f\x98\x8e",
  3422 		       '8O' => "\xf0\x9f\x98\xaf",
  4004 			'8O'        => "\xf0\x9f\x98\xaf",
  3423 		       ':(' => "\xf0\x9f\x99\x81",
  4005 			':('        => "\xf0\x9f\x99\x81",
  3424 		       ':)' => "\xf0\x9f\x99\x82",
  4006 			':)'        => "\xf0\x9f\x99\x82",
  3425 		       ':?' => "\xf0\x9f\x98\x95",
  4007 			':?'        => "\xf0\x9f\x98\x95",
  3426 		       ':D' => "\xf0\x9f\x98\x80",
  4008 			':D'        => "\xf0\x9f\x98\x80",
  3427 		       ':P' => "\xf0\x9f\x98\x9b",
  4009 			':P'        => "\xf0\x9f\x98\x9b",
  3428 		       ':o' => "\xf0\x9f\x98\xae",
  4010 			':o'        => "\xf0\x9f\x98\xae",
  3429 		       ':x' => "\xf0\x9f\x98\xa1",
  4011 			':x'        => "\xf0\x9f\x98\xa1",
  3430 		       ':|' => "\xf0\x9f\x98\x90",
  4012 			':|'        => "\xf0\x9f\x98\x90",
  3431 		       ';)' => "\xf0\x9f\x98\x89",
  4013 			';)'        => "\xf0\x9f\x98\x89",
  3432 		      ':!:' => "\xe2\x9d\x97",
  4014 			':!:'       => "\xe2\x9d\x97",
  3433 		      ':?:' => "\xe2\x9d\x93",
  4015 			':?:'       => "\xe2\x9d\x93",
  3434 		);
  4016 		);
  3435 	}
  4017 	}
  3436 
  4018 
  3437 	/**
  4019 	/**
  3438 	 * Filters all the smilies.
  4020 	 * Filters all the smilies.
  3442 	 *
  4024 	 *
  3443 	 * @since 4.7.0
  4025 	 * @since 4.7.0
  3444 	 *
  4026 	 *
  3445 	 * @param array $wpsmiliestrans List of the smilies.
  4027 	 * @param array $wpsmiliestrans List of the smilies.
  3446 	 */
  4028 	 */
  3447 	$wpsmiliestrans = apply_filters('smilies', $wpsmiliestrans);
  4029 	$wpsmiliestrans = apply_filters( 'smilies', $wpsmiliestrans );
  3448 
  4030 
  3449 	if (count($wpsmiliestrans) == 0) {
  4031 	if ( count( $wpsmiliestrans ) == 0 ) {
  3450 		return;
  4032 		return;
  3451 	}
  4033 	}
  3452 
  4034 
  3453 	/*
  4035 	/*
  3454 	 * NOTE: we sort the smilies in reverse key order. This is to make sure
  4036 	 * NOTE: we sort the smilies in reverse key order. This is to make sure
  3455 	 * we match the longest possible smilie (:???: vs :?) as the regular
  4037 	 * we match the longest possible smilie (:???: vs :?) as the regular
  3456 	 * expression used below is first-match
  4038 	 * expression used below is first-match
  3457 	 */
  4039 	 */
  3458 	krsort($wpsmiliestrans);
  4040 	krsort( $wpsmiliestrans );
  3459 
  4041 
  3460 	$spaces = wp_spaces_regexp();
  4042 	$spaces = wp_spaces_regexp();
  3461 
  4043 
  3462 	// Begin first "subpattern"
  4044 	// Begin first "subpattern"
  3463 	$wp_smiliessearch = '/(?<=' . $spaces . '|^)';
  4045 	$wp_smiliessearch = '/(?<=' . $spaces . '|^)';
  3464 
  4046 
  3465 	$subchar = '';
  4047 	$subchar = '';
  3466 	foreach ( (array) $wpsmiliestrans as $smiley => $img ) {
  4048 	foreach ( (array) $wpsmiliestrans as $smiley => $img ) {
  3467 		$firstchar = substr($smiley, 0, 1);
  4049 		$firstchar = substr( $smiley, 0, 1 );
  3468 		$rest = substr($smiley, 1);
  4050 		$rest      = substr( $smiley, 1 );
  3469 
  4051 
  3470 		// new subpattern?
  4052 		// new subpattern?
  3471 		if ($firstchar != $subchar) {
  4053 		if ( $firstchar != $subchar ) {
  3472 			if ($subchar != '') {
  4054 			if ( $subchar != '' ) {
  3473 				$wp_smiliessearch .= ')(?=' . $spaces . '|$)';  // End previous "subpattern"
  4055 				$wp_smiliessearch .= ')(?=' . $spaces . '|$)';  // End previous "subpattern"
  3474 				$wp_smiliessearch .= '|(?<=' . $spaces . '|^)'; // Begin another "subpattern"
  4056 				$wp_smiliessearch .= '|(?<=' . $spaces . '|^)'; // Begin another "subpattern"
  3475 			}
  4057 			}
  3476 			$subchar = $firstchar;
  4058 			$subchar           = $firstchar;
  3477 			$wp_smiliessearch .= preg_quote($firstchar, '/') . '(?:';
  4059 			$wp_smiliessearch .= preg_quote( $firstchar, '/' ) . '(?:';
  3478 		} else {
  4060 		} else {
  3479 			$wp_smiliessearch .= '|';
  4061 			$wp_smiliessearch .= '|';
  3480 		}
  4062 		}
  3481 		$wp_smiliessearch .= preg_quote($rest, '/');
  4063 		$wp_smiliessearch .= preg_quote( $rest, '/' );
  3482 	}
  4064 	}
  3483 
  4065 
  3484 	$wp_smiliessearch .= ')(?=' . $spaces . '|$)/m';
  4066 	$wp_smiliessearch .= ')(?=' . $spaces . '|$)/m';
  3485 
  4067 
  3486 }
  4068 }
  3497  * @param string|array|object $args     Value to merge with $defaults.
  4079  * @param string|array|object $args     Value to merge with $defaults.
  3498  * @param array               $defaults Optional. Array that serves as the defaults. Default empty.
  4080  * @param array               $defaults Optional. Array that serves as the defaults. Default empty.
  3499  * @return array Merged user defined values with defaults.
  4081  * @return array Merged user defined values with defaults.
  3500  */
  4082  */
  3501 function wp_parse_args( $args, $defaults = '' ) {
  4083 function wp_parse_args( $args, $defaults = '' ) {
  3502 	if ( is_object( $args ) )
  4084 	if ( is_object( $args ) ) {
  3503 		$r = get_object_vars( $args );
  4085 		$r = get_object_vars( $args );
  3504 	elseif ( is_array( $args ) )
  4086 	} elseif ( is_array( $args ) ) {
  3505 		$r =& $args;
  4087 		$r =& $args;
  3506 	else
  4088 	} else {
  3507 		wp_parse_str( $args, $r );
  4089 		wp_parse_str( $args, $r );
  3508 
  4090 	}
  3509 	if ( is_array( $defaults ) )
  4091 
       
  4092 	if ( is_array( $defaults ) ) {
  3510 		return array_merge( $defaults, $r );
  4093 		return array_merge( $defaults, $r );
       
  4094 	}
  3511 	return $r;
  4095 	return $r;
       
  4096 }
       
  4097 
       
  4098 /**
       
  4099  * Cleans up an array, comma- or space-separated list of scalar values.
       
  4100  *
       
  4101  * @since 5.1.0
       
  4102  *
       
  4103  * @param array|string $list List of values.
       
  4104  * @return array Sanitized array of values.
       
  4105  */
       
  4106 function wp_parse_list( $list ) {
       
  4107 	if ( ! is_array( $list ) ) {
       
  4108 		return preg_split( '/[\s,]+/', $list, -1, PREG_SPLIT_NO_EMPTY );
       
  4109 	}
       
  4110 
       
  4111 	return $list;
  3512 }
  4112 }
  3513 
  4113 
  3514 /**
  4114 /**
  3515  * Clean up an array, comma- or space-separated list of IDs.
  4115  * Clean up an array, comma- or space-separated list of IDs.
  3516  *
  4116  *
  3518  *
  4118  *
  3519  * @param array|string $list List of ids.
  4119  * @param array|string $list List of ids.
  3520  * @return array Sanitized array of IDs.
  4120  * @return array Sanitized array of IDs.
  3521  */
  4121  */
  3522 function wp_parse_id_list( $list ) {
  4122 function wp_parse_id_list( $list ) {
  3523 	if ( !is_array($list) )
  4123 	$list = wp_parse_list( $list );
  3524 		$list = preg_split('/[\s,]+/', $list);
  4124 
  3525 
  4125 	return array_unique( array_map( 'absint', $list ) );
  3526 	return array_unique(array_map('absint', $list));
       
  3527 }
  4126 }
  3528 
  4127 
  3529 /**
  4128 /**
  3530  * Clean up an array, comma- or space-separated list of slugs.
  4129  * Clean up an array, comma- or space-separated list of slugs.
  3531  *
  4130  *
  3533  *
  4132  *
  3534  * @param  array|string $list List of slugs.
  4133  * @param  array|string $list List of slugs.
  3535  * @return array Sanitized array of slugs.
  4134  * @return array Sanitized array of slugs.
  3536  */
  4135  */
  3537 function wp_parse_slug_list( $list ) {
  4136 function wp_parse_slug_list( $list ) {
  3538 	if ( ! is_array( $list ) ) {
  4137 	$list = wp_parse_list( $list );
  3539 		$list = preg_split( '/[\s,]+/', $list );
  4138 
  3540 	}
  4139 	return array_unique( array_map( 'sanitize_title', $list ) );
  3541 
       
  3542 	foreach ( $list as $key => $value ) {
       
  3543 		$list[ $key ] = sanitize_title( $value );
       
  3544 	}
       
  3545 
       
  3546 	return array_unique( $list );
       
  3547 }
  4140 }
  3548 
  4141 
  3549 /**
  4142 /**
  3550  * Extract a slice of an array, given a list of keys.
  4143  * Extract a slice of an array, given a list of keys.
  3551  *
  4144  *
  3555  * @param array $keys  The list of keys.
  4148  * @param array $keys  The list of keys.
  3556  * @return array The array slice.
  4149  * @return array The array slice.
  3557  */
  4150  */
  3558 function wp_array_slice_assoc( $array, $keys ) {
  4151 function wp_array_slice_assoc( $array, $keys ) {
  3559 	$slice = array();
  4152 	$slice = array();
  3560 	foreach ( $keys as $key )
  4153 	foreach ( $keys as $key ) {
  3561 		if ( isset( $array[ $key ] ) )
  4154 		if ( isset( $array[ $key ] ) ) {
  3562 			$slice[ $key ] = $array[ $key ];
  4155 			$slice[ $key ] = $array[ $key ];
       
  4156 		}
       
  4157 	}
  3563 
  4158 
  3564 	return $slice;
  4159 	return $slice;
  3565 }
  4160 }
  3566 
  4161 
  3567 /**
  4162 /**
  3575 function wp_is_numeric_array( $data ) {
  4170 function wp_is_numeric_array( $data ) {
  3576 	if ( ! is_array( $data ) ) {
  4171 	if ( ! is_array( $data ) ) {
  3577 		return false;
  4172 		return false;
  3578 	}
  4173 	}
  3579 
  4174 
  3580 	$keys = array_keys( $data );
  4175 	$keys        = array_keys( $data );
  3581 	$string_keys = array_filter( $keys, 'is_string' );
  4176 	$string_keys = array_filter( $keys, 'is_string' );
  3582 	return count( $string_keys ) === 0;
  4177 	return count( $string_keys ) === 0;
  3583 }
  4178 }
  3584 
  4179 
  3585 /**
  4180 /**
  3586  * Filters a list of objects, based on a set of key => value arguments.
  4181  * Filters a list of objects, based on a set of key => value arguments.
  3587  *
  4182  *
  3588  * @since 3.0.0
  4183  * @since 3.0.0
  3589  * @since 4.7.0 Uses WP_List_Util class.
  4184  * @since 4.7.0 Uses `WP_List_Util` class.
  3590  *
  4185  *
  3591  * @param array       $list     An array of objects to filter
  4186  * @param array       $list     An array of objects to filter
  3592  * @param array       $args     Optional. An array of key => value arguments to match
  4187  * @param array       $args     Optional. An array of key => value arguments to match
  3593  *                              against each object. Default empty array.
  4188  *                              against each object. Default empty array.
  3594  * @param string      $operator Optional. The logical operation to perform. 'or' means
  4189  * @param string      $operator Optional. The logical operation to perform. 'or' means
  3617 
  4212 
  3618 /**
  4213 /**
  3619  * Filters a list of objects, based on a set of key => value arguments.
  4214  * Filters a list of objects, based on a set of key => value arguments.
  3620  *
  4215  *
  3621  * @since 3.1.0
  4216  * @since 3.1.0
  3622  * @since 4.7.0 Uses WP_List_Util class.
  4217  * @since 4.7.0 Uses `WP_List_Util` class.
  3623  *
  4218  *
  3624  * @param array  $list     An array of objects to filter.
  4219  * @param array  $list     An array of objects to filter.
  3625  * @param array  $args     Optional. An array of key => value arguments to match
  4220  * @param array  $args     Optional. An array of key => value arguments to match
  3626  *                         against each object. Default empty array.
  4221  *                         against each object. Default empty array.
  3627  * @param string $operator Optional. The logical operation to perform. 'AND' means
  4222  * @param string $operator Optional. The logical operation to perform. 'AND' means
  3645  * This has the same functionality and prototype of
  4240  * This has the same functionality and prototype of
  3646  * array_column() (PHP 5.5) but also supports objects.
  4241  * array_column() (PHP 5.5) but also supports objects.
  3647  *
  4242  *
  3648  * @since 3.1.0
  4243  * @since 3.1.0
  3649  * @since 4.0.0 $index_key parameter added.
  4244  * @since 4.0.0 $index_key parameter added.
  3650  * @since 4.7.0 Uses WP_List_Util class.
  4245  * @since 4.7.0 Uses `WP_List_Util` class.
  3651  *
  4246  *
  3652  * @param array      $list      List of objects or arrays
  4247  * @param array      $list      List of objects or arrays
  3653  * @param int|string $field     Field from the object to place instead of the entire object
  4248  * @param int|string $field     Field from the object to place instead of the entire object
  3654  * @param int|string $index_key Optional. Field from the object to use as keys for the new array.
  4249  * @param int|string $index_key Optional. Field from the object to use as keys for the new array.
  3655  *                              Default null.
  4250  *                              Default null.
  3665 /**
  4260 /**
  3666  * Sorts a list of objects, based on one or more orderby arguments.
  4261  * Sorts a list of objects, based on one or more orderby arguments.
  3667  *
  4262  *
  3668  * @since 4.7.0
  4263  * @since 4.7.0
  3669  *
  4264  *
  3670  * @param array        $list          An array of objects to filter.
  4265  * @param array        $list          An array of objects to sort.
  3671  * @param string|array $orderby       Optional. Either the field name to order by or an array
  4266  * @param string|array $orderby       Optional. Either the field name to order by or an array
  3672  *                                    of multiple orderby fields as $orderby => $order.
  4267  *                                    of multiple orderby fields as $orderby => $order.
  3673  * @param string       $order         Optional. Either 'ASC' or 'DESC'. Only used if $orderby
  4268  * @param string       $order         Optional. Either 'ASC' or 'DESC'. Only used if $orderby
  3674  *                                    is a string.
  4269  *                                    is a string.
  3675  * @param bool         $preserve_keys Optional. Whether to preserve keys. Default false.
  4270  * @param bool         $preserve_keys Optional. Whether to preserve keys. Default false.
  3721  * @global array $submenu
  4316  * @global array $submenu
  3722  */
  4317  */
  3723 function wp_widgets_add_menu() {
  4318 function wp_widgets_add_menu() {
  3724 	global $submenu;
  4319 	global $submenu;
  3725 
  4320 
  3726 	if ( ! current_theme_supports( 'widgets' ) )
  4321 	if ( ! current_theme_supports( 'widgets' ) ) {
  3727 		return;
  4322 		return;
       
  4323 	}
  3728 
  4324 
  3729 	$submenu['themes.php'][7] = array( __( 'Widgets' ), 'edit_theme_options', 'widgets.php' );
  4325 	$submenu['themes.php'][7] = array( __( 'Widgets' ), 'edit_theme_options', 'widgets.php' );
  3730 	ksort( $submenu['themes.php'], SORT_NUMERIC );
  4326 	ksort( $submenu['themes.php'], SORT_NUMERIC );
  3731 }
  4327 }
  3732 
  4328 
  3737  *
  4333  *
  3738  * @since 2.2.0
  4334  * @since 2.2.0
  3739  */
  4335  */
  3740 function wp_ob_end_flush_all() {
  4336 function wp_ob_end_flush_all() {
  3741 	$levels = ob_get_level();
  4337 	$levels = ob_get_level();
  3742 	for ($i=0; $i<$levels; $i++)
  4338 	for ( $i = 0; $i < $levels; $i++ ) {
  3743 		ob_end_flush();
  4339 		ob_end_flush();
       
  4340 	}
  3744 }
  4341 }
  3745 
  4342 
  3746 /**
  4343 /**
  3747  * Load custom DB error or display WordPress DB error.
  4344  * Load custom DB error or display WordPress DB error.
  3748  *
  4345  *
  3771 		require_once( WP_CONTENT_DIR . '/db-error.php' );
  4368 		require_once( WP_CONTENT_DIR . '/db-error.php' );
  3772 		die();
  4369 		die();
  3773 	}
  4370 	}
  3774 
  4371 
  3775 	// If installing or in the admin, provide the verbose message.
  4372 	// If installing or in the admin, provide the verbose message.
  3776 	if ( wp_installing() || defined( 'WP_ADMIN' ) )
  4373 	if ( wp_installing() || defined( 'WP_ADMIN' ) ) {
  3777 		wp_die($wpdb->error);
  4374 		wp_die( $wpdb->error );
       
  4375 	}
  3778 
  4376 
  3779 	// Otherwise, be terse.
  4377 	// Otherwise, be terse.
  3780 	status_header( 500 );
  4378 	wp_die( '<h1>' . __( 'Error establishing a database connection' ) . '</h1>', __( 'Database Error' ) );
  3781 	nocache_headers();
       
  3782 	header( 'Content-Type: text/html; charset=utf-8' );
       
  3783 ?>
       
  3784 <!DOCTYPE html>
       
  3785 <html xmlns="http://www.w3.org/1999/xhtml"<?php if ( is_rtl() ) echo ' dir="rtl"'; ?>>
       
  3786 <head>
       
  3787 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
       
  3788 	<title><?php _e( 'Database Error' ); ?></title>
       
  3789 
       
  3790 </head>
       
  3791 <body>
       
  3792 	<h1><?php _e( 'Error establishing a database connection' ); ?></h1>
       
  3793 </body>
       
  3794 </html>
       
  3795 <?php
       
  3796 	die();
       
  3797 }
  4379 }
  3798 
  4380 
  3799 /**
  4381 /**
  3800  * Convert a value to non-negative integer.
  4382  * Convert a value to non-negative integer.
  3801  *
  4383  *
  3848 	 */
  4430 	 */
  3849 	if ( WP_DEBUG && apply_filters( 'deprecated_function_trigger_error', true ) ) {
  4431 	if ( WP_DEBUG && apply_filters( 'deprecated_function_trigger_error', true ) ) {
  3850 		if ( function_exists( '__' ) ) {
  4432 		if ( function_exists( '__' ) ) {
  3851 			if ( ! is_null( $replacement ) ) {
  4433 			if ( ! is_null( $replacement ) ) {
  3852 				/* translators: 1: PHP function name, 2: version number, 3: alternative function name */
  4434 				/* translators: 1: PHP function name, 2: version number, 3: alternative function name */
  3853 				trigger_error( sprintf( __('%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.'), $function, $version, $replacement ) );
  4435 				trigger_error( sprintf( __( '%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ), $function, $version, $replacement ) );
  3854 			} else {
  4436 			} else {
  3855 				/* translators: 1: PHP function name, 2: version number */
  4437 				/* translators: 1: PHP function name, 2: version number */
  3856 				trigger_error( sprintf( __('%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.'), $function, $version ) );
  4438 				trigger_error( sprintf( __( '%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.' ), $function, $version ) );
  3857 			}
  4439 			}
  3858 		} else {
  4440 		} else {
  3859 			if ( ! is_null( $replacement ) ) {
  4441 			if ( ! is_null( $replacement ) ) {
  3860 				trigger_error( sprintf( '%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.', $function, $version, $replacement ) );
  4442 				trigger_error( sprintf( '%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.', $function, $version, $replacement ) );
  3861 			} else {
  4443 			} else {
  3910 	 */
  4492 	 */
  3911 	if ( WP_DEBUG && apply_filters( 'deprecated_constructor_trigger_error', true ) ) {
  4493 	if ( WP_DEBUG && apply_filters( 'deprecated_constructor_trigger_error', true ) ) {
  3912 		if ( function_exists( '__' ) ) {
  4494 		if ( function_exists( '__' ) ) {
  3913 			if ( ! empty( $parent_class ) ) {
  4495 			if ( ! empty( $parent_class ) ) {
  3914 				/* translators: 1: PHP class name, 2: PHP parent class name, 3: version number, 4: __construct() method */
  4496 				/* translators: 1: PHP class name, 2: PHP parent class name, 3: version number, 4: __construct() method */
  3915 				trigger_error( sprintf( __( 'The called constructor method for %1$s in %2$s is <strong>deprecated</strong> since version %3$s! Use %4$s instead.' ),
  4497 				trigger_error(
  3916 					$class, $parent_class, $version, '<pre>__construct()</pre>' ) );
  4498 					sprintf(
       
  4499 						__( 'The called constructor method for %1$s in %2$s is <strong>deprecated</strong> since version %3$s! Use %4$s instead.' ),
       
  4500 						$class,
       
  4501 						$parent_class,
       
  4502 						$version,
       
  4503 						'<pre>__construct()</pre>'
       
  4504 					)
       
  4505 				);
  3917 			} else {
  4506 			} else {
  3918 				/* translators: 1: PHP class name, 2: version number, 3: __construct() method */
  4507 				/* translators: 1: PHP class name, 2: version number, 3: __construct() method */
  3919 				trigger_error( sprintf( __( 'The called constructor method for %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ),
  4508 				trigger_error(
  3920 					$class, $version, '<pre>__construct()</pre>' ) );
  4509 					sprintf(
       
  4510 						__( 'The called constructor method for %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ),
       
  4511 						$class,
       
  4512 						$version,
       
  4513 						'<pre>__construct()</pre>'
       
  4514 					)
       
  4515 				);
  3921 			}
  4516 			}
  3922 		} else {
  4517 		} else {
  3923 			if ( ! empty( $parent_class ) ) {
  4518 			if ( ! empty( $parent_class ) ) {
  3924 				trigger_error( sprintf( 'The called constructor method for %1$s in %2$s is <strong>deprecated</strong> since version %3$s! Use %4$s instead.',
  4519 				trigger_error(
  3925 					$class, $parent_class, $version, '<pre>__construct()</pre>' ) );
  4520 					sprintf(
       
  4521 						'The called constructor method for %1$s in %2$s is <strong>deprecated</strong> since version %3$s! Use %4$s instead.',
       
  4522 						$class,
       
  4523 						$parent_class,
       
  4524 						$version,
       
  4525 						'<pre>__construct()</pre>'
       
  4526 					)
       
  4527 				);
  3926 			} else {
  4528 			} else {
  3927 				trigger_error( sprintf( 'The called constructor method for %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.',
  4529 				trigger_error(
  3928 					$class, $version, '<pre>__construct()</pre>' ) );
  4530 					sprintf(
       
  4531 						'The called constructor method for %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.',
       
  4532 						$class,
       
  4533 						$version,
       
  4534 						'<pre>__construct()</pre>'
       
  4535 					)
       
  4536 				);
  3929 			}
  4537 			}
  3930 		}
  4538 		}
  3931 	}
  4539 	}
  3932 
  4540 
  3933 }
  4541 }
  3976 	if ( WP_DEBUG && apply_filters( 'deprecated_file_trigger_error', true ) ) {
  4584 	if ( WP_DEBUG && apply_filters( 'deprecated_file_trigger_error', true ) ) {
  3977 		$message = empty( $message ) ? '' : ' ' . $message;
  4585 		$message = empty( $message ) ? '' : ' ' . $message;
  3978 		if ( function_exists( '__' ) ) {
  4586 		if ( function_exists( '__' ) ) {
  3979 			if ( ! is_null( $replacement ) ) {
  4587 			if ( ! is_null( $replacement ) ) {
  3980 				/* translators: 1: PHP file name, 2: version number, 3: alternative file name */
  4588 				/* translators: 1: PHP file name, 2: version number, 3: alternative file name */
  3981 				trigger_error( sprintf( __('%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.'), $file, $version, $replacement ) . $message );
  4589 				trigger_error( sprintf( __( '%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ), $file, $version, $replacement ) . $message );
  3982 			} else {
  4590 			} else {
  3983 				/* translators: 1: PHP file name, 2: version number */
  4591 				/* translators: 1: PHP file name, 2: version number */
  3984 				trigger_error( sprintf( __('%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.'), $file, $version ) . $message );
  4592 				trigger_error( sprintf( __( '%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.' ), $file, $version ) . $message );
  3985 			}
  4593 			}
  3986 		} else {
  4594 		} else {
  3987 			if ( ! is_null( $replacement ) ) {
  4595 			if ( ! is_null( $replacement ) ) {
  3988 				trigger_error( sprintf( '%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.', $file, $version, $replacement ) . $message );
  4596 				trigger_error( sprintf( '%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.', $file, $version, $replacement ) . $message );
  3989 			} else {
  4597 			} else {
  4002  *
  4610  *
  4003  *     if ( ! empty( $deprecated ) ) {
  4611  *     if ( ! empty( $deprecated ) ) {
  4004  *         _deprecated_argument( __FUNCTION__, '3.0.0' );
  4612  *         _deprecated_argument( __FUNCTION__, '3.0.0' );
  4005  *     }
  4613  *     }
  4006  *
  4614  *
  4007  *
       
  4008  * There is a hook deprecated_argument_run that will be called that can be used
  4615  * There is a hook deprecated_argument_run that will be called that can be used
  4009  * to get the backtrace up to what file and function used the deprecated
  4616  * to get the backtrace up to what file and function used the deprecated
  4010  * argument.
  4617  * argument.
  4011  *
  4618  *
  4012  * The current behavior is to trigger a user error if WP_DEBUG is true.
  4619  * The current behavior is to trigger a user error if WP_DEBUG is true.
  4040 	 */
  4647 	 */
  4041 	if ( WP_DEBUG && apply_filters( 'deprecated_argument_trigger_error', true ) ) {
  4648 	if ( WP_DEBUG && apply_filters( 'deprecated_argument_trigger_error', true ) ) {
  4042 		if ( function_exists( '__' ) ) {
  4649 		if ( function_exists( '__' ) ) {
  4043 			if ( ! is_null( $message ) ) {
  4650 			if ( ! is_null( $message ) ) {
  4044 				/* translators: 1: PHP function name, 2: version number, 3: optional message regarding the change */
  4651 				/* translators: 1: PHP function name, 2: version number, 3: optional message regarding the change */
  4045 				trigger_error( sprintf( __('%1$s was called with an argument that is <strong>deprecated</strong> since version %2$s! %3$s'), $function, $version, $message ) );
  4652 				trigger_error( sprintf( __( '%1$s was called with an argument that is <strong>deprecated</strong> since version %2$s! %3$s' ), $function, $version, $message ) );
  4046 			} else {
  4653 			} else {
  4047 				/* translators: 1: PHP function name, 2: version number */
  4654 				/* translators: 1: PHP function name, 2: version number */
  4048 				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 ) );
  4655 				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 ) );
  4049 			}
  4656 			}
  4050 		} else {
  4657 		} else {
  4051 			if ( ! is_null( $message ) ) {
  4658 			if ( ! is_null( $message ) ) {
  4052 				trigger_error( sprintf( '%1$s was called with an argument that is <strong>deprecated</strong> since version %2$s! %3$s', $function, $version, $message ) );
  4659 				trigger_error( sprintf( '%1$s was called with an argument that is <strong>deprecated</strong> since version %2$s! %3$s', $function, $version, $message ) );
  4053 			} else {
  4660 			} else {
  4140 
  4747 
  4141 	/**
  4748 	/**
  4142 	 * Filters whether to trigger an error for _doing_it_wrong() calls.
  4749 	 * Filters whether to trigger an error for _doing_it_wrong() calls.
  4143 	 *
  4750 	 *
  4144 	 * @since 3.1.0
  4751 	 * @since 3.1.0
  4145 	 *
  4752 	 * @since 5.1.0 Added the $function, $message and $version parameters.
  4146 	 * @param bool $trigger Whether to trigger the error for _doing_it_wrong() calls. Default true.
  4753 	 *
       
  4754 	 * @param bool   $trigger  Whether to trigger the error for _doing_it_wrong() calls. Default true.
       
  4755 	 * @param string $function The function that was called.
       
  4756 	 * @param string $message  A message explaining what has been done incorrectly.
       
  4757 	 * @param string $version  The version of WordPress where the message was added.
  4147 	 */
  4758 	 */
  4148 	if ( WP_DEBUG && apply_filters( 'doing_it_wrong_trigger_error', true ) ) {
  4759 	if ( WP_DEBUG && apply_filters( 'doing_it_wrong_trigger_error', true, $function, $message, $version ) ) {
  4149 		if ( function_exists( '__' ) ) {
  4760 		if ( function_exists( '__' ) ) {
  4150 			if ( is_null( $version ) ) {
  4761 			if ( is_null( $version ) ) {
  4151 				$version = '';
  4762 				$version = '';
  4152 			} else {
  4763 			} else {
  4153 				/* translators: %s: version number */
  4764 				/* translators: %s: version number */
  4154 				$version = sprintf( __( '(This message was added in version %s.)' ), $version );
  4765 				$version = sprintf( __( '(This message was added in version %s.)' ), $version );
  4155 			}
  4766 			}
  4156 			/* translators: %s: Codex URL */
  4767 			/* translators: %s: Codex URL */
  4157 			$message .= ' ' . sprintf( __( 'Please see <a href="%s">Debugging in WordPress</a> for more information.' ),
  4768 			$message .= ' ' . sprintf(
       
  4769 				__( 'Please see <a href="%s">Debugging in WordPress</a> for more information.' ),
  4158 				__( 'https://codex.wordpress.org/Debugging_in_WordPress' )
  4770 				__( 'https://codex.wordpress.org/Debugging_in_WordPress' )
  4159 			);
  4771 			);
  4160 			/* translators: Developer debugging message. 1: PHP function name, 2: Explanatory message, 3: Version information message */
  4772 			/* translators: Developer debugging message. 1: PHP function name, 2: Explanatory message, 3: Version information message */
  4161 			trigger_error( sprintf( __( '%1$s was called <strong>incorrectly</strong>. %2$s %3$s' ), $function, $message, $version ) );
  4773 			trigger_error( sprintf( __( '%1$s was called <strong>incorrectly</strong>. %2$s %3$s' ), $function, $message, $version ) );
  4162 		} else {
  4774 		} else {
  4163 			if ( is_null( $version ) ) {
  4775 			if ( is_null( $version ) ) {
  4164 				$version = '';
  4776 				$version = '';
  4165 			} else {
  4777 			} else {
  4166 				$version = sprintf( '(This message was added in version %s.)', $version );
  4778 				$version = sprintf( '(This message was added in version %s.)', $version );
  4167 			}
  4779 			}
  4168 			$message .= sprintf( ' Please see <a href="%s">Debugging in WordPress</a> for more information.',
  4780 			$message .= sprintf(
       
  4781 				' Please see <a href="%s">Debugging in WordPress</a> for more information.',
  4169 				'https://codex.wordpress.org/Debugging_in_WordPress'
  4782 				'https://codex.wordpress.org/Debugging_in_WordPress'
  4170 			);
  4783 			);
  4171 			trigger_error( sprintf( '%1$s was called <strong>incorrectly</strong>. %2$s %3$s', $function, $message, $version ) );
  4784 			trigger_error( sprintf( '%1$s was called <strong>incorrectly</strong>. %2$s %3$s', $function, $message, $version ) );
  4172 		}
  4785 		}
  4173 	}
  4786 	}
  4179  * @since 2.5.0
  4792  * @since 2.5.0
  4180  *
  4793  *
  4181  * @return bool Whether the server is running lighttpd < 1.5.0.
  4794  * @return bool Whether the server is running lighttpd < 1.5.0.
  4182  */
  4795  */
  4183 function is_lighttpd_before_150() {
  4796 function is_lighttpd_before_150() {
  4184 	$server_parts = explode( '/', isset( $_SERVER['SERVER_SOFTWARE'] )? $_SERVER['SERVER_SOFTWARE'] : '' );
  4797 	$server_parts    = explode( '/', isset( $_SERVER['SERVER_SOFTWARE'] ) ? $_SERVER['SERVER_SOFTWARE'] : '' );
  4185 	$server_parts[1] = isset( $server_parts[1] )? $server_parts[1] : '';
  4798 	$server_parts[1] = isset( $server_parts[1] ) ? $server_parts[1] : '';
  4186 	return  'lighttpd' == $server_parts[0] && -1 == version_compare( $server_parts[1], '1.5.0' );
  4799 	return  'lighttpd' == $server_parts[0] && -1 == version_compare( $server_parts[1], '1.5.0' );
  4187 }
  4800 }
  4188 
  4801 
  4189 /**
  4802 /**
  4190  * Does the specified module exist in the Apache config?
  4803  * Does the specified module exist in the Apache config?
  4195  *
  4808  *
  4196  * @param string $mod     The module, e.g. mod_rewrite.
  4809  * @param string $mod     The module, e.g. mod_rewrite.
  4197  * @param bool   $default Optional. The default return value if the module is not found. Default false.
  4810  * @param bool   $default Optional. The default return value if the module is not found. Default false.
  4198  * @return bool Whether the specified module is loaded.
  4811  * @return bool Whether the specified module is loaded.
  4199  */
  4812  */
  4200 function apache_mod_loaded($mod, $default = false) {
  4813 function apache_mod_loaded( $mod, $default = false ) {
  4201 	global $is_apache;
  4814 	global $is_apache;
  4202 
  4815 
  4203 	if ( !$is_apache )
  4816 	if ( ! $is_apache ) {
  4204 		return false;
  4817 		return false;
       
  4818 	}
  4205 
  4819 
  4206 	if ( function_exists( 'apache_get_modules' ) ) {
  4820 	if ( function_exists( 'apache_get_modules' ) ) {
  4207 		$mods = apache_get_modules();
  4821 		$mods = apache_get_modules();
  4208 		if ( in_array($mod, $mods) )
  4822 		if ( in_array( $mod, $mods ) ) {
  4209 			return true;
  4823 			return true;
       
  4824 		}
  4210 	} elseif ( function_exists( 'phpinfo' ) && false === strpos( ini_get( 'disable_functions' ), 'phpinfo' ) ) {
  4825 	} elseif ( function_exists( 'phpinfo' ) && false === strpos( ini_get( 'disable_functions' ), 'phpinfo' ) ) {
  4211 			ob_start();
  4826 			ob_start();
  4212 			phpinfo(8);
  4827 			phpinfo( 8 );
  4213 			$phpinfo = ob_get_clean();
  4828 			$phpinfo = ob_get_clean();
  4214 			if ( false !== strpos($phpinfo, $mod) )
  4829 		if ( false !== strpos( $phpinfo, $mod ) ) {
  4215 				return true;
  4830 			return true;
       
  4831 		}
  4216 	}
  4832 	}
  4217 	return $default;
  4833 	return $default;
  4218 }
  4834 }
  4219 
  4835 
  4220 /**
  4836 /**
  4238 		 * Next we check if the URL Rewrite Module 1.1 is loaded and enabled for the web site. When
  4854 		 * Next we check if the URL Rewrite Module 1.1 is loaded and enabled for the web site. When
  4239 		 * URL Rewrite 1.1 is loaded it always sets a server variable called 'IIS_UrlRewriteModule'.
  4855 		 * URL Rewrite 1.1 is loaded it always sets a server variable called 'IIS_UrlRewriteModule'.
  4240 		 * Lastly we make sure that PHP is running via FastCGI. This is important because if it runs
  4856 		 * Lastly we make sure that PHP is running via FastCGI. This is important because if it runs
  4241 		 * via ISAPI then pretty permalinks will not work.
  4857 		 * via ISAPI then pretty permalinks will not work.
  4242 		 */
  4858 		 */
  4243 		$supports_permalinks = class_exists( 'DOMDocument', false ) && isset($_SERVER['IIS_UrlRewriteModule']) && ( PHP_SAPI == 'cgi-fcgi' );
  4859 		$supports_permalinks = class_exists( 'DOMDocument', false ) && isset( $_SERVER['IIS_UrlRewriteModule'] ) && ( PHP_SAPI == 'cgi-fcgi' );
  4244 	}
  4860 	}
  4245 
  4861 
  4246 	/**
  4862 	/**
  4247 	 * Filters whether IIS 7+ supports pretty permalinks.
  4863 	 * Filters whether IIS 7+ supports pretty permalinks.
  4248 	 *
  4864 	 *
  4283 	if ( false !== strpos( $file, '../' ) && '../' !== mb_substr( $file, -3, 3 ) ) {
  4899 	if ( false !== strpos( $file, '../' ) && '../' !== mb_substr( $file, -3, 3 ) ) {
  4284 		return 1;
  4900 		return 1;
  4285 	}
  4901 	}
  4286 
  4902 
  4287 	// Files not in the allowed file list are not allowed:
  4903 	// Files not in the allowed file list are not allowed:
  4288 	if ( ! empty( $allowed_files ) && ! in_array( $file, $allowed_files ) )
  4904 	if ( ! empty( $allowed_files ) && ! in_array( $file, $allowed_files ) ) {
  4289 		return 3;
  4905 		return 3;
       
  4906 	}
  4290 
  4907 
  4291 	// Absolute Windows drive paths are not allowed:
  4908 	// Absolute Windows drive paths are not allowed:
  4292 	if (':' == substr( $file, 1, 1 ) )
  4909 	if ( ':' == substr( $file, 1, 1 ) ) {
  4293 		return 2;
  4910 		return 2;
       
  4911 	}
  4294 
  4912 
  4295 	return 0;
  4913 	return 0;
  4296 }
  4914 }
  4297 
  4915 
  4298 /**
  4916 /**
  4306  * @return bool True if forced, false if not forced.
  4924  * @return bool True if forced, false if not forced.
  4307  */
  4925  */
  4308 function force_ssl_admin( $force = null ) {
  4926 function force_ssl_admin( $force = null ) {
  4309 	static $forced = false;
  4927 	static $forced = false;
  4310 
  4928 
  4311 	if ( !is_null( $force ) ) {
  4929 	if ( ! is_null( $force ) ) {
  4312 		$old_forced = $forced;
  4930 		$old_forced = $forced;
  4313 		$forced = $force;
  4931 		$forced     = $force;
  4314 		return $old_forced;
  4932 		return $old_forced;
  4315 	}
  4933 	}
  4316 
  4934 
  4317 	return $forced;
  4935 	return $forced;
  4318 }
  4936 }
  4326  * @since 2.6.0
  4944  * @since 2.6.0
  4327  *
  4945  *
  4328  * @return string The guessed URL.
  4946  * @return string The guessed URL.
  4329  */
  4947  */
  4330 function wp_guess_url() {
  4948 function wp_guess_url() {
  4331 	if ( defined('WP_SITEURL') && '' != WP_SITEURL ) {
  4949 	if ( defined( 'WP_SITEURL' ) && '' != WP_SITEURL ) {
  4332 		$url = WP_SITEURL;
  4950 		$url = WP_SITEURL;
  4333 	} else {
  4951 	} else {
  4334 		$abspath_fix = str_replace( '\\', '/', ABSPATH );
  4952 		$abspath_fix         = str_replace( '\\', '/', ABSPATH );
  4335 		$script_filename_dir = dirname( $_SERVER['SCRIPT_FILENAME'] );
  4953 		$script_filename_dir = dirname( $_SERVER['SCRIPT_FILENAME'] );
  4336 
  4954 
  4337 		// The request is for the admin
  4955 		// The request is for the admin
  4338 		if ( strpos( $_SERVER['REQUEST_URI'], 'wp-admin' ) !== false || strpos( $_SERVER['REQUEST_URI'], 'wp-login.php' ) !== false ) {
  4956 		if ( strpos( $_SERVER['REQUEST_URI'], 'wp-admin' ) !== false || strpos( $_SERVER['REQUEST_URI'], 'wp-login.php' ) !== false ) {
  4339 			$path = preg_replace( '#/(wp-admin/.*|wp-login.php)#i', '', $_SERVER['REQUEST_URI'] );
  4957 			$path = preg_replace( '#/(wp-admin/.*|wp-login.php)#i', '', $_SERVER['REQUEST_URI'] );
  4340 
  4958 
  4341 		// The request is for a file in ABSPATH
  4959 			// The request is for a file in ABSPATH
  4342 		} elseif ( $script_filename_dir . '/' == $abspath_fix ) {
  4960 		} elseif ( $script_filename_dir . '/' == $abspath_fix ) {
  4343 			// Strip off any file/query params in the path
  4961 			// Strip off any file/query params in the path
  4344 			$path = preg_replace( '#/[^/]*$#i', '', $_SERVER['PHP_SELF'] );
  4962 			$path = preg_replace( '#/[^/]*$#i', '', $_SERVER['PHP_SELF'] );
  4345 
  4963 
  4346 		} else {
  4964 		} else {
  4347 			if ( false !== strpos( $_SERVER['SCRIPT_FILENAME'], $abspath_fix ) ) {
  4965 			if ( false !== strpos( $_SERVER['SCRIPT_FILENAME'], $abspath_fix ) ) {
  4348 				// Request is hitting a file inside ABSPATH
  4966 				// Request is hitting a file inside ABSPATH
  4349 				$directory = str_replace( ABSPATH, '', $script_filename_dir );
  4967 				$directory = str_replace( ABSPATH, '', $script_filename_dir );
  4350 				// Strip off the sub directory, and any file/query params
  4968 				// Strip off the sub directory, and any file/query params
  4351 				$path = preg_replace( '#/' . preg_quote( $directory, '#' ) . '/[^/]*$#i', '' , $_SERVER['REQUEST_URI'] );
  4969 				$path = preg_replace( '#/' . preg_quote( $directory, '#' ) . '/[^/]*$#i', '', $_SERVER['REQUEST_URI'] );
  4352 			} elseif ( false !== strpos( $abspath_fix, $script_filename_dir ) ) {
  4970 			} elseif ( false !== strpos( $abspath_fix, $script_filename_dir ) ) {
  4353 				// Request is hitting a file above ABSPATH
  4971 				// Request is hitting a file above ABSPATH
  4354 				$subdirectory = substr( $abspath_fix, strpos( $abspath_fix, $script_filename_dir ) + strlen( $script_filename_dir ) );
  4972 				$subdirectory = substr( $abspath_fix, strpos( $abspath_fix, $script_filename_dir ) + strlen( $script_filename_dir ) );
  4355 				// Strip off any file/query params from the path, appending the sub directory to the installation
  4973 				// Strip off any file/query params from the path, appending the sub directory to the installation
  4356 				$path = preg_replace( '#/[^/]*$#i', '' , $_SERVER['REQUEST_URI'] ) . $subdirectory;
  4974 				$path = preg_replace( '#/[^/]*$#i', '', $_SERVER['REQUEST_URI'] ) . $subdirectory;
  4357 			} else {
  4975 			} else {
  4358 				$path = $_SERVER['REQUEST_URI'];
  4976 				$path = $_SERVER['REQUEST_URI'];
  4359 			}
  4977 			}
  4360 		}
  4978 		}
  4361 
  4979 
  4362 		$schema = is_ssl() ? 'https://' : 'http://'; // set_url_scheme() is not defined yet
  4980 		$schema = is_ssl() ? 'https://' : 'http://'; // set_url_scheme() is not defined yet
  4363 		$url = $schema . $_SERVER['HTTP_HOST'] . $path;
  4981 		$url    = $schema . $_SERVER['HTTP_HOST'] . $path;
  4364 	}
  4982 	}
  4365 
  4983 
  4366 	return rtrim($url, '/');
  4984 	return rtrim( $url, '/' );
  4367 }
  4985 }
  4368 
  4986 
  4369 /**
  4987 /**
  4370  * Temporarily suspend cache additions.
  4988  * Temporarily suspend cache additions.
  4371  *
  4989  *
  4384  * @return bool The current suspend setting
  5002  * @return bool The current suspend setting
  4385  */
  5003  */
  4386 function wp_suspend_cache_addition( $suspend = null ) {
  5004 function wp_suspend_cache_addition( $suspend = null ) {
  4387 	static $_suspend = false;
  5005 	static $_suspend = false;
  4388 
  5006 
  4389 	if ( is_bool( $suspend ) )
  5007 	if ( is_bool( $suspend ) ) {
  4390 		$_suspend = $suspend;
  5008 		$_suspend = $suspend;
       
  5009 	}
  4391 
  5010 
  4392 	return $_suspend;
  5011 	return $_suspend;
  4393 }
  5012 }
  4394 
  5013 
  4395 /**
  5014 /**
  4407  * @return bool The current suspend setting.
  5026  * @return bool The current suspend setting.
  4408  */
  5027  */
  4409 function wp_suspend_cache_invalidation( $suspend = true ) {
  5028 function wp_suspend_cache_invalidation( $suspend = true ) {
  4410 	global $_wp_suspend_cache_invalidation;
  5029 	global $_wp_suspend_cache_invalidation;
  4411 
  5030 
  4412 	$current_suspend = $_wp_suspend_cache_invalidation;
  5031 	$current_suspend                = $_wp_suspend_cache_invalidation;
  4413 	$_wp_suspend_cache_invalidation = $suspend;
  5032 	$_wp_suspend_cache_invalidation = $suspend;
  4414 	return $current_suspend;
  5033 	return $current_suspend;
  4415 }
  5034 }
  4416 
  5035 
  4417 /**
  5036 /**
  4418  * Determine whether a site is the main site of the current network.
  5037  * Determine whether a site is the main site of the current network.
  4419  *
  5038  *
  4420  * @since 3.0.0
  5039  * @since 3.0.0
  4421  * @since 4.9.0 The $network_id parameter has been added.
  5040  * @since 4.9.0 The `$network_id` parameter was added.
  4422  *
  5041  *
  4423  * @param int $site_id    Optional. Site ID to test. Defaults to current site.
  5042  * @param int $site_id    Optional. Site ID to test. Defaults to current site.
  4424  * @param int $network_id Optional. Network ID of the network to check for.
  5043  * @param int $network_id Optional. Network ID of the network to check for.
  4425  *                        Defaults to current network.
  5044  *                        Defaults to current network.
  4426  * @return bool True if $site_id is the main site of the network, or if not
  5045  * @return bool True if $site_id is the main site of the network, or if not
  4502 		$main_network_id = PRIMARY_NETWORK_ID;
  5121 		$main_network_id = PRIMARY_NETWORK_ID;
  4503 	} elseif ( isset( $current_network->id ) && 1 === (int) $current_network->id ) {
  5122 	} elseif ( isset( $current_network->id ) && 1 === (int) $current_network->id ) {
  4504 		// If the current network has an ID of 1, assume it is the main network.
  5123 		// If the current network has an ID of 1, assume it is the main network.
  4505 		$main_network_id = 1;
  5124 		$main_network_id = 1;
  4506 	} else {
  5125 	} else {
  4507 		$_networks = get_networks( array( 'fields' => 'ids', 'number' => 1 ) );
  5126 		$_networks       = get_networks(
       
  5127 			array(
       
  5128 				'fields' => 'ids',
       
  5129 				'number' => 1,
       
  5130 			)
       
  5131 		);
  4508 		$main_network_id = array_shift( $_networks );
  5132 		$main_network_id = array_shift( $_networks );
  4509 	}
  5133 	}
  4510 
  5134 
  4511 	/**
  5135 	/**
  4512 	 * Filters the main network ID.
  5136 	 * Filters the main network ID.
  4526  * @staticvar bool $global_terms
  5150  * @staticvar bool $global_terms
  4527  *
  5151  *
  4528  * @return bool True if multisite and global terms enabled.
  5152  * @return bool True if multisite and global terms enabled.
  4529  */
  5153  */
  4530 function global_terms_enabled() {
  5154 function global_terms_enabled() {
  4531 	if ( ! is_multisite() )
  5155 	if ( ! is_multisite() ) {
  4532 		return false;
  5156 		return false;
       
  5157 	}
  4533 
  5158 
  4534 	static $global_terms = null;
  5159 	static $global_terms = null;
  4535 	if ( is_null( $global_terms ) ) {
  5160 	if ( is_null( $global_terms ) ) {
  4536 
  5161 
  4537 		/**
  5162 		/**
  4543 		 * @since 3.0.0
  5168 		 * @since 3.0.0
  4544 		 *
  5169 		 *
  4545 		 * @param null $enabled Whether global terms are enabled.
  5170 		 * @param null $enabled Whether global terms are enabled.
  4546 		 */
  5171 		 */
  4547 		$filter = apply_filters( 'global_terms_enabled', null );
  5172 		$filter = apply_filters( 'global_terms_enabled', null );
  4548 		if ( ! is_null( $filter ) )
  5173 		if ( ! is_null( $filter ) ) {
  4549 			$global_terms = (bool) $filter;
  5174 			$global_terms = (bool) $filter;
  4550 		else
  5175 		} else {
  4551 			$global_terms = (bool) get_site_option( 'global_terms_enabled', false );
  5176 			$global_terms = (bool) get_site_option( 'global_terms_enabled', false );
       
  5177 		}
  4552 	}
  5178 	}
  4553 	return $global_terms;
  5179 	return $global_terms;
  4554 }
  5180 }
  4555 
  5181 
  4556 /**
  5182 /**
       
  5183  * Determines whether site meta is enabled.
       
  5184  *
       
  5185  * This function checks whether the 'blogmeta' database table exists. The result is saved as
       
  5186  * a setting for the main network, making it essentially a global setting. Subsequent requests
       
  5187  * will refer to this setting instead of running the query.
       
  5188  *
       
  5189  * @since 5.1.0
       
  5190  *
       
  5191  * @global wpdb $wpdb WordPress database abstraction object.
       
  5192  *
       
  5193  * @return bool True if site meta is supported, false otherwise.
       
  5194  */
       
  5195 function is_site_meta_supported() {
       
  5196 	global $wpdb;
       
  5197 
       
  5198 	if ( ! is_multisite() ) {
       
  5199 		return false;
       
  5200 	}
       
  5201 
       
  5202 	$network_id = get_main_network_id();
       
  5203 
       
  5204 	$supported = get_network_option( $network_id, 'site_meta_supported', false );
       
  5205 	if ( false === $supported ) {
       
  5206 		$supported = $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->blogmeta}'" ) ? 1 : 0;
       
  5207 
       
  5208 		update_network_option( $network_id, 'site_meta_supported', $supported );
       
  5209 	}
       
  5210 
       
  5211 	return (bool) $supported;
       
  5212 }
       
  5213 
       
  5214 /**
  4557  * gmt_offset modification for smart timezone handling.
  5215  * gmt_offset modification for smart timezone handling.
  4558  *
  5216  *
  4559  * Overrides the gmt_offset option if we have a timezone_string available.
  5217  * Overrides the gmt_offset option if we have a timezone_string available.
  4560  *
  5218  *
  4561  * @since 2.8.0
  5219  * @since 2.8.0
  4562  *
  5220  *
  4563  * @return float|false Timezone GMT offset, false otherwise.
  5221  * @return float|false Timezone GMT offset, false otherwise.
  4564  */
  5222  */
  4565 function wp_timezone_override_offset() {
  5223 function wp_timezone_override_offset() {
  4566 	if ( !$timezone_string = get_option( 'timezone_string' ) ) {
  5224 	if ( ! $timezone_string = get_option( 'timezone_string' ) ) {
  4567 		return false;
  5225 		return false;
  4568 	}
  5226 	}
  4569 
  5227 
  4570 	$timezone_object = timezone_open( $timezone_string );
  5228 	$timezone_object = timezone_open( $timezone_string );
  4571 	$datetime_object = date_create();
  5229 	$datetime_object = date_create();
  4637  * @return string
  5295  * @return string
  4638  */
  5296  */
  4639 function wp_timezone_choice( $selected_zone, $locale = null ) {
  5297 function wp_timezone_choice( $selected_zone, $locale = null ) {
  4640 	static $mo_loaded = false, $locale_loaded = null;
  5298 	static $mo_loaded = false, $locale_loaded = null;
  4641 
  5299 
  4642 	$continents = array( 'Africa', 'America', 'Antarctica', 'Arctic', 'Asia', 'Atlantic', 'Australia', 'Europe', 'Indian', 'Pacific');
  5300 	$continents = array( 'Africa', 'America', 'Antarctica', 'Arctic', 'Asia', 'Atlantic', 'Australia', 'Europe', 'Indian', 'Pacific' );
  4643 
  5301 
  4644 	// Load translations for continents and cities.
  5302 	// Load translations for continents and cities.
  4645 	if ( ! $mo_loaded || $locale !== $locale_loaded ) {
  5303 	if ( ! $mo_loaded || $locale !== $locale_loaded ) {
  4646 		$locale_loaded = $locale ? $locale : get_locale();
  5304 		$locale_loaded = $locale ? $locale : get_locale();
  4647 		$mofile = WP_LANG_DIR . '/continents-cities-' . $locale_loaded . '.mo';
  5305 		$mofile        = WP_LANG_DIR . '/continents-cities-' . $locale_loaded . '.mo';
  4648 		unload_textdomain( 'continents-cities' );
  5306 		unload_textdomain( 'continents-cities' );
  4649 		load_textdomain( 'continents-cities', $mofile );
  5307 		load_textdomain( 'continents-cities', $mofile );
  4650 		$mo_loaded = true;
  5308 		$mo_loaded = true;
  4651 	}
  5309 	}
  4652 
  5310 
  4653 	$zonen = array();
  5311 	$zonen = array();
  4654 	foreach ( timezone_identifiers_list() as $zone ) {
  5312 	foreach ( timezone_identifiers_list() as $zone ) {
  4655 		$zone = explode( '/', $zone );
  5313 		$zone = explode( '/', $zone );
  4656 		if ( !in_array( $zone[0], $continents ) ) {
  5314 		if ( ! in_array( $zone[0], $continents ) ) {
  4657 			continue;
  5315 			continue;
  4658 		}
  5316 		}
  4659 
  5317 
  4660 		// This determines what gets set and translated - we don't translate Etc/* strings here, they are done later
  5318 		// This determines what gets set and translated - we don't translate Etc/* strings here, they are done later
  4661 		$exists = array(
  5319 		$exists    = array(
  4662 			0 => ( isset( $zone[0] ) && $zone[0] ),
  5320 			0 => ( isset( $zone[0] ) && $zone[0] ),
  4663 			1 => ( isset( $zone[1] ) && $zone[1] ),
  5321 			1 => ( isset( $zone[1] ) && $zone[1] ),
  4664 			2 => ( isset( $zone[2] ) && $zone[2] ),
  5322 			2 => ( isset( $zone[2] ) && $zone[2] ),
  4665 		);
  5323 		);
  4666 		$exists[3] = ( $exists[0] && 'Etc' !== $zone[0] );
  5324 		$exists[3] = ( $exists[0] && 'Etc' !== $zone[0] );
  4667 		$exists[4] = ( $exists[1] && $exists[3] );
  5325 		$exists[4] = ( $exists[1] && $exists[3] );
  4668 		$exists[5] = ( $exists[2] && $exists[3] );
  5326 		$exists[5] = ( $exists[2] && $exists[3] );
  4669 
  5327 
       
  5328 		// phpcs:disable WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText
  4670 		$zonen[] = array(
  5329 		$zonen[] = array(
  4671 			'continent'   => ( $exists[0] ? $zone[0] : '' ),
  5330 			'continent'   => ( $exists[0] ? $zone[0] : '' ),
  4672 			'city'        => ( $exists[1] ? $zone[1] : '' ),
  5331 			'city'        => ( $exists[1] ? $zone[1] : '' ),
  4673 			'subcity'     => ( $exists[2] ? $zone[2] : '' ),
  5332 			'subcity'     => ( $exists[2] ? $zone[2] : '' ),
  4674 			't_continent' => ( $exists[3] ? translate( str_replace( '_', ' ', $zone[0] ), 'continents-cities' ) : '' ),
  5333 			't_continent' => ( $exists[3] ? translate( str_replace( '_', ' ', $zone[0] ), 'continents-cities' ) : '' ),
  4675 			't_city'      => ( $exists[4] ? translate( str_replace( '_', ' ', $zone[1] ), 'continents-cities' ) : '' ),
  5334 			't_city'      => ( $exists[4] ? translate( str_replace( '_', ' ', $zone[1] ), 'continents-cities' ) : '' ),
  4676 			't_subcity'   => ( $exists[5] ? translate( str_replace( '_', ' ', $zone[2] ), 'continents-cities' ) : '' )
  5335 			't_subcity'   => ( $exists[5] ? translate( str_replace( '_', ' ', $zone[2] ), 'continents-cities' ) : '' ),
  4677 		);
  5336 		);
       
  5337 		// phpcs:enable
  4678 	}
  5338 	}
  4679 	usort( $zonen, '_wp_timezone_choice_usort_callback' );
  5339 	usort( $zonen, '_wp_timezone_choice_usort_callback' );
  4680 
  5340 
  4681 	$structure = array();
  5341 	$structure = array();
  4682 
  5342 
  4693 			$display = $zone['t_continent'];
  5353 			$display = $zone['t_continent'];
  4694 		} else {
  5354 		} else {
  4695 			// It's inside a continent group
  5355 			// It's inside a continent group
  4696 
  5356 
  4697 			// Continent optgroup
  5357 			// Continent optgroup
  4698 			if ( !isset( $zonen[$key - 1] ) || $zonen[$key - 1]['continent'] !== $zone['continent'] ) {
  5358 			if ( ! isset( $zonen[ $key - 1 ] ) || $zonen[ $key - 1 ]['continent'] !== $zone['continent'] ) {
  4699 				$label = $zone['t_continent'];
  5359 				$label       = $zone['t_continent'];
  4700 				$structure[] = '<optgroup label="'. esc_attr( $label ) .'">';
  5360 				$structure[] = '<optgroup label="' . esc_attr( $label ) . '">';
  4701 			}
  5361 			}
  4702 
  5362 
  4703 			// Add the city to the value
  5363 			// Add the city to the value
  4704 			$value[] = $zone['city'];
  5364 			$value[] = $zone['city'];
  4705 
  5365 
  4706 			$display = $zone['t_city'];
  5366 			$display = $zone['t_city'];
  4707 			if ( !empty( $zone['subcity'] ) ) {
  5367 			if ( ! empty( $zone['subcity'] ) ) {
  4708 				// Add the subcity to the value
  5368 				// Add the subcity to the value
  4709 				$value[] = $zone['subcity'];
  5369 				$value[]  = $zone['subcity'];
  4710 				$display .= ' - ' . $zone['t_subcity'];
  5370 				$display .= ' - ' . $zone['t_subcity'];
  4711 			}
  5371 			}
  4712 		}
  5372 		}
  4713 
  5373 
  4714 		// Build the value
  5374 		// Build the value
  4715 		$value = join( '/', $value );
  5375 		$value    = join( '/', $value );
  4716 		$selected = '';
  5376 		$selected = '';
  4717 		if ( $value === $selected_zone ) {
  5377 		if ( $value === $selected_zone ) {
  4718 			$selected = 'selected="selected" ';
  5378 			$selected = 'selected="selected" ';
  4719 		}
  5379 		}
  4720 		$structure[] = '<option ' . $selected . 'value="' . esc_attr( $value ) . '">' . esc_html( $display ) . "</option>";
  5380 		$structure[] = '<option ' . $selected . 'value="' . esc_attr( $value ) . '">' . esc_html( $display ) . '</option>';
  4721 
  5381 
  4722 		// Close continent optgroup
  5382 		// Close continent optgroup
  4723 		if ( !empty( $zone['city'] ) && ( !isset($zonen[$key + 1]) || (isset( $zonen[$key + 1] ) && $zonen[$key + 1]['continent'] !== $zone['continent']) ) ) {
  5383 		if ( ! empty( $zone['city'] ) && ( ! isset( $zonen[ $key + 1 ] ) || ( isset( $zonen[ $key + 1 ] ) && $zonen[ $key + 1 ]['continent'] !== $zone['continent'] ) ) ) {
  4724 			$structure[] = '</optgroup>';
  5384 			$structure[] = '</optgroup>';
  4725 		}
  5385 		}
  4726 	}
  5386 	}
  4727 
  5387 
  4728 	// Do UTC
  5388 	// Do UTC
  4729 	$structure[] = '<optgroup label="'. esc_attr__( 'UTC' ) .'">';
  5389 	$structure[] = '<optgroup label="' . esc_attr__( 'UTC' ) . '">';
  4730 	$selected = '';
  5390 	$selected    = '';
  4731 	if ( 'UTC' === $selected_zone )
  5391 	if ( 'UTC' === $selected_zone ) {
  4732 		$selected = 'selected="selected" ';
  5392 		$selected = 'selected="selected" ';
  4733 	$structure[] = '<option ' . $selected . 'value="' . esc_attr( 'UTC' ) . '">' . __('UTC') . '</option>';
  5393 	}
       
  5394 	$structure[] = '<option ' . $selected . 'value="' . esc_attr( 'UTC' ) . '">' . __( 'UTC' ) . '</option>';
  4734 	$structure[] = '</optgroup>';
  5395 	$structure[] = '</optgroup>';
  4735 
  5396 
  4736 	// Do manual UTC offsets
  5397 	// Do manual UTC offsets
  4737 	$structure[] = '<optgroup label="'. esc_attr__( 'Manual Offsets' ) .'">';
  5398 	$structure[]  = '<optgroup label="' . esc_attr__( 'Manual Offsets' ) . '">';
  4738 	$offset_range = array (-12, -11.5, -11, -10.5, -10, -9.5, -9, -8.5, -8, -7.5, -7, -6.5, -6, -5.5, -5, -4.5, -4, -3.5, -3, -2.5, -2, -1.5, -1, -0.5,
  5399 	$offset_range = array(
  4739 		0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 5.75, 6, 6.5, 7, 7.5, 8, 8.5, 8.75, 9, 9.5, 10, 10.5, 11, 11.5, 12, 12.75, 13, 13.75, 14);
  5400 		-12,
       
  5401 		-11.5,
       
  5402 		-11,
       
  5403 		-10.5,
       
  5404 		-10,
       
  5405 		-9.5,
       
  5406 		-9,
       
  5407 		-8.5,
       
  5408 		-8,
       
  5409 		-7.5,
       
  5410 		-7,
       
  5411 		-6.5,
       
  5412 		-6,
       
  5413 		-5.5,
       
  5414 		-5,
       
  5415 		-4.5,
       
  5416 		-4,
       
  5417 		-3.5,
       
  5418 		-3,
       
  5419 		-2.5,
       
  5420 		-2,
       
  5421 		-1.5,
       
  5422 		-1,
       
  5423 		-0.5,
       
  5424 		0,
       
  5425 		0.5,
       
  5426 		1,
       
  5427 		1.5,
       
  5428 		2,
       
  5429 		2.5,
       
  5430 		3,
       
  5431 		3.5,
       
  5432 		4,
       
  5433 		4.5,
       
  5434 		5,
       
  5435 		5.5,
       
  5436 		5.75,
       
  5437 		6,
       
  5438 		6.5,
       
  5439 		7,
       
  5440 		7.5,
       
  5441 		8,
       
  5442 		8.5,
       
  5443 		8.75,
       
  5444 		9,
       
  5445 		9.5,
       
  5446 		10,
       
  5447 		10.5,
       
  5448 		11,
       
  5449 		11.5,
       
  5450 		12,
       
  5451 		12.75,
       
  5452 		13,
       
  5453 		13.75,
       
  5454 		14,
       
  5455 	);
  4740 	foreach ( $offset_range as $offset ) {
  5456 	foreach ( $offset_range as $offset ) {
  4741 		if ( 0 <= $offset )
  5457 		if ( 0 <= $offset ) {
  4742 			$offset_name = '+' . $offset;
  5458 			$offset_name = '+' . $offset;
  4743 		else
  5459 		} else {
  4744 			$offset_name = (string) $offset;
  5460 			$offset_name = (string) $offset;
       
  5461 		}
  4745 
  5462 
  4746 		$offset_value = $offset_name;
  5463 		$offset_value = $offset_name;
  4747 		$offset_name = str_replace(array('.25','.5','.75'), array(':15',':30',':45'), $offset_name);
  5464 		$offset_name  = str_replace( array( '.25', '.5', '.75' ), array( ':15', ':30', ':45' ), $offset_name );
  4748 		$offset_name = 'UTC' . $offset_name;
  5465 		$offset_name  = 'UTC' . $offset_name;
  4749 		$offset_value = 'UTC' . $offset_value;
  5466 		$offset_value = 'UTC' . $offset_value;
  4750 		$selected = '';
  5467 		$selected     = '';
  4751 		if ( $offset_value === $selected_zone )
  5468 		if ( $offset_value === $selected_zone ) {
  4752 			$selected = 'selected="selected" ';
  5469 			$selected = 'selected="selected" ';
  4753 		$structure[] = '<option ' . $selected . 'value="' . esc_attr( $offset_value ) . '">' . esc_html( $offset_name ) . "</option>";
  5470 		}
       
  5471 		$structure[] = '<option ' . $selected . 'value="' . esc_attr( $offset_value ) . '">' . esc_html( $offset_name ) . '</option>';
  4754 
  5472 
  4755 	}
  5473 	}
  4756 	$structure[] = '</optgroup>';
  5474 	$structure[] = '</optgroup>';
  4757 
  5475 
  4758 	return join( "\n", $structure );
  5476 	return join( "\n", $structure );
  4768  *
  5486  *
  4769  * @param string $str Header comment to clean up.
  5487  * @param string $str Header comment to clean up.
  4770  * @return string
  5488  * @return string
  4771  */
  5489  */
  4772 function _cleanup_header_comment( $str ) {
  5490 function _cleanup_header_comment( $str ) {
  4773 	return trim(preg_replace("/\s*(?:\*\/|\?>).*/", '', $str));
  5491 	return trim( preg_replace( '/\s*(?:\*\/|\?>).*/', '', $str ) );
  4774 }
  5492 }
  4775 
  5493 
  4776 /**
  5494 /**
  4777  * Permanently delete comments or posts of any type that have held a status
  5495  * Permanently delete comments or posts of any type that have held a status
  4778  * of 'trash' for the number of days defined in EMPTY_TRASH_DAYS.
  5496  * of 'trash' for the number of days defined in EMPTY_TRASH_DAYS.
  4786 function wp_scheduled_delete() {
  5504 function wp_scheduled_delete() {
  4787 	global $wpdb;
  5505 	global $wpdb;
  4788 
  5506 
  4789 	$delete_timestamp = time() - ( DAY_IN_SECONDS * EMPTY_TRASH_DAYS );
  5507 	$delete_timestamp = time() - ( DAY_IN_SECONDS * EMPTY_TRASH_DAYS );
  4790 
  5508 
  4791 	$posts_to_delete = $wpdb->get_results($wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_wp_trash_meta_time' AND meta_value < %d", $delete_timestamp), ARRAY_A);
  5509 	$posts_to_delete = $wpdb->get_results( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_wp_trash_meta_time' AND meta_value < %d", $delete_timestamp ), ARRAY_A );
  4792 
  5510 
  4793 	foreach ( (array) $posts_to_delete as $post ) {
  5511 	foreach ( (array) $posts_to_delete as $post ) {
  4794 		$post_id = (int) $post['post_id'];
  5512 		$post_id = (int) $post['post_id'];
  4795 		if ( !$post_id )
  5513 		if ( ! $post_id ) {
  4796 			continue;
  5514 			continue;
  4797 
  5515 		}
  4798 		$del_post = get_post($post_id);
  5516 
  4799 
  5517 		$del_post = get_post( $post_id );
  4800 		if ( !$del_post || 'trash' != $del_post->post_status ) {
  5518 
  4801 			delete_post_meta($post_id, '_wp_trash_meta_status');
  5519 		if ( ! $del_post || 'trash' != $del_post->post_status ) {
  4802 			delete_post_meta($post_id, '_wp_trash_meta_time');
  5520 			delete_post_meta( $post_id, '_wp_trash_meta_status' );
       
  5521 			delete_post_meta( $post_id, '_wp_trash_meta_time' );
  4803 		} else {
  5522 		} else {
  4804 			wp_delete_post($post_id);
  5523 			wp_delete_post( $post_id );
  4805 		}
  5524 		}
  4806 	}
  5525 	}
  4807 
  5526 
  4808 	$comments_to_delete = $wpdb->get_results($wpdb->prepare("SELECT comment_id FROM $wpdb->commentmeta WHERE meta_key = '_wp_trash_meta_time' AND meta_value < %d", $delete_timestamp), ARRAY_A);
  5527 	$comments_to_delete = $wpdb->get_results( $wpdb->prepare( "SELECT comment_id FROM $wpdb->commentmeta WHERE meta_key = '_wp_trash_meta_time' AND meta_value < %d", $delete_timestamp ), ARRAY_A );
  4809 
  5528 
  4810 	foreach ( (array) $comments_to_delete as $comment ) {
  5529 	foreach ( (array) $comments_to_delete as $comment ) {
  4811 		$comment_id = (int) $comment['comment_id'];
  5530 		$comment_id = (int) $comment['comment_id'];
  4812 		if ( !$comment_id )
  5531 		if ( ! $comment_id ) {
  4813 			continue;
  5532 			continue;
  4814 
  5533 		}
  4815 		$del_comment = get_comment($comment_id);
  5534 
  4816 
  5535 		$del_comment = get_comment( $comment_id );
  4817 		if ( !$del_comment || 'trash' != $del_comment->comment_approved ) {
  5536 
  4818 			delete_comment_meta($comment_id, '_wp_trash_meta_time');
  5537 		if ( ! $del_comment || 'trash' != $del_comment->comment_approved ) {
  4819 			delete_comment_meta($comment_id, '_wp_trash_meta_status');
  5538 			delete_comment_meta( $comment_id, '_wp_trash_meta_time' );
       
  5539 			delete_comment_meta( $comment_id, '_wp_trash_meta_status' );
  4820 		} else {
  5540 		} else {
  4821 			wp_delete_comment( $del_comment );
  5541 			wp_delete_comment( $del_comment );
  4822 		}
  5542 		}
  4823 	}
  5543 	}
  4824 }
  5544 }
  4835  *
  5555  *
  4836  * @link https://codex.wordpress.org/File_Header
  5556  * @link https://codex.wordpress.org/File_Header
  4837  *
  5557  *
  4838  * @since 2.9.0
  5558  * @since 2.9.0
  4839  *
  5559  *
  4840  * @param string $file            Path to the file.
  5560  * @param string $file            Absolute path to the file.
  4841  * @param array  $default_headers List of headers, in the format array('HeaderKey' => 'Header Name').
  5561  * @param array  $default_headers List of headers, in the format `array('HeaderKey' => 'Header Name')`.
  4842  * @param string $context         Optional. If specified adds filter hook {@see 'extra_$context_headers'}.
  5562  * @param string $context         Optional. If specified adds filter hook {@see 'extra_$context_headers'}.
  4843  *                                Default empty.
  5563  *                                Default empty.
  4844  * @return array Array of file headers in `HeaderKey => Header Value` format.
  5564  * @return array Array of file headers in `HeaderKey => Header Value` format.
  4845  */
  5565  */
  4846 function get_file_data( $file, $default_headers, $context = '' ) {
  5566 function get_file_data( $file, $default_headers, $context = '' ) {
  4866 	 *
  5586 	 *
  4867 	 * @param array $extra_context_headers Empty array by default.
  5587 	 * @param array $extra_context_headers Empty array by default.
  4868 	 */
  5588 	 */
  4869 	if ( $context && $extra_headers = apply_filters( "extra_{$context}_headers", array() ) ) {
  5589 	if ( $context && $extra_headers = apply_filters( "extra_{$context}_headers", array() ) ) {
  4870 		$extra_headers = array_combine( $extra_headers, $extra_headers ); // keys equal values
  5590 		$extra_headers = array_combine( $extra_headers, $extra_headers ); // keys equal values
  4871 		$all_headers = array_merge( $extra_headers, (array) $default_headers );
  5591 		$all_headers   = array_merge( $extra_headers, (array) $default_headers );
  4872 	} else {
  5592 	} else {
  4873 		$all_headers = $default_headers;
  5593 		$all_headers = $default_headers;
  4874 	}
  5594 	}
  4875 
  5595 
  4876 	foreach ( $all_headers as $field => $regex ) {
  5596 	foreach ( $all_headers as $field => $regex ) {
  4877 		if ( preg_match( '/^[ \t\/*#@]*' . preg_quote( $regex, '/' ) . ':(.*)$/mi', $file_data, $match ) && $match[1] )
  5597 		if ( preg_match( '/^[ \t\/*#@]*' . preg_quote( $regex, '/' ) . ':(.*)$/mi', $file_data, $match ) && $match[1] ) {
  4878 			$all_headers[ $field ] = _cleanup_header_comment( $match[1] );
  5598 			$all_headers[ $field ] = _cleanup_header_comment( $match[1] );
  4879 		else
  5599 		} else {
  4880 			$all_headers[ $field ] = '';
  5600 			$all_headers[ $field ] = '';
       
  5601 		}
  4881 	}
  5602 	}
  4882 
  5603 
  4883 	return $all_headers;
  5604 	return $all_headers;
  4884 }
  5605 }
  4885 
  5606 
  4988  * @param string $column Database column.
  5709  * @param string $column Database column.
  4989  * @return string SQL clause.
  5710  * @return string SQL clause.
  4990  */
  5711  */
  4991 function _wp_mysql_week( $column ) {
  5712 function _wp_mysql_week( $column ) {
  4992 	switch ( $start_of_week = (int) get_option( 'start_of_week' ) ) {
  5713 	switch ( $start_of_week = (int) get_option( 'start_of_week' ) ) {
  4993 	case 1 :
  5714 		case 1:
  4994 		return "WEEK( $column, 1 )";
  5715 			return "WEEK( $column, 1 )";
  4995 	case 2 :
  5716 		case 2:
  4996 	case 3 :
  5717 		case 3:
  4997 	case 4 :
  5718 		case 4:
  4998 	case 5 :
  5719 		case 5:
  4999 	case 6 :
  5720 		case 6:
  5000 		return "WEEK( DATE_SUB( $column, INTERVAL $start_of_week DAY ), 0 )";
  5721 			return "WEEK( DATE_SUB( $column, INTERVAL $start_of_week DAY ), 0 )";
  5001 	case 0 :
  5722 		case 0:
  5002 	default :
  5723 		default:
  5003 		return "WEEK( $column, 0 )";
  5724 			return "WEEK( $column, 0 )";
  5004 	}
  5725 	}
  5005 }
  5726 }
  5006 
  5727 
  5007 /**
  5728 /**
  5008  * Find hierarchy loops using a callback function that maps object IDs to parent IDs.
  5729  * Find hierarchy loops using a callback function that maps object IDs to parent IDs.
  5018  * @return array IDs of all members of loop.
  5739  * @return array IDs of all members of loop.
  5019  */
  5740  */
  5020 function wp_find_hierarchy_loop( $callback, $start, $start_parent, $callback_args = array() ) {
  5741 function wp_find_hierarchy_loop( $callback, $start, $start_parent, $callback_args = array() ) {
  5021 	$override = is_null( $start_parent ) ? array() : array( $start => $start_parent );
  5742 	$override = is_null( $start_parent ) ? array() : array( $start => $start_parent );
  5022 
  5743 
  5023 	if ( !$arbitrary_loop_member = wp_find_hierarchy_loop_tortoise_hare( $callback, $start, $override, $callback_args ) )
  5744 	if ( ! $arbitrary_loop_member = wp_find_hierarchy_loop_tortoise_hare( $callback, $start, $override, $callback_args ) ) {
  5024 		return array();
  5745 		return array();
       
  5746 	}
  5025 
  5747 
  5026 	return wp_find_hierarchy_loop_tortoise_hare( $callback, $arbitrary_loop_member, $override, $callback_args, true );
  5748 	return wp_find_hierarchy_loop_tortoise_hare( $callback, $arbitrary_loop_member, $override, $callback_args, true );
  5027 }
  5749 }
  5028 
  5750 
  5029 /**
  5751 /**
  5046  * @return mixed Scalar ID of some arbitrary member of the loop, or array of IDs of all members of loop if
  5768  * @return mixed Scalar ID of some arbitrary member of the loop, or array of IDs of all members of loop if
  5047  *               $_return_loop
  5769  *               $_return_loop
  5048  */
  5770  */
  5049 function wp_find_hierarchy_loop_tortoise_hare( $callback, $start, $override = array(), $callback_args = array(), $_return_loop = false ) {
  5771 function wp_find_hierarchy_loop_tortoise_hare( $callback, $start, $override = array(), $callback_args = array(), $_return_loop = false ) {
  5050 	$tortoise = $hare = $evanescent_hare = $start;
  5772 	$tortoise = $hare = $evanescent_hare = $start;
  5051 	$return = array();
  5773 	$return   = array();
  5052 
  5774 
  5053 	// Set evanescent_hare to one past hare
  5775 	// Set evanescent_hare to one past hare
  5054 	// Increment hare two steps
  5776 	// Increment hare two steps
  5055 	while (
  5777 	while (
  5056 		$tortoise
  5778 		$tortoise
  5057 	&&
  5779 	&&
  5058 		( $evanescent_hare = isset( $override[$hare] ) ? $override[$hare] : call_user_func_array( $callback, array_merge( array( $hare ), $callback_args ) ) )
  5780 		( $evanescent_hare = isset( $override[ $hare ] ) ? $override[ $hare ] : call_user_func_array( $callback, array_merge( array( $hare ), $callback_args ) ) )
  5059 	&&
  5781 	&&
  5060 		( $hare = isset( $override[$evanescent_hare] ) ? $override[$evanescent_hare] : call_user_func_array( $callback, array_merge( array( $evanescent_hare ), $callback_args ) ) )
  5782 		( $hare = isset( $override[ $evanescent_hare ] ) ? $override[ $evanescent_hare ] : call_user_func_array( $callback, array_merge( array( $evanescent_hare ), $callback_args ) ) )
  5061 	) {
  5783 	) {
  5062 		if ( $_return_loop )
  5784 		if ( $_return_loop ) {
  5063 			$return[$tortoise] = $return[$evanescent_hare] = $return[$hare] = true;
  5785 			$return[ $tortoise ] = $return[ $evanescent_hare ] = $return[ $hare ] = true;
       
  5786 		}
  5064 
  5787 
  5065 		// tortoise got lapped - must be a loop
  5788 		// tortoise got lapped - must be a loop
  5066 		if ( $tortoise == $evanescent_hare || $tortoise == $hare )
  5789 		if ( $tortoise == $evanescent_hare || $tortoise == $hare ) {
  5067 			return $_return_loop ? $return : $tortoise;
  5790 			return $_return_loop ? $return : $tortoise;
       
  5791 		}
  5068 
  5792 
  5069 		// Increment tortoise by one step
  5793 		// Increment tortoise by one step
  5070 		$tortoise = isset( $override[$tortoise] ) ? $override[$tortoise] : call_user_func_array( $callback, array_merge( array( $tortoise ), $callback_args ) );
  5794 		$tortoise = isset( $override[ $tortoise ] ) ? $override[ $tortoise ] : call_user_func_array( $callback, array_merge( array( $tortoise ), $callback_args ) );
  5071 	}
  5795 	}
  5072 
  5796 
  5073 	return false;
  5797 	return false;
  5074 }
  5798 }
  5075 
  5799 
  5094  * @see wp_kses()
  5818  * @see wp_kses()
  5095  * @see esc_url()
  5819  * @see esc_url()
  5096  *
  5820  *
  5097  * @staticvar array $protocols
  5821  * @staticvar array $protocols
  5098  *
  5822  *
  5099  * @return array Array of allowed protocols. Defaults to an array containing 'http', 'https',
  5823  * @return string[] Array of allowed protocols. Defaults to an array containing 'http', 'https',
  5100  *               'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet',
  5824  *                  'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet',
  5101  *               'mms', 'rtsp', 'svn', 'tel', 'fax', 'xmpp', 'webcal', and 'urn'.
  5825  *                  'mms', 'rtsp', 'svn', 'tel', 'fax', 'xmpp', 'webcal', and 'urn'. This covers
       
  5826  *                  all common link protocols, except for 'javascript' which should not be
       
  5827  *                  allowed for untrusted users.
  5102  */
  5828  */
  5103 function wp_allowed_protocols() {
  5829 function wp_allowed_protocols() {
  5104 	static $protocols = array();
  5830 	static $protocols = array();
  5105 
  5831 
  5106 	if ( empty( $protocols ) ) {
  5832 	if ( empty( $protocols ) ) {
  5127  *
  5853  *
  5128  * @since 3.4.0
  5854  * @since 3.4.0
  5129  *
  5855  *
  5130  * @see https://core.trac.wordpress.org/ticket/19589
  5856  * @see https://core.trac.wordpress.org/ticket/19589
  5131  *
  5857  *
       
  5858  * @staticvar array $truncate_paths Array of paths to truncate.
       
  5859  *
  5132  * @param string $ignore_class Optional. A class to ignore all function calls within - useful
  5860  * @param string $ignore_class Optional. A class to ignore all function calls within - useful
  5133  *                             when you want to just give info about the callee. Default null.
  5861  *                             when you want to just give info about the callee. Default null.
  5134  * @param int    $skip_frames  Optional. A number of stack frames to skip - useful for unwinding
  5862  * @param int    $skip_frames  Optional. A number of stack frames to skip - useful for unwinding
  5135  *                             back to the source of the issue. Default 0.
  5863  *                             back to the source of the issue. Default 0.
  5136  * @param bool   $pretty       Optional. Whether or not you want a comma separated string or raw
  5864  * @param bool   $pretty       Optional. Whether or not you want a comma separated string or raw
  5137  *                             array returned. Default true.
  5865  *                             array returned. Default true.
  5138  * @return string|array Either a string containing a reversed comma separated trace or an array
  5866  * @return string|array Either a string containing a reversed comma separated trace or an array
  5139  *                      of individual calls.
  5867  *                      of individual calls.
  5140  */
  5868  */
  5141 function wp_debug_backtrace_summary( $ignore_class = null, $skip_frames = 0, $pretty = true ) {
  5869 function wp_debug_backtrace_summary( $ignore_class = null, $skip_frames = 0, $pretty = true ) {
  5142 	if ( version_compare( PHP_VERSION, '5.2.5', '>=' ) )
  5870 	static $truncate_paths;
       
  5871 
       
  5872 	if ( version_compare( PHP_VERSION, '5.2.5', '>=' ) ) {
  5143 		$trace = debug_backtrace( false );
  5873 		$trace = debug_backtrace( false );
  5144 	else
  5874 	} else {
  5145 		$trace = debug_backtrace();
  5875 		$trace = debug_backtrace();
  5146 
  5876 	}
  5147 	$caller = array();
  5877 
       
  5878 	$caller      = array();
  5148 	$check_class = ! is_null( $ignore_class );
  5879 	$check_class = ! is_null( $ignore_class );
  5149 	$skip_frames++; // skip this function
  5880 	$skip_frames++; // skip this function
       
  5881 
       
  5882 	if ( ! isset( $truncate_paths ) ) {
       
  5883 		$truncate_paths = array(
       
  5884 			wp_normalize_path( WP_CONTENT_DIR ),
       
  5885 			wp_normalize_path( ABSPATH ),
       
  5886 		);
       
  5887 	}
  5150 
  5888 
  5151 	foreach ( $trace as $call ) {
  5889 	foreach ( $trace as $call ) {
  5152 		if ( $skip_frames > 0 ) {
  5890 		if ( $skip_frames > 0 ) {
  5153 			$skip_frames--;
  5891 			$skip_frames--;
  5154 		} elseif ( isset( $call['class'] ) ) {
  5892 		} elseif ( isset( $call['class'] ) ) {
  5155 			if ( $check_class && $ignore_class == $call['class'] )
  5893 			if ( $check_class && $ignore_class == $call['class'] ) {
  5156 				continue; // Filter out calls
  5894 				continue; // Filter out calls
       
  5895 			}
  5157 
  5896 
  5158 			$caller[] = "{$call['class']}{$call['type']}{$call['function']}";
  5897 			$caller[] = "{$call['class']}{$call['type']}{$call['function']}";
  5159 		} else {
  5898 		} else {
  5160 			if ( in_array( $call['function'], array( 'do_action', 'apply_filters' ) ) ) {
  5899 			if ( in_array( $call['function'], array( 'do_action', 'apply_filters', 'do_action_ref_array', 'apply_filters_ref_array' ) ) ) {
  5161 				$caller[] = "{$call['function']}('{$call['args'][0]}')";
  5900 				$caller[] = "{$call['function']}('{$call['args'][0]}')";
  5162 			} elseif ( in_array( $call['function'], array( 'include', 'include_once', 'require', 'require_once' ) ) ) {
  5901 			} elseif ( in_array( $call['function'], array( 'include', 'include_once', 'require', 'require_once' ) ) ) {
  5163 				$caller[] = $call['function'] . "('" . str_replace( array( WP_CONTENT_DIR, ABSPATH ) , '', $call['args'][0] ) . "')";
  5902 				$filename = isset( $call['args'][0] ) ? $call['args'][0] : '';
       
  5903 				$caller[] = $call['function'] . "('" . str_replace( $truncate_paths, '', wp_normalize_path( $filename ) ) . "')";
  5164 			} else {
  5904 			} else {
  5165 				$caller[] = $call['function'];
  5905 				$caller[] = $call['function'];
  5166 			}
  5906 			}
  5167 		}
  5907 		}
  5168 	}
  5908 	}
  5169 	if ( $pretty )
  5909 	if ( $pretty ) {
  5170 		return join( ', ', array_reverse( $caller ) );
  5910 		return join( ', ', array_reverse( $caller ) );
  5171 	else
  5911 	} else {
  5172 		return $caller;
  5912 		return $caller;
  5173 }
  5913 	}
  5174 
  5914 }
  5175 /**
  5915 
  5176  * Retrieve ids that are not already present in the cache.
  5916 /**
       
  5917  * Retrieve IDs that are not already present in the cache.
  5177  *
  5918  *
  5178  * @since 3.4.0
  5919  * @since 3.4.0
  5179  * @access private
  5920  * @access private
  5180  *
  5921  *
  5181  * @param array  $object_ids ID list.
  5922  * @param int[]  $object_ids Array of IDs.
  5182  * @param string $cache_key  The cache bucket to check against.
  5923  * @param string $cache_key  The cache bucket to check against.
  5183  *
  5924  * @return int[] Array of IDs not present in the cache.
  5184  * @return array List of ids not present in the cache.
       
  5185  */
  5925  */
  5186 function _get_non_cached_ids( $object_ids, $cache_key ) {
  5926 function _get_non_cached_ids( $object_ids, $cache_key ) {
  5187 	$clean = array();
  5927 	$clean = array();
  5188 	foreach ( $object_ids as $id ) {
  5928 	foreach ( $object_ids as $id ) {
  5189 		$id = (int) $id;
  5929 		$id = (int) $id;
  5190 		if ( !wp_cache_get( $id, $cache_key ) ) {
  5930 		if ( ! wp_cache_get( $id, $cache_key ) ) {
  5191 			$clean[] = $id;
  5931 			$clean[] = $id;
  5192 		}
  5932 		}
  5193 	}
  5933 	}
  5194 
  5934 
  5195 	return $clean;
  5935 	return $clean;
  5202  * @access private
  5942  * @access private
  5203  *
  5943  *
  5204  * @return bool Whether the device is able to upload files.
  5944  * @return bool Whether the device is able to upload files.
  5205  */
  5945  */
  5206 function _device_can_upload() {
  5946 function _device_can_upload() {
  5207 	if ( ! wp_is_mobile() )
  5947 	if ( ! wp_is_mobile() ) {
  5208 		return true;
  5948 		return true;
       
  5949 	}
  5209 
  5950 
  5210 	$ua = $_SERVER['HTTP_USER_AGENT'];
  5951 	$ua = $_SERVER['HTTP_USER_AGENT'];
  5211 
  5952 
  5212 	if ( strpos($ua, 'iPhone') !== false
  5953 	if ( strpos( $ua, 'iPhone' ) !== false
  5213 		|| strpos($ua, 'iPad') !== false
  5954 		|| strpos( $ua, 'iPad' ) !== false
  5214 		|| strpos($ua, 'iPod') !== false ) {
  5955 		|| strpos( $ua, 'iPod' ) !== false ) {
  5215 			return preg_match( '#OS ([\d_]+) like Mac OS X#', $ua, $version ) && version_compare( $version[1], '6', '>=' );
  5956 			return preg_match( '#OS ([\d_]+) like Mac OS X#', $ua, $version ) && version_compare( $version[1], '6', '>=' );
  5216 	}
  5957 	}
  5217 
  5958 
  5218 	return true;
  5959 	return true;
  5219 }
  5960 }
  5225  *
  5966  *
  5226  * @param string $path The resource path or URL.
  5967  * @param string $path The resource path or URL.
  5227  * @return bool True if the path is a stream URL.
  5968  * @return bool True if the path is a stream URL.
  5228  */
  5969  */
  5229 function wp_is_stream( $path ) {
  5970 function wp_is_stream( $path ) {
  5230 	if ( false === strpos( $path, '://' ) ) {
  5971 	$scheme_separator = strpos( $path, '://' );
       
  5972 
       
  5973 	if ( false === $scheme_separator ) {
  5231 		// $path isn't a stream
  5974 		// $path isn't a stream
  5232 		return false;
  5975 		return false;
  5233 	}
  5976 	}
  5234 
  5977 
  5235 	$wrappers    = stream_get_wrappers();
  5978 	$stream = substr( $path, 0, $scheme_separator );
  5236 	$wrappers    = array_map( 'preg_quote', $wrappers );
  5979 
  5237 	$wrappers_re = '(' . join( '|', $wrappers ) . ')';
  5980 	return in_array( $stream, stream_get_wrappers(), true );
  5238 
       
  5239 	return preg_match( "!^$wrappers_re://!", $path ) === 1;
       
  5240 }
  5981 }
  5241 
  5982 
  5242 /**
  5983 /**
  5243  * Test if the supplied date is valid for the Gregorian calendar.
  5984  * Test if the supplied date is valid for the Gregorian calendar.
  5244  *
  5985  *
  5245  * @since 3.5.0
  5986  * @since 3.5.0
  5246  *
  5987  *
  5247  * @see checkdate()
  5988  * @link https://secure.php.net/manual/en/function.checkdate.php
  5248  *
  5989  *
  5249  * @param  int    $month       Month number.
  5990  * @param  int    $month       Month number.
  5250  * @param  int    $day         Day number.
  5991  * @param  int    $day         Day number.
  5251  * @param  int    $year        Year number.
  5992  * @param  int    $year        Year number.
  5252  * @param  string $source_date The date to filter.
  5993  * @param  string $source_date The date to filter.
  5274  * for fine-grained control.
  6015  * for fine-grained control.
  5275  *
  6016  *
  5276  * @since 3.6.0
  6017  * @since 3.6.0
  5277  */
  6018  */
  5278 function wp_auth_check_load() {
  6019 function wp_auth_check_load() {
  5279 	if ( ! is_admin() && ! is_user_logged_in() )
  6020 	if ( ! is_admin() && ! is_user_logged_in() ) {
  5280 		return;
  6021 		return;
  5281 
  6022 	}
  5282 	if ( defined( 'IFRAME_REQUEST' ) )
  6023 
       
  6024 	if ( defined( 'IFRAME_REQUEST' ) ) {
  5283 		return;
  6025 		return;
       
  6026 	}
  5284 
  6027 
  5285 	$screen = get_current_screen();
  6028 	$screen = get_current_screen();
  5286 	$hidden = array( 'update', 'update-network', 'update-core', 'update-core-network', 'upgrade', 'upgrade-network', 'network' );
  6029 	$hidden = array( 'update', 'update-network', 'update-core', 'update-core-network', 'upgrade', 'upgrade-network', 'network' );
  5287 	$show = ! in_array( $screen->id, $hidden );
  6030 	$show   = ! in_array( $screen->id, $hidden );
  5288 
  6031 
  5289 	/**
  6032 	/**
  5290 	 * Filters whether to load the authentication check.
  6033 	 * Filters whether to load the authentication check.
  5291 	 *
  6034 	 *
  5292 	 * Passing a falsey value to the filter will effectively short-circuit
  6035 	 * Passing a falsey value to the filter will effectively short-circuit
  5310  * Output the HTML that shows the wp-login dialog when the user is no longer logged in.
  6053  * Output the HTML that shows the wp-login dialog when the user is no longer logged in.
  5311  *
  6054  *
  5312  * @since 3.6.0
  6055  * @since 3.6.0
  5313  */
  6056  */
  5314 function wp_auth_check_html() {
  6057 function wp_auth_check_html() {
  5315 	$login_url = wp_login_url();
  6058 	$login_url      = wp_login_url();
  5316 	$current_domain = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'];
  6059 	$current_domain = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'];
  5317 	$same_domain = ( strpos( $login_url, $current_domain ) === 0 );
  6060 	$same_domain    = ( strpos( $login_url, $current_domain ) === 0 );
  5318 
  6061 
  5319 	/**
  6062 	/**
  5320 	 * Filters whether the authentication check originated at the same domain.
  6063 	 * Filters whether the authentication check originated at the same domain.
  5321 	 *
  6064 	 *
  5322 	 * @since 3.6.0
  6065 	 * @since 3.6.0
  5323 	 *
  6066 	 *
  5324 	 * @param bool $same_domain Whether the authentication check originated at the same domain.
  6067 	 * @param bool $same_domain Whether the authentication check originated at the same domain.
  5325 	 */
  6068 	 */
  5326 	$same_domain = apply_filters( 'wp_auth_check_same_domain', $same_domain );
  6069 	$same_domain = apply_filters( 'wp_auth_check_same_domain', $same_domain );
  5327 	$wrap_class = $same_domain ? 'hidden' : 'hidden fallback';
  6070 	$wrap_class  = $same_domain ? 'hidden' : 'hidden fallback';
  5328 
  6071 
  5329 	?>
  6072 	?>
  5330 	<div id="wp-auth-check-wrap" class="<?php echo $wrap_class; ?>">
  6073 	<div id="wp-auth-check-wrap" class="<?php echo $wrap_class; ?>">
  5331 	<div id="wp-auth-check-bg"></div>
  6074 	<div id="wp-auth-check-bg"></div>
  5332 	<div id="wp-auth-check">
  6075 	<div id="wp-auth-check">
  5333 	<button type="button" class="wp-auth-check-close button-link"><span class="screen-reader-text"><?php _e( 'Close dialog' ); ?></span></button>
  6076 	<button type="button" class="wp-auth-check-close button-link"><span class="screen-reader-text"><?php _e( 'Close dialog' ); ?></span></button>
  5334 	<?php
  6077 	<?php
  5335 
  6078 
  5336 	if ( $same_domain ) {
  6079 	if ( $same_domain ) {
  5337 		$login_src = add_query_arg( array(
  6080 		$login_src = add_query_arg(
  5338 			'interim-login' => '1',
  6081 			array(
  5339 			'wp_lang'       => get_user_locale(),
  6082 				'interim-login' => '1',
  5340 		), $login_url );
  6083 				'wp_lang'       => get_user_locale(),
       
  6084 			),
       
  6085 			$login_url
       
  6086 		);
  5341 		?>
  6087 		?>
  5342 		<div id="wp-auth-check-form" class="loading" data-src="<?php echo esc_url( $login_src ); ?>"></div>
  6088 		<div id="wp-auth-check-form" class="loading" data-src="<?php echo esc_url( $login_src ); ?>"></div>
  5343 		<?php
  6089 		<?php
  5344 	}
  6090 	}
  5345 
  6091 
  5346 	?>
  6092 	?>
  5347 	<div class="wp-auth-fallback">
  6093 	<div class="wp-auth-fallback">
  5348 		<p><b class="wp-auth-fallback-expired" tabindex="0"><?php _e('Session expired'); ?></b></p>
  6094 		<p><b class="wp-auth-fallback-expired" tabindex="0"><?php _e( 'Session expired' ); ?></b></p>
  5349 		<p><a href="<?php echo esc_url( $login_url ); ?>" target="_blank"><?php _e('Please log in again.'); ?></a>
  6095 		<p><a href="<?php echo esc_url( $login_url ); ?>" target="_blank"><?php _e( 'Please log in again.' ); ?></a>
  5350 		<?php _e('The login page will open in a new window. After logging in you can close it and return to this page.'); ?></p>
  6096 		<?php _e( 'The login page will open in a new tab. After logging in you can close it and return to this page.' ); ?></p>
  5351 	</div>
  6097 	</div>
  5352 	</div>
  6098 	</div>
  5353 	</div>
  6099 	</div>
  5354 	<?php
  6100 	<?php
  5355 }
  6101 }
  5387  *
  6133  *
  5388  * @param string $tag An HTML tag name. Example: 'video'.
  6134  * @param string $tag An HTML tag name. Example: 'video'.
  5389  * @return string Tag RegEx.
  6135  * @return string Tag RegEx.
  5390  */
  6136  */
  5391 function get_tag_regex( $tag ) {
  6137 function get_tag_regex( $tag ) {
  5392 	if ( empty( $tag ) )
  6138 	if ( empty( $tag ) ) {
  5393 		return;
  6139 		return;
       
  6140 	}
  5394 	return sprintf( '<%1$s[^<]*(?:>[\s\S]*<\/%1$s>|\s*\/>)', tag_escape( $tag ) );
  6141 	return sprintf( '<%1$s[^<]*(?:>[\s\S]*<\/%1$s>|\s*\/>)', tag_escape( $tag ) );
  5395 }
  6142 }
  5396 
  6143 
  5397 /**
  6144 /**
  5398  * Retrieve a canonical form of the provided charset appropriate for passing to PHP
  6145  * Retrieve a canonical form of the provided charset appropriate for passing to PHP
  5405  *
  6152  *
  5406  * @param string $charset A charset name.
  6153  * @param string $charset A charset name.
  5407  * @return string The canonical form of the charset.
  6154  * @return string The canonical form of the charset.
  5408  */
  6155  */
  5409 function _canonical_charset( $charset ) {
  6156 function _canonical_charset( $charset ) {
  5410 	if ( 'utf-8' === strtolower( $charset ) || 'utf8' === strtolower( $charset) ) {
  6157 	if ( 'utf-8' === strtolower( $charset ) || 'utf8' === strtolower( $charset ) ) {
  5411 
  6158 
  5412 		return 'UTF-8';
  6159 		return 'UTF-8';
  5413 	}
  6160 	}
  5414 
  6161 
  5415 	if ( 'iso-8859-1' === strtolower( $charset ) || 'iso8859-1' === strtolower( $charset ) ) {
  6162 	if ( 'iso-8859-1' === strtolower( $charset ) || 'iso8859-1' === strtolower( $charset ) ) {
  5445  *
  6192  *
  5446  * @param bool $reset Optional. Whether to reset the encoding back to a previously-set encoding.
  6193  * @param bool $reset Optional. Whether to reset the encoding back to a previously-set encoding.
  5447  *                    Default false.
  6194  *                    Default false.
  5448  */
  6195  */
  5449 function mbstring_binary_safe_encoding( $reset = false ) {
  6196 function mbstring_binary_safe_encoding( $reset = false ) {
  5450 	static $encodings = array();
  6197 	static $encodings  = array();
  5451 	static $overloaded = null;
  6198 	static $overloaded = null;
  5452 
  6199 
  5453 	if ( is_null( $overloaded ) )
  6200 	if ( is_null( $overloaded ) ) {
  5454 		$overloaded = function_exists( 'mb_internal_encoding' ) && ( ini_get( 'mbstring.func_overload' ) & 2 );
  6201 		$overloaded = function_exists( 'mb_internal_encoding' ) && ( ini_get( 'mbstring.func_overload' ) & 2 );
  5455 
  6202 	}
  5456 	if ( false === $overloaded )
  6203 
       
  6204 	if ( false === $overloaded ) {
  5457 		return;
  6205 		return;
       
  6206 	}
  5458 
  6207 
  5459 	if ( ! $reset ) {
  6208 	if ( ! $reset ) {
  5460 		$encoding = mb_internal_encoding();
  6209 		$encoding = mb_internal_encoding();
  5461 		array_push( $encodings, $encoding );
  6210 		array_push( $encodings, $encoding );
  5462 		mb_internal_encoding( 'ISO-8859-1' );
  6211 		mb_internal_encoding( 'ISO-8859-1' );
  5530  * @param string $file      Absolute path to the file to delete.
  6279  * @param string $file      Absolute path to the file to delete.
  5531  * @param string $directory Absolute path to a directory.
  6280  * @param string $directory Absolute path to a directory.
  5532  * @return bool True on success, false on failure.
  6281  * @return bool True on success, false on failure.
  5533  */
  6282  */
  5534 function wp_delete_file_from_directory( $file, $directory ) {
  6283 function wp_delete_file_from_directory( $file, $directory ) {
  5535 	$real_file = realpath( wp_normalize_path( $file ) );
  6284 	if ( wp_is_stream( $file ) ) {
  5536 	$real_directory = realpath( wp_normalize_path( $directory ) );
  6285 		$real_file      = $file;
  5537 
  6286 		$real_directory = $directory;
  5538 	if ( false === $real_file || false === $real_directory || strpos( wp_normalize_path( $real_file ), trailingslashit( wp_normalize_path( $real_directory ) ) ) !== 0 ) {
  6287 	} else {
       
  6288 		$real_file      = realpath( wp_normalize_path( $file ) );
       
  6289 		$real_directory = realpath( wp_normalize_path( $directory ) );
       
  6290 	}
       
  6291 
       
  6292 	if ( false !== $real_file ) {
       
  6293 		$real_file = wp_normalize_path( $real_file );
       
  6294 	}
       
  6295 
       
  6296 	if ( false !== $real_directory ) {
       
  6297 		$real_directory = wp_normalize_path( $real_directory );
       
  6298 	}
       
  6299 
       
  6300 	if ( false === $real_file || false === $real_directory || strpos( $real_file, trailingslashit( $real_directory ) ) !== 0 ) {
  5539 		return false;
  6301 		return false;
  5540 	}
  6302 	}
  5541 
  6303 
  5542 	wp_delete_file( $file );
  6304 	wp_delete_file( $file );
  5543 
  6305 
  5579 	</script>
  6341 	</script>
  5580 	<?php
  6342 	<?php
  5581 }
  6343 }
  5582 
  6344 
  5583 /**
  6345 /**
  5584  * Parses and formats a MySQL datetime (Y-m-d H:i:s) for ISO8601/RFC3339.
  6346  * Parses and formats a MySQL datetime (Y-m-d H:i:s) for ISO8601 (Y-m-d\TH:i:s).
  5585  *
  6347  *
  5586  * Explicitly strips timezones, as datetimes are not saved with any timezone
  6348  * Explicitly strips timezones, as datetimes are not saved with any timezone
  5587  * information. Including any information on the offset could be misleading.
  6349  * information. Including any information on the offset could be misleading.
  5588  *
  6350  *
       
  6351  * Despite historical function name, the output does not conform to RFC3339 format,
       
  6352  * which must contain timezone.
       
  6353  *
  5589  * @since 4.4.0
  6354  * @since 4.4.0
  5590  *
  6355  *
  5591  * @param string $date_string Date string to parse and format.
  6356  * @param string $date_string Date string to parse and format.
  5592  * @return string Date formatted for ISO8601/RFC3339.
  6357  * @return string Date formatted for ISO8601 without time zone.
  5593  */
  6358  */
  5594 function mysql_to_rfc3339( $date_string ) {
  6359 function mysql_to_rfc3339( $date_string ) {
  5595 	$formatted = mysql2date( 'c', $date_string, false );
  6360 	return mysql2date( 'Y-m-d\TH:i:s', $date_string, false );
  5596 
       
  5597 	// Strip timezone information
       
  5598 	return preg_replace( '/(?:Z|[+-]\d{2}(?::\d{2})?)$/', '', $formatted );
       
  5599 }
  6361 }
  5600 
  6362 
  5601 /**
  6363 /**
  5602  * Attempts to raise the PHP memory limit for memory intensive processes.
  6364  * Attempts to raise the PHP memory limit for memory intensive processes.
  5603  *
  6365  *
  5711  * @since 4.7.0
  6473  * @since 4.7.0
  5712  *
  6474  *
  5713  * @return string UUID.
  6475  * @return string UUID.
  5714  */
  6476  */
  5715 function wp_generate_uuid4() {
  6477 function wp_generate_uuid4() {
  5716 	return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
  6478 	return sprintf(
  5717 		mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
  6479 		'%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
       
  6480 		mt_rand( 0, 0xffff ),
       
  6481 		mt_rand( 0, 0xffff ),
  5718 		mt_rand( 0, 0xffff ),
  6482 		mt_rand( 0, 0xffff ),
  5719 		mt_rand( 0, 0x0fff ) | 0x4000,
  6483 		mt_rand( 0, 0x0fff ) | 0x4000,
  5720 		mt_rand( 0, 0x3fff ) | 0x8000,
  6484 		mt_rand( 0, 0x3fff ) | 0x8000,
  5721 		mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff )
  6485 		mt_rand( 0, 0xffff ),
       
  6486 		mt_rand( 0, 0xffff ),
       
  6487 		mt_rand( 0, 0xffff )
  5722 	);
  6488 	);
  5723 }
  6489 }
  5724 
  6490 
  5725 /**
  6491 /**
  5726  * Validates that a UUID is valid.
  6492  * Validates that a UUID is valid.
  5727  *
  6493  *
  5728  * @since 4.9.0
  6494  * @since 4.9.0
  5729  *
  6495  *
  5730  * @param mixed $uuid    UUID to check.
  6496  * @param mixed $uuid    UUID to check.
  5731  * @param int   $version Specify which version of UUID to check against. Default is none, to accept any UUID version. Otherwise, only version allowed is `4`.
  6497  * @param int   $version Specify which version of UUID to check against. Default is none,
       
  6498  *                       to accept any UUID version. Otherwise, only version allowed is `4`.
  5732  * @return bool The string is a valid UUID or false on failure.
  6499  * @return bool The string is a valid UUID or false on failure.
  5733  */
  6500  */
  5734 function wp_is_uuid( $uuid, $version = null ) {
  6501 function wp_is_uuid( $uuid, $version = null ) {
  5735 
  6502 
  5736 	if ( ! is_string( $uuid ) ) {
  6503 	if ( ! is_string( $uuid ) ) {
  5746 	} else {
  6513 	} else {
  5747 		$regex = '/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/';
  6514 		$regex = '/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/';
  5748 	}
  6515 	}
  5749 
  6516 
  5750 	return (bool) preg_match( $regex, $uuid );
  6517 	return (bool) preg_match( $regex, $uuid );
       
  6518 }
       
  6519 
       
  6520 /**
       
  6521  * Get unique ID.
       
  6522  *
       
  6523  * This is a PHP implementation of Underscore's uniqueId method. A static variable
       
  6524  * contains an integer that is incremented with each call. This number is returned
       
  6525  * with the optional prefix. As such the returned value is not universally unique,
       
  6526  * but it is unique across the life of the PHP process.
       
  6527  *
       
  6528  * @since 5.0.3
       
  6529  *
       
  6530  * @staticvar int $id_counter
       
  6531  *
       
  6532  * @param string $prefix Prefix for the returned ID.
       
  6533  * @return string Unique ID.
       
  6534  */
       
  6535 function wp_unique_id( $prefix = '' ) {
       
  6536 	static $id_counter = 0;
       
  6537 	return $prefix . (string) ++$id_counter;
  5751 }
  6538 }
  5752 
  6539 
  5753 /**
  6540 /**
  5754  * Get last changed date for the specified cache group.
  6541  * Get last changed date for the specified cache group.
  5755  *
  6542  *
  5801 	if ( ! $send ) {
  6588 	if ( ! $send ) {
  5802 		return;
  6589 		return;
  5803 	}
  6590 	}
  5804 
  6591 
  5805 	/* translators: Do not translate OLD_EMAIL, NEW_EMAIL, SITENAME, SITEURL: those are placeholders. */
  6592 	/* translators: Do not translate OLD_EMAIL, NEW_EMAIL, SITENAME, SITEURL: those are placeholders. */
  5806 	$email_change_text = __( 'Hi,
  6593 	$email_change_text = __(
       
  6594 		'Hi,
  5807 
  6595 
  5808 This notice confirms that the admin email address was changed on ###SITENAME###.
  6596 This notice confirms that the admin email address was changed on ###SITENAME###.
  5809 
  6597 
  5810 The new admin email address is ###NEW_EMAIL###.
  6598 The new admin email address is ###NEW_EMAIL###.
  5811 
  6599 
  5812 This email has been sent to ###OLD_EMAIL###
  6600 This email has been sent to ###OLD_EMAIL###
  5813 
  6601 
  5814 Regards,
  6602 Regards,
  5815 All at ###SITENAME###
  6603 All at ###SITENAME###
  5816 ###SITEURL###' );
  6604 ###SITEURL###'
       
  6605 	);
  5817 
  6606 
  5818 	$email_change_email = array(
  6607 	$email_change_email = array(
  5819 		'to'      => $old_email,
  6608 		'to'      => $old_email,
  5820 		/* translators: Site admin email change notification email subject. %s: Site title */
  6609 		/* translators: Site admin email change notification email subject. %s: Site title */
  5821 		'subject' => __( '[%s] Notice of Admin Email Change' ),
  6610 		'subject' => __( '[%s] Admin Email Changed' ),
  5822 		'message' => $email_change_text,
  6611 		'message' => $email_change_text,
  5823 		'headers' => '',
  6612 		'headers' => '',
  5824 	);
  6613 	);
  5825 	// get site name
  6614 	// get site name
  5826 	$site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
  6615 	$site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
  5848 	 */
  6637 	 */
  5849 	$email_change_email = apply_filters( 'site_admin_email_change_email', $email_change_email, $old_email, $new_email );
  6638 	$email_change_email = apply_filters( 'site_admin_email_change_email', $email_change_email, $old_email, $new_email );
  5850 
  6639 
  5851 	$email_change_email['message'] = str_replace( '###OLD_EMAIL###', $old_email, $email_change_email['message'] );
  6640 	$email_change_email['message'] = str_replace( '###OLD_EMAIL###', $old_email, $email_change_email['message'] );
  5852 	$email_change_email['message'] = str_replace( '###NEW_EMAIL###', $new_email, $email_change_email['message'] );
  6641 	$email_change_email['message'] = str_replace( '###NEW_EMAIL###', $new_email, $email_change_email['message'] );
  5853 	$email_change_email['message'] = str_replace( '###SITENAME###',  $site_name, $email_change_email['message'] );
  6642 	$email_change_email['message'] = str_replace( '###SITENAME###', $site_name, $email_change_email['message'] );
  5854 	$email_change_email['message'] = str_replace( '###SITEURL###',   home_url(), $email_change_email['message'] );
  6643 	$email_change_email['message'] = str_replace( '###SITEURL###', home_url(), $email_change_email['message'] );
  5855 
  6644 
  5856 	wp_mail( $email_change_email['to'], sprintf(
  6645 	wp_mail(
  5857 		$email_change_email['subject'],
  6646 		$email_change_email['to'],
  5858 		$site_name
  6647 		sprintf(
  5859 	), $email_change_email['message'], $email_change_email['headers'] );
  6648 			$email_change_email['subject'],
       
  6649 			$site_name
       
  6650 		),
       
  6651 		$email_change_email['message'],
       
  6652 		$email_change_email['headers']
       
  6653 	);
  5860 }
  6654 }
  5861 
  6655 
  5862 /**
  6656 /**
  5863  * Return an anonymized IPv4 or IPv6 address.
  6657  * Return an anonymized IPv4 or IPv6 address.
  5864  *
  6658  *
  5909 		}
  6703 		}
  5910 
  6704 
  5911 		// Partially anonymize the IP by reducing it to the corresponding network ID.
  6705 		// Partially anonymize the IP by reducing it to the corresponding network ID.
  5912 		if ( function_exists( 'inet_pton' ) && function_exists( 'inet_ntop' ) ) {
  6706 		if ( function_exists( 'inet_pton' ) && function_exists( 'inet_ntop' ) ) {
  5913 			$ip_addr = inet_ntop( inet_pton( $ip_addr ) & inet_pton( $netmask ) );
  6707 			$ip_addr = inet_ntop( inet_pton( $ip_addr ) & inet_pton( $netmask ) );
  5914 			if ( false === $ip_addr) {
  6708 			if ( false === $ip_addr ) {
  5915 				return '::';
  6709 				return '::';
  5916 			}
  6710 			}
  5917 		} elseif ( ! $ipv6_fallback ) {
  6711 		} elseif ( ! $ipv6_fallback ) {
  5918 			return '::';
  6712 			return '::';
  5919 		}
  6713 		}
  6048  * layer of protection.
  6842  * layer of protection.
  6049  *
  6843  *
  6050  * @since 4.9.6
  6844  * @since 4.9.6
  6051  */
  6845  */
  6052 function wp_privacy_delete_old_export_files() {
  6846 function wp_privacy_delete_old_export_files() {
       
  6847 	$exports_dir = wp_privacy_exports_dir();
       
  6848 	if ( ! is_dir( $exports_dir ) ) {
       
  6849 		return;
       
  6850 	}
       
  6851 
  6053 	require_once( ABSPATH . 'wp-admin/includes/file.php' );
  6852 	require_once( ABSPATH . 'wp-admin/includes/file.php' );
  6054 
       
  6055 	$exports_dir  = wp_privacy_exports_dir();
       
  6056 	$export_files = list_files( $exports_dir, 100, array( 'index.html' ) );
  6853 	$export_files = list_files( $exports_dir, 100, array( 'index.html' ) );
  6057 
  6854 
  6058 	/**
  6855 	/**
  6059 	 * Filters the lifetime, in seconds, of a personal data export file.
  6856 	 * Filters the lifetime, in seconds, of a personal data export file.
  6060 	 *
  6857 	 *
  6073 		if ( $expiration < $file_age_in_seconds ) {
  6870 		if ( $expiration < $file_age_in_seconds ) {
  6074 			unlink( $export_file );
  6871 			unlink( $export_file );
  6075 		}
  6872 		}
  6076 	}
  6873 	}
  6077 }
  6874 }
       
  6875 
       
  6876 /**
       
  6877  * Gets the URL to learn more about updating the PHP version the site is running on.
       
  6878  *
       
  6879  * This URL can be overridden by specifying an environment variable `WP_UPDATE_PHP_URL` or by using the
       
  6880  * {@see 'wp_update_php_url'} filter. Providing an empty string is not allowed and will result in the
       
  6881  * default URL being used. Furthermore the page the URL links to should preferably be localized in the
       
  6882  * site language.
       
  6883  *
       
  6884  * @since 5.1.0
       
  6885  *
       
  6886  * @return string URL to learn more about updating PHP.
       
  6887  */
       
  6888 function wp_get_update_php_url() {
       
  6889 	$default_url = wp_get_default_update_php_url();
       
  6890 
       
  6891 	$update_url = $default_url;
       
  6892 	if ( false !== getenv( 'WP_UPDATE_PHP_URL' ) ) {
       
  6893 		$update_url = getenv( 'WP_UPDATE_PHP_URL' );
       
  6894 	}
       
  6895 
       
  6896 	/**
       
  6897 	 * Filters the URL to learn more about updating the PHP version the site is running on.
       
  6898 	 *
       
  6899 	 * Providing an empty string is not allowed and will result in the default URL being used. Furthermore
       
  6900 	 * the page the URL links to should preferably be localized in the site language.
       
  6901 	 *
       
  6902 	 * @since 5.1.0
       
  6903 	 *
       
  6904 	 * @param string $update_url URL to learn more about updating PHP.
       
  6905 	 */
       
  6906 	$update_url = apply_filters( 'wp_update_php_url', $update_url );
       
  6907 
       
  6908 	if ( empty( $update_url ) ) {
       
  6909 		$update_url = $default_url;
       
  6910 	}
       
  6911 
       
  6912 	return $update_url;
       
  6913 }
       
  6914 
       
  6915 /**
       
  6916  * Gets the default URL to learn more about updating the PHP version the site is running on.
       
  6917  *
       
  6918  * Do not use this function to retrieve this URL. Instead, use {@see wp_get_update_php_url()} when relying on the URL.
       
  6919  * This function does not allow modifying the returned URL, and is only used to compare the actually used URL with the
       
  6920  * default one.
       
  6921  *
       
  6922  * @since 5.1.0
       
  6923  * @access private
       
  6924  *
       
  6925  * @return string Default URL to learn more about updating PHP.
       
  6926  */
       
  6927 function wp_get_default_update_php_url() {
       
  6928 	return _x( 'https://wordpress.org/support/update-php/', 'localized PHP upgrade information page' );
       
  6929 }
       
  6930 
       
  6931 /**
       
  6932  * Prints the default annotation for the web host altering the "Update PHP" page URL.
       
  6933  *
       
  6934  * This function is to be used after {@see wp_get_update_php_url()} to display a consistent
       
  6935  * annotation if the web host has altered the default "Update PHP" page URL.
       
  6936  *
       
  6937  * @since 5.1.0
       
  6938  * @since 5.2.0 Added the `$before` and `$after` parameters.
       
  6939  *
       
  6940  * @param string $before Markup to output before the annotation. Default `<p class="description">`.
       
  6941  * @param string $after  Markup to output after the annotation. Default `</p>`.
       
  6942  */
       
  6943 function wp_update_php_annotation( $before = '<p class="description">', $after = '</p>' ) {
       
  6944 	$annotation = wp_get_update_php_annotation();
       
  6945 
       
  6946 	if ( $annotation ) {
       
  6947 		echo $before . $annotation . $after;
       
  6948 	}
       
  6949 }
       
  6950 
       
  6951 /**
       
  6952  * Returns the default annotation for the web hosting altering the "Update PHP" page URL.
       
  6953  *
       
  6954  * This function is to be used after {@see wp_get_update_php_url()} to return a consistent
       
  6955  * annotation if the web host has altered the default "Update PHP" page URL.
       
  6956  *
       
  6957  * @since 5.2.0
       
  6958  *
       
  6959  * @return string $message Update PHP page annotation. An empty string if no custom URLs are provided.
       
  6960  */
       
  6961 function wp_get_update_php_annotation() {
       
  6962 	$update_url  = wp_get_update_php_url();
       
  6963 	$default_url = wp_get_default_update_php_url();
       
  6964 
       
  6965 	if ( $update_url === $default_url ) {
       
  6966 		return '';
       
  6967 	}
       
  6968 
       
  6969 	$annotation = sprintf(
       
  6970 		/* translators: %s: default Update PHP page URL */
       
  6971 		__( '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>.' ),
       
  6972 		esc_url( $default_url )
       
  6973 	);
       
  6974 
       
  6975 	return $annotation;
       
  6976 }
       
  6977 
       
  6978 /**
       
  6979  * Gets the URL for directly updating the PHP version the site is running on.
       
  6980  *
       
  6981  * A URL will only be returned if the `WP_DIRECT_UPDATE_PHP_URL` environment variable is specified or
       
  6982  * by using the {@see 'wp_direct_php_update_url'} filter. This allows hosts to send users directly to
       
  6983  * the page where they can update PHP to a newer version.
       
  6984  *
       
  6985  * @since 5.1.1
       
  6986  *
       
  6987  * @return string URL for directly updating PHP or empty string.
       
  6988  */
       
  6989 function wp_get_direct_php_update_url() {
       
  6990 	$direct_update_url = '';
       
  6991 
       
  6992 	if ( false !== getenv( 'WP_DIRECT_UPDATE_PHP_URL' ) ) {
       
  6993 		$direct_update_url = getenv( 'WP_DIRECT_UPDATE_PHP_URL' );
       
  6994 	}
       
  6995 
       
  6996 	/**
       
  6997 	 * Filters the URL for directly updating the PHP version the site is running on from the host.
       
  6998 	 *
       
  6999 	 * @since 5.1.1
       
  7000 	 *
       
  7001 	 * @param string $direct_update_url URL for directly updating PHP.
       
  7002 	 */
       
  7003 	$direct_update_url = apply_filters( 'wp_direct_php_update_url', $direct_update_url );
       
  7004 
       
  7005 	return $direct_update_url;
       
  7006 }
       
  7007 
       
  7008 /**
       
  7009  * Display a button directly linking to a PHP update process.
       
  7010  *
       
  7011  * This provides hosts with a way for users to be sent directly to their PHP update process.
       
  7012  *
       
  7013  * The button is only displayed if a URL is returned by `wp_get_direct_php_update_url()`.
       
  7014  *
       
  7015  * @since 5.1.1
       
  7016  */
       
  7017 function wp_direct_php_update_button() {
       
  7018 	$direct_update_url = wp_get_direct_php_update_url();
       
  7019 
       
  7020 	if ( empty( $direct_update_url ) ) {
       
  7021 		return;
       
  7022 	}
       
  7023 
       
  7024 	echo '<p class="button-container">';
       
  7025 	printf(
       
  7026 		'<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>',
       
  7027 		esc_url( $direct_update_url ),
       
  7028 		__( 'Update PHP' ),
       
  7029 		/* translators: accessibility text */
       
  7030 		__( '(opens in a new tab)' )
       
  7031 	);
       
  7032 	echo '</p>';
       
  7033 }
       
  7034 
       
  7035 /**
       
  7036  * Get the size of a directory.
       
  7037  *
       
  7038  * A helper function that is used primarily to check whether
       
  7039  * a blog has exceeded its allowed upload space.
       
  7040  *
       
  7041  * @since MU (3.0.0)
       
  7042  * @since 5.2.0 $max_execution_time parameter added.
       
  7043  *
       
  7044  * @param string $directory Full path of a directory.
       
  7045  * @param int    $max_execution_time Maximum time to run before giving up. In seconds.
       
  7046  *                                   The timeout is global and is measured from the moment WordPress started to load.
       
  7047  * @return int|false|null Size in bytes if a valid directory. False if not. Null if timeout.
       
  7048  */
       
  7049 function get_dirsize( $directory, $max_execution_time = null ) {
       
  7050 	$dirsize = get_transient( 'dirsize_cache' );
       
  7051 
       
  7052 	if ( is_array( $dirsize ) && isset( $dirsize[ $directory ]['size'] ) ) {
       
  7053 		return $dirsize[ $directory ]['size'];
       
  7054 	}
       
  7055 
       
  7056 	if ( ! is_array( $dirsize ) ) {
       
  7057 		$dirsize = array();
       
  7058 	}
       
  7059 
       
  7060 	// Exclude individual site directories from the total when checking the main site of a network
       
  7061 	// as they are subdirectories and should not be counted.
       
  7062 	if ( is_multisite() && is_main_site() ) {
       
  7063 		$dirsize[ $directory ]['size'] = recurse_dirsize( $directory, $directory . '/sites', $max_execution_time );
       
  7064 	} else {
       
  7065 		$dirsize[ $directory ]['size'] = recurse_dirsize( $directory, null, $max_execution_time );
       
  7066 	}
       
  7067 
       
  7068 	set_transient( 'dirsize_cache', $dirsize, HOUR_IN_SECONDS );
       
  7069 	return $dirsize[ $directory ]['size'];
       
  7070 }
       
  7071 
       
  7072 /**
       
  7073  * Get the size of a directory recursively.
       
  7074  *
       
  7075  * Used by get_dirsize() to get a directory's size when it contains
       
  7076  * other directories.
       
  7077  *
       
  7078  * @since MU (3.0.0)
       
  7079  * @since 4.3.0 $exclude parameter added.
       
  7080  * @since 5.2.0 $max_execution_time parameter added.
       
  7081  *
       
  7082  * @param string $directory       Full path of a directory.
       
  7083  * @param string|array $exclude   Optional. Full path of a subdirectory to exclude from the total, or array of paths.
       
  7084  *                                Expected without trailing slash(es).
       
  7085  * @param int $max_execution_time Maximum time to run before giving up. In seconds.
       
  7086  *                                The timeout is global and is measured from the moment WordPress started to load.
       
  7087  * @return int|false|null Size in bytes if a valid directory. False if not. Null if timeout.
       
  7088  */
       
  7089 function recurse_dirsize( $directory, $exclude = null, $max_execution_time = null ) {
       
  7090 	$size = 0;
       
  7091 
       
  7092 	$directory = untrailingslashit( $directory );
       
  7093 
       
  7094 	if ( ! file_exists( $directory ) || ! is_dir( $directory ) || ! is_readable( $directory ) ) {
       
  7095 		return false;
       
  7096 	}
       
  7097 
       
  7098 	if (
       
  7099 		( is_string( $exclude ) && $directory === $exclude ) ||
       
  7100 		( is_array( $exclude ) && in_array( $directory, $exclude, true ) )
       
  7101 	) {
       
  7102 		return false;
       
  7103 	}
       
  7104 
       
  7105 	if ( $max_execution_time === null ) {
       
  7106 		// Keep the previous behavior but attempt to prevent fatal errors from timeout if possible.
       
  7107 		if ( function_exists( 'ini_get' ) ) {
       
  7108 			$max_execution_time = ini_get( 'max_execution_time' );
       
  7109 		} else {
       
  7110 			// Disable...
       
  7111 			$max_execution_time = 0;
       
  7112 		}
       
  7113 
       
  7114 		// Leave 1 second "buffer" for other operations if $max_execution_time has reasonable value.
       
  7115 		if ( $max_execution_time > 10 ) {
       
  7116 			$max_execution_time -= 1;
       
  7117 		}
       
  7118 	}
       
  7119 
       
  7120 	if ( $handle = opendir( $directory ) ) {
       
  7121 		while ( ( $file = readdir( $handle ) ) !== false ) {
       
  7122 			$path = $directory . '/' . $file;
       
  7123 			if ( $file != '.' && $file != '..' ) {
       
  7124 				if ( is_file( $path ) ) {
       
  7125 					$size += filesize( $path );
       
  7126 				} elseif ( is_dir( $path ) ) {
       
  7127 					$handlesize = recurse_dirsize( $path, $exclude, $max_execution_time );
       
  7128 					if ( $handlesize > 0 ) {
       
  7129 						$size += $handlesize;
       
  7130 					}
       
  7131 				}
       
  7132 
       
  7133 				if ( $max_execution_time > 0 && microtime( true ) - WP_START_TIMESTAMP > $max_execution_time ) {
       
  7134 					// Time exceeded. Give up instead of risking a fatal timeout.
       
  7135 					$size = null;
       
  7136 					break;
       
  7137 				}
       
  7138 			}
       
  7139 		}
       
  7140 		closedir( $handle );
       
  7141 	}
       
  7142 	return $size;
       
  7143 }
       
  7144 
       
  7145 /**
       
  7146 * Checks compatibility with the current WordPress version.
       
  7147 *
       
  7148 * @since 5.2.0
       
  7149 *
       
  7150 * @param string $required Minimum required WordPress version.
       
  7151 * @return bool True if required version is compatible or empty, false if not.
       
  7152 */
       
  7153 function is_wp_version_compatible( $required ) {
       
  7154 	return empty( $required ) || version_compare( get_bloginfo( 'version' ), $required, '>=' );
       
  7155 }
       
  7156 
       
  7157 /**
       
  7158  * Checks compatibility with the current PHP version.
       
  7159  *
       
  7160  * @since 5.2.0
       
  7161  *
       
  7162  * @param string $required Minimum required PHP version.
       
  7163  * @return bool True if required version is compatible or empty, false if not.
       
  7164  */
       
  7165 function is_php_version_compatible( $required ) {
       
  7166 	return empty( $required ) || version_compare( phpversion(), $required, '>=' );
       
  7167 }