--- a/wp/wp-includes/functions.php Mon Oct 14 18:06:33 2019 +0200
+++ b/wp/wp-includes/functions.php Mon Oct 14 18:28:13 2019 +0200
@@ -24,21 +24,25 @@
* @return string|int|bool Formatted date string or Unix timestamp. False if $date is empty.
*/
function mysql2date( $format, $date, $translate = true ) {
- if ( empty( $date ) )
+ if ( empty( $date ) ) {
return false;
-
- if ( 'G' == $format )
+ }
+
+ if ( 'G' == $format ) {
return strtotime( $date . ' +0000' );
+ }
$i = strtotime( $date );
- if ( 'U' == $format )
+ if ( 'U' == $format ) {
return $i;
-
- if ( $translate )
+ }
+
+ if ( $translate ) {
return date_i18n( $format, $i );
- else
+ } else {
return date( $format, $i );
+ }
}
/**
@@ -65,12 +69,13 @@
case 'timestamp':
return ( $gmt ) ? time() : time() + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS );
default:
- return ( $gmt ) ? date( $type ) : date( $type, time() + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ) );
- }
-}
-
-/**
- * Retrieve the date in localized format, based on timestamp.
+ return ( $gmt ) ? gmdate( $type ) : gmdate( $type, time() + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ) );
+ }
+}
+
+/**
+ * Retrieve the date in localized format, based on a sum of Unix timestamp and
+ * timezone offset in seconds.
*
* If the locale specifies the locale month and weekday, then the locale will
* take over the format for the date. If it isn't, then the date format string
@@ -80,15 +85,17 @@
*
* @global WP_Locale $wp_locale
*
- * @param string $dateformatstring Format to display the date.
- * @param bool|int $unixtimestamp Optional. Unix timestamp. Default false.
- * @param bool $gmt Optional. Whether to use GMT timezone. Default false.
+ * @param string $dateformatstring Format to display the date.
+ * @param int|bool $timestamp_with_offset Optional. A sum of Unix timestamp and timezone offset in seconds.
+ * Default false.
+ * @param bool $gmt Optional. Whether to use GMT timezone. Only applies if timestamp is
+ * not provided. Default false.
*
* @return string The date, translated if locale specifies it.
*/
-function date_i18n( $dateformatstring, $unixtimestamp = false, $gmt = false ) {
+function date_i18n( $dateformatstring, $timestamp_with_offset = false, $gmt = false ) {
global $wp_locale;
- $i = $unixtimestamp;
+ $i = $timestamp_with_offset;
if ( false === $i ) {
$i = current_time( 'timestamp', $gmt );
@@ -100,36 +107,72 @@
*/
$req_format = $dateformatstring;
- if ( ( !empty( $wp_locale->month ) ) && ( !empty( $wp_locale->weekday ) ) ) {
- $datemonth = $wp_locale->get_month( date( 'm', $i ) );
- $datemonth_abbrev = $wp_locale->get_month_abbrev( $datemonth );
- $dateweekday = $wp_locale->get_weekday( date( 'w', $i ) );
- $dateweekday_abbrev = $wp_locale->get_weekday_abbrev( $dateweekday );
- $datemeridiem = $wp_locale->get_meridiem( date( 'a', $i ) );
+ $dateformatstring = preg_replace( '/(?<!\\\\)c/', DATE_W3C, $dateformatstring );
+ $dateformatstring = preg_replace( '/(?<!\\\\)r/', DATE_RFC2822, $dateformatstring );
+
+ if ( ( ! empty( $wp_locale->month ) ) && ( ! empty( $wp_locale->weekday ) ) ) {
+ $datemonth = $wp_locale->get_month( date( 'm', $i ) );
+ $datemonth_abbrev = $wp_locale->get_month_abbrev( $datemonth );
+ $dateweekday = $wp_locale->get_weekday( date( 'w', $i ) );
+ $dateweekday_abbrev = $wp_locale->get_weekday_abbrev( $dateweekday );
+ $datemeridiem = $wp_locale->get_meridiem( date( 'a', $i ) );
$datemeridiem_capital = $wp_locale->get_meridiem( date( 'A', $i ) );
- $dateformatstring = ' '.$dateformatstring;
- $dateformatstring = preg_replace( "/([^\\\])D/", "\\1" . backslashit( $dateweekday_abbrev ), $dateformatstring );
- $dateformatstring = preg_replace( "/([^\\\])F/", "\\1" . backslashit( $datemonth ), $dateformatstring );
- $dateformatstring = preg_replace( "/([^\\\])l/", "\\1" . backslashit( $dateweekday ), $dateformatstring );
- $dateformatstring = preg_replace( "/([^\\\])M/", "\\1" . backslashit( $datemonth_abbrev ), $dateformatstring );
- $dateformatstring = preg_replace( "/([^\\\])a/", "\\1" . backslashit( $datemeridiem ), $dateformatstring );
- $dateformatstring = preg_replace( "/([^\\\])A/", "\\1" . backslashit( $datemeridiem_capital ), $dateformatstring );
-
- $dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) -1 );
- }
- $timezone_formats = array( 'P', 'I', 'O', 'T', 'Z', 'e' );
+ $dateformatstring = ' ' . $dateformatstring;
+ $dateformatstring = preg_replace( '/([^\\\])D/', "\\1" . backslashit( $dateweekday_abbrev ), $dateformatstring );
+ $dateformatstring = preg_replace( '/([^\\\])F/', "\\1" . backslashit( $datemonth ), $dateformatstring );
+ $dateformatstring = preg_replace( '/([^\\\])l/', "\\1" . backslashit( $dateweekday ), $dateformatstring );
+ $dateformatstring = preg_replace( '/([^\\\])M/', "\\1" . backslashit( $datemonth_abbrev ), $dateformatstring );
+ $dateformatstring = preg_replace( '/([^\\\])a/', "\\1" . backslashit( $datemeridiem ), $dateformatstring );
+ $dateformatstring = preg_replace( '/([^\\\])A/', "\\1" . backslashit( $datemeridiem_capital ), $dateformatstring );
+
+ $dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) - 1 );
+ }
+ $timezone_formats = array( 'P', 'I', 'O', 'T', 'Z', 'e' );
$timezone_formats_re = implode( '|', $timezone_formats );
if ( preg_match( "/$timezone_formats_re/", $dateformatstring ) ) {
$timezone_string = get_option( 'timezone_string' );
+ if ( false === $timestamp_with_offset && $gmt ) {
+ $timezone_string = 'UTC';
+ }
if ( $timezone_string ) {
$timezone_object = timezone_open( $timezone_string );
- $date_object = date_create( null, $timezone_object );
+ $date_object = date_create( null, $timezone_object );
foreach ( $timezone_formats as $timezone_format ) {
if ( false !== strpos( $dateformatstring, $timezone_format ) ) {
- $formatted = date_format( $date_object, $timezone_format );
- $dateformatstring = ' '.$dateformatstring;
+ $formatted = date_format( $date_object, $timezone_format );
+ $dateformatstring = ' ' . $dateformatstring;
$dateformatstring = preg_replace( "/([^\\\])$timezone_format/", "\\1" . backslashit( $formatted ), $dateformatstring );
- $dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) -1 );
+ $dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) - 1 );
+ }
+ }
+ } else {
+ $offset = get_option( 'gmt_offset' );
+ foreach ( $timezone_formats as $timezone_format ) {
+ if ( 'I' === $timezone_format ) {
+ continue;
+ }
+
+ if ( false !== strpos( $dateformatstring, $timezone_format ) ) {
+ if ( 'Z' === $timezone_format ) {
+ $formatted = (string) ( $offset * HOUR_IN_SECONDS );
+ } else {
+ $prefix = '';
+ $hours = (int) $offset;
+ $separator = '';
+ $minutes = abs( ( $offset - $hours ) * 60 );
+
+ if ( 'T' === $timezone_format ) {
+ $prefix = 'GMT';
+ } elseif ( 'e' === $timezone_format || 'P' === $timezone_format ) {
+ $separator = ':';
+ }
+
+ $formatted = sprintf( '%s%+03d%s%02d', $prefix, $hours, $separator, $minutes );
+ }
+
+ $dateformatstring = ' ' . $dateformatstring;
+ $dateformatstring = preg_replace( "/([^\\\])$timezone_format/", "\\1" . backslashit( $formatted ), $dateformatstring );
+ $dateformatstring = substr( $dateformatstring, 1 );
}
}
}
@@ -143,8 +186,9 @@
*
* @param string $j Formatted date string.
* @param string $req_format Format to display the date.
- * @param int $i Unix timestamp.
- * @param bool $gmt Whether to convert to GMT for time. Default false.
+ * @param int $i A sum of Unix timestamp and timezone offset in seconds.
+ * @param bool $gmt Whether to use GMT timezone. Only applies if timestamp was
+ * not provided. Default false.
*/
$j = apply_filters( 'date_i18n', $j, $req_format, $i, $gmt );
return $j;
@@ -227,7 +271,7 @@
* Filters the number formatted based on the locale.
*
* @since 2.8.0
- * @since 4.9.0 The `$number` and `$decimals` arguments were added.
+ * @since 4.9.0 The `$number` and `$decimals` parameters were added.
*
* @param string $formatted Converted number in string format.
* @param float $number The number to convert based on locale.
@@ -279,6 +323,76 @@
}
/**
+ * Convert a duration to human readable format.
+ *
+ * @since 5.1.0
+ *
+ * @param string $duration Duration will be in string format (HH:ii:ss) OR (ii:ss),
+ * with a possible prepended negative sign (-).
+ * @return string|false A human readable duration string, false on failure.
+ */
+function human_readable_duration( $duration = '' ) {
+ if ( ( empty( $duration ) || ! is_string( $duration ) ) ) {
+ return false;
+ }
+
+ $duration = trim( $duration );
+
+ // Remove prepended negative sign.
+ if ( '-' === substr( $duration, 0, 1 ) ) {
+ $duration = substr( $duration, 1 );
+ }
+
+ // Extract duration parts.
+ $duration_parts = array_reverse( explode( ':', $duration ) );
+ $duration_count = count( $duration_parts );
+
+ $hour = null;
+ $minute = null;
+ $second = null;
+
+ if ( 3 === $duration_count ) {
+ // Validate HH:ii:ss duration format.
+ if ( ! ( (bool) preg_match( '/^([0-9]+):([0-5]?[0-9]):([0-5]?[0-9])$/', $duration ) ) ) {
+ return false;
+ }
+ // Three parts: hours, minutes & seconds.
+ list( $second, $minute, $hour ) = $duration_parts;
+ } elseif ( 2 === $duration_count ) {
+ // Validate ii:ss duration format.
+ if ( ! ( (bool) preg_match( '/^([0-5]?[0-9]):([0-5]?[0-9])$/', $duration ) ) ) {
+ return false;
+ }
+ // Two parts: minutes & seconds.
+ list( $second, $minute ) = $duration_parts;
+ } else {
+ return false;
+ }
+
+ $human_readable_duration = array();
+
+ // Add the hour part to the string.
+ if ( is_numeric( $hour ) ) {
+ /* translators: Time duration in hour or hours. */
+ $human_readable_duration[] = sprintf( _n( '%s hour', '%s hours', $hour ), (int) $hour );
+ }
+
+ // Add the minute part to the string.
+ if ( is_numeric( $minute ) ) {
+ /* translators: Time duration in minute or minutes. */
+ $human_readable_duration[] = sprintf( _n( '%s minute', '%s minutes', $minute ), (int) $minute );
+ }
+
+ // Add the second part to the string.
+ if ( is_numeric( $second ) ) {
+ /* translators: Time duration in second or seconds. */
+ $human_readable_duration[] = sprintf( _n( '%s second', '%s seconds', $second ), (int) $second );
+ }
+
+ return implode( ', ', $human_readable_duration );
+}
+
+/**
* Get the week start and end from the datetime or date string from MySQL.
*
* @since 0.71
@@ -303,11 +417,13 @@
// The day of the week from the timestamp.
$weekday = date( 'w', $day );
- if ( !is_numeric($start_of_week) )
+ if ( ! is_numeric( $start_of_week ) ) {
$start_of_week = get_option( 'start_of_week' );
-
- if ( $weekday < $start_of_week )
+ }
+
+ if ( $weekday < $start_of_week ) {
$weekday += 7;
+ }
// The most recent week start day on or before $day.
$start = $day - DAY_IN_SECONDS * ( $weekday - $start_of_week );
@@ -326,8 +442,9 @@
* @return mixed Unserialized data can be any type.
*/
function maybe_unserialize( $original ) {
- if ( is_serialized( $original ) ) // don't attempt to unserialize data that wasn't serialized going in
+ if ( is_serialized( $original ) ) { // don't attempt to unserialize data that wasn't serialized going in
return @unserialize( $original );
+ }
return $original;
}
@@ -349,7 +466,7 @@
return false;
}
$data = trim( $data );
- if ( 'N;' == $data ) {
+ if ( 'N;' == $data ) {
return true;
}
if ( strlen( $data ) < 4 ) {
@@ -367,17 +484,20 @@
$semicolon = strpos( $data, ';' );
$brace = strpos( $data, '}' );
// Either ; or } must exist.
- if ( false === $semicolon && false === $brace )
+ if ( false === $semicolon && false === $brace ) {
return false;
+ }
// But neither must be in the first X characters.
- if ( false !== $semicolon && $semicolon < 3 )
+ if ( false !== $semicolon && $semicolon < 3 ) {
return false;
- if ( false !== $brace && $brace < 4 )
+ }
+ if ( false !== $brace && $brace < 4 ) {
return false;
+ }
}
$token = $data[0];
switch ( $token ) {
- case 's' :
+ case 's':
if ( $strict ) {
if ( '"' !== substr( $data, -2, 1 ) ) {
return false;
@@ -386,12 +506,12 @@
return false;
}
// or else fall through
- case 'a' :
- case 'O' :
+ case 'a':
+ case 'O':
return (bool) preg_match( "/^{$token}:[0-9]+:/s", $data );
- case 'b' :
- case 'i' :
- case 'd' :
+ case 'b':
+ case 'i':
+ case 'd':
$end = $strict ? '$' : '';
return (bool) preg_match( "/^{$token}:[0-9.E-]+;$end/", $data );
}
@@ -436,14 +556,16 @@
* @return mixed A scalar data
*/
function maybe_serialize( $data ) {
- if ( is_array( $data ) || is_object( $data ) )
+ if ( is_array( $data ) || is_object( $data ) ) {
return serialize( $data );
+ }
// Double serialization is required for backward compatibility.
// See https://core.trac.wordpress.org/ticket/12930
// Also the world will end. See WP 3.6.1.
- if ( is_serialized( $data, false ) )
+ if ( is_serialized( $data, false ) ) {
return serialize( $data );
+ }
return $data;
}
@@ -522,16 +644,16 @@
function wp_extract_urls( $content ) {
preg_match_all(
"#([\"']?)("
- . "(?:([\w-]+:)?//?)"
- . "[^\s()<>]+"
- . "[.]"
- . "(?:"
- . "\([\w\d]+\)|"
- . "(?:"
+ . '(?:([\w-]+:)?//?)'
+ . '[^\s()<>]+'
+ . '[.]'
+ . '(?:'
+ . '\([\w\d]+\)|'
+ . '(?:'
. "[^`!()\[\]{};:'\".,<>«»“”‘’\s]|"
- . "(?:[:]\d+)?/?"
- . ")+"
- . ")"
+ . '(?:[:]\d+)?/?'
+ . ')+'
+ . ')'
. ")\\1#",
$content,
$post_links
@@ -570,21 +692,24 @@
foreach ( $pung as $link_test ) {
if ( ! in_array( $link_test, $post_links_temp ) ) { // link no longer in post
- $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 ) . '%') );
- foreach ( $mids as $mid )
+ $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 ) . '%' ) );
+ foreach ( $mids as $mid ) {
delete_metadata_by_mid( 'post', $mid );
+ }
}
}
foreach ( (array) $post_links_temp as $link_test ) {
- if ( !in_array( $link_test, $pung ) ) { // If we haven't pung it already
+ if ( ! in_array( $link_test, $pung ) ) { // If we haven't pung it already
$test = @parse_url( $link_test );
- if ( false === $test )
+ if ( false === $test ) {
continue;
- if ( isset( $test['query'] ) )
+ }
+ if ( isset( $test['query'] ) ) {
$post_links[] = $link_test;
- elseif ( isset($test['path']) && ( $test['path'] != '/' ) && ($test['path'] != '' ) )
+ } elseif ( isset( $test['path'] ) && ( $test['path'] != '/' ) && ( $test['path'] != '' ) ) {
$post_links[] = $link_test;
+ }
}
}
@@ -602,11 +727,11 @@
$post_links = apply_filters( 'enclosure_links', $post_links, $post_ID );
foreach ( (array) $post_links as $url ) {
- 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 ) . '%' ) ) ) {
-
- if ( $headers = wp_get_http_headers( $url) ) {
- $len = isset( $headers['content-length'] ) ? (int) $headers['content-length'] : 0;
- $type = isset( $headers['content-type'] ) ? $headers['content-type'] : '';
+ 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 ) . '%' ) ) ) {
+
+ if ( $headers = wp_get_http_headers( $url ) ) {
+ $len = isset( $headers['content-length'] ) ? (int) $headers['content-length'] : 0;
+ $type = isset( $headers['content-type'] ) ? $headers['content-type'] : '';
$allowed_types = array( 'video', 'audio' );
// Check to see if we can figure out the mime type from
@@ -614,7 +739,7 @@
$url_parts = @parse_url( $url );
if ( false !== $url_parts ) {
$extension = pathinfo( $url_parts['path'], PATHINFO_EXTENSION );
- if ( !empty( $extension ) ) {
+ if ( ! empty( $extension ) ) {
foreach ( wp_get_mime_types() as $exts => $mime ) {
if ( preg_match( '!^(' . $exts . ')$!i', $extension ) ) {
$type = $mime;
@@ -624,7 +749,7 @@
}
}
- if ( in_array( substr( $type, 0, strpos( $type, "/" ) ), $allowed_types ) ) {
+ if ( in_array( substr( $type, 0, strpos( $type, '/' ) ), $allowed_types ) ) {
add_post_meta( $post_ID, 'enclosure', "$url\n$len\n$mime\n" );
}
}
@@ -642,20 +767,26 @@
* @return bool|string False on failure, headers on success.
*/
function wp_get_http_headers( $url, $deprecated = false ) {
- if ( !empty( $deprecated ) )
+ if ( ! empty( $deprecated ) ) {
_deprecated_argument( __FUNCTION__, '2.7.0' );
+ }
$response = wp_safe_remote_head( $url );
- if ( is_wp_error( $response ) )
+ if ( is_wp_error( $response ) ) {
return false;
+ }
return wp_remote_retrieve_headers( $response );
}
/**
- * Whether the publish date of the current post in the loop is different from the
- * publish date of the previous post in the loop.
+ * Determines whether the publish date of the current post in the loop is different
+ * from the publish date of the previous post in the loop.
+ *
+ * For more information on this and similar theme functions, check out
+ * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
+ * Conditional Tags} article in the Theme Developer Handbook.
*
* @since 0.71
*
@@ -666,10 +797,11 @@
*/
function is_new_day() {
global $currentday, $previousday;
- if ( $currentday != $previousday )
+ if ( $currentday != $previousday ) {
return 1;
- else
+ } else {
return 0;
+ }
}
/**
@@ -682,7 +814,7 @@
*
* @see _http_build_query() Used to build the query
* @link https://secure.php.net/manual/en/function.http-build-query.php for more on what
- * http_build_query() does.
+ * http_build_query() does.
*
* @param array $data URL-encode key/value pairs.
* @return string URL-encoded string.
@@ -713,29 +845,35 @@
$ret = array();
foreach ( (array) $data as $k => $v ) {
- if ( $urlencode)
- $k = urlencode($k);
- if ( is_int($k) && $prefix != null )
- $k = $prefix.$k;
- if ( !empty($key) )
+ if ( $urlencode ) {
+ $k = urlencode( $k );
+ }
+ if ( is_int( $k ) && $prefix != null ) {
+ $k = $prefix . $k;
+ }
+ if ( ! empty( $key ) ) {
$k = $key . '%5B' . $k . '%5D';
- if ( $v === null )
+ }
+ if ( $v === null ) {
continue;
- elseif ( $v === false )
+ } elseif ( $v === false ) {
$v = '0';
-
- if ( is_array($v) || is_object($v) )
- array_push($ret,_http_build_query($v, '', $sep, $k, $urlencode));
- elseif ( $urlencode )
- array_push($ret, $k.'='.urlencode($v));
- else
- array_push($ret, $k.'='.$v);
- }
-
- if ( null === $sep )
- $sep = ini_get('arg_separator.output');
-
- return implode($sep, $ret);
+ }
+
+ if ( is_array( $v ) || is_object( $v ) ) {
+ array_push( $ret, _http_build_query( $v, '', $sep, $k, $urlencode ) );
+ } elseif ( $urlencode ) {
+ array_push( $ret, $k . '=' . urlencode( $v ) );
+ } else {
+ array_push( $ret, $k . '=' . $v );
+ }
+ }
+
+ if ( null === $sep ) {
+ $sep = ini_get( 'arg_separator.output' );
+ }
+
+ return implode( $sep, $ret );
}
/**
@@ -776,40 +914,43 @@
function add_query_arg() {
$args = func_get_args();
if ( is_array( $args[0] ) ) {
- if ( count( $args ) < 2 || false === $args[1] )
+ if ( count( $args ) < 2 || false === $args[1] ) {
$uri = $_SERVER['REQUEST_URI'];
- else
+ } else {
$uri = $args[1];
+ }
} else {
- if ( count( $args ) < 3 || false === $args[2] )
+ if ( count( $args ) < 3 || false === $args[2] ) {
$uri = $_SERVER['REQUEST_URI'];
- else
+ } else {
$uri = $args[2];
- }
-
- if ( $frag = strstr( $uri, '#' ) )
+ }
+ }
+
+ if ( $frag = strstr( $uri, '#' ) ) {
$uri = substr( $uri, 0, -strlen( $frag ) );
- else
+ } else {
$frag = '';
+ }
if ( 0 === stripos( $uri, 'http://' ) ) {
$protocol = 'http://';
- $uri = substr( $uri, 7 );
+ $uri = substr( $uri, 7 );
} elseif ( 0 === stripos( $uri, 'https://' ) ) {
$protocol = 'https://';
- $uri = substr( $uri, 8 );
+ $uri = substr( $uri, 8 );
} else {
$protocol = '';
}
if ( strpos( $uri, '?' ) !== false ) {
list( $base, $query ) = explode( '?', $uri, 2 );
- $base .= '?';
+ $base .= '?';
} elseif ( $protocol || strpos( $uri, '=' ) === false ) {
- $base = $uri . '?';
+ $base = $uri . '?';
$query = '';
} else {
- $base = '';
+ $base = '';
$query = $uri;
}
@@ -824,8 +965,9 @@
}
foreach ( $qs as $k => $v ) {
- if ( $v === false )
- unset( $qs[$k] );
+ if ( $v === false ) {
+ unset( $qs[ $k ] );
+ }
}
$ret = build_query( $qs );
@@ -847,8 +989,9 @@
*/
function remove_query_arg( $key, $query = false ) {
if ( is_array( $key ) ) { // removing multiple keys
- foreach ( $key as $k )
+ foreach ( $key as $k ) {
$query = add_query_arg( $k, false, $query );
+ }
return $query;
}
return add_query_arg( $key, false, $query );
@@ -909,9 +1052,9 @@
function add_magic_quotes( $array ) {
foreach ( (array) $array as $k => $v ) {
if ( is_array( $v ) ) {
- $array[$k] = add_magic_quotes( $v );
+ $array[ $k ] = add_magic_quotes( $v );
} else {
- $array[$k] = addslashes( $v );
+ $array[ $k ] = addslashes( $v );
}
}
return $array;
@@ -930,16 +1073,18 @@
function wp_remote_fopen( $uri ) {
$parsed_url = @parse_url( $uri );
- if ( !$parsed_url || !is_array( $parsed_url ) )
+ if ( ! $parsed_url || ! is_array( $parsed_url ) ) {
return false;
-
- $options = array();
+ }
+
+ $options = array();
$options['timeout'] = 10;
$response = wp_safe_remote_get( $uri, $options );
- if ( is_wp_error( $response ) )
+ if ( is_wp_error( $response ) ) {
return false;
+ }
return wp_remote_retrieve_body( $response );
}
@@ -959,14 +1104,18 @@
global $wp, $wp_query, $wp_the_query;
$wp->main( $query_vars );
- if ( !isset($wp_the_query) )
+ if ( ! isset( $wp_the_query ) ) {
$wp_the_query = $wp_query;
+ }
}
/**
* Retrieve the description for the HTTP status.
*
* @since 2.3.0
+ * @since 3.9.0 Added status codes 418, 428, 429, 431, and 511.
+ * @since 4.5.0 Added status codes 308, 421, and 451.
+ * @since 5.1.0 Added status code 103.
*
* @global array $wp_header_to_desc
*
@@ -978,11 +1127,12 @@
$code = absint( $code );
- if ( !isset( $wp_header_to_desc ) ) {
+ if ( ! isset( $wp_header_to_desc ) ) {
$wp_header_to_desc = array(
100 => 'Continue',
101 => 'Switching Protocols',
102 => 'Processing',
+ 103 => 'Early Hints',
200 => 'OK',
201 => 'Created',
@@ -1046,10 +1196,11 @@
);
}
- if ( isset( $wp_header_to_desc[$code] ) )
- return $wp_header_to_desc[$code];
- else
+ if ( isset( $wp_header_to_desc[ $code ] ) ) {
+ return $wp_header_to_desc[ $code ];
+ } else {
return '';
+ }
}
/**
@@ -1072,9 +1223,9 @@
return;
}
- $protocol = wp_get_server_protocol();
+ $protocol = wp_get_server_protocol();
$status_header = "$protocol $code $description";
- if ( function_exists( 'apply_filters' ) )
+ if ( function_exists( 'apply_filters' ) ) {
/**
* Filters an HTTP status header.
@@ -1087,6 +1238,7 @@
* @param string $protocol Server protocol.
*/
$status_header = apply_filters( 'status_header', $status_header, $code, $description, $protocol );
+ }
@header( $status_header, true, $code );
}
@@ -1103,11 +1255,11 @@
*/
function wp_get_nocache_headers() {
$headers = array(
- 'Expires' => 'Wed, 11 Jan 1984 05:00:00 GMT',
+ 'Expires' => 'Wed, 11 Jan 1984 05:00:00 GMT',
'Cache-Control' => 'no-cache, must-revalidate, max-age=0',
);
- if ( function_exists('apply_filters') ) {
+ if ( function_exists( 'apply_filters' ) ) {
/**
* Filters the cache-controlling headers.
*
@@ -1158,8 +1310,9 @@
}
}
- foreach ( $headers as $name => $field_value )
- @header("{$name}: {$field_value}");
+ foreach ( $headers as $name => $field_value ) {
+ @header( "{$name}: {$field_value}" );
+ }
}
/**
@@ -1170,9 +1323,9 @@
function cache_javascript_headers() {
$expiresOffset = 10 * DAY_IN_SECONDS;
- header( "Content-Type: text/javascript; charset=" . get_bloginfo( 'charset' ) );
- header( "Vary: Accept-Encoding" ); // Handle proxies
- header( "Expires: " . gmdate( "D, d M Y H:i:s", time() + $expiresOffset ) . " GMT" );
+ header( 'Content-Type: text/javascript; charset=' . get_bloginfo( 'charset' ) );
+ header( 'Vary: Accept-Encoding' ); // Handle proxies
+ header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', time() + $expiresOffset ) . ' GMT' );
}
/**
@@ -1223,8 +1376,9 @@
// Remove the pad, if present.
$feed = preg_replace( '/^_+/', '', $feed );
- if ( $feed == '' || $feed == 'feed' )
+ if ( $feed == '' || $feed == 'feed' ) {
$feed = get_default_feed();
+ }
if ( ! has_action( "do_feed_{$feed}" ) ) {
wp_die( __( 'ERROR: This is not a valid feed template.' ), '', array( 'response' => 404 ) );
@@ -1277,10 +1431,11 @@
* @param bool $for_comments True for the comment feed, false for normal feed.
*/
function do_feed_rss2( $for_comments ) {
- if ( $for_comments )
+ if ( $for_comments ) {
load_template( ABSPATH . WPINC . '/feed-rss2-comments.php' );
- else
+ } else {
load_template( ABSPATH . WPINC . '/feed-rss2.php' );
+ }
}
/**
@@ -1293,10 +1448,11 @@
* @param bool $for_comments True for the comment feed, false for normal feed.
*/
function do_feed_atom( $for_comments ) {
- if ($for_comments)
- load_template( ABSPATH . WPINC . '/feed-atom-comments.php');
- else
+ if ( $for_comments ) {
+ load_template( ABSPATH . WPINC . '/feed-atom-comments.php' );
+ } else {
load_template( ABSPATH . WPINC . '/feed-atom.php' );
+ }
}
/**
@@ -1323,9 +1479,9 @@
$output .= "Disallow: /\n";
} else {
$site_url = parse_url( site_url() );
- $path = ( !empty( $site_url['path'] ) ) ? $site_url['path'] : '';
- $output .= "Disallow: $path/wp-admin/\n";
- $output .= "Allow: $path/wp-admin/admin-ajax.php\n";
+ $path = ( ! empty( $site_url['path'] ) ) ? $site_url['path'] : '';
+ $output .= "Disallow: $path/wp-admin/\n";
+ $output .= "Allow: $path/wp-admin/admin-ajax.php\n";
}
/**
@@ -1340,7 +1496,7 @@
}
/**
- * Test whether WordPress is already installed.
+ * Determines whether WordPress is already installed.
*
* The cache will be checked first. If you have a cache plugin, which saves
* the cache values, then this will work. If you use the default WordPress
@@ -1348,6 +1504,10 @@
*
* Checks for the 'siteurl' option for whether WordPress is installed.
*
+ * For more information on this and similar theme functions, check out
+ * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
+ * Conditional Tags} article in the Theme Developer Handbook.
+ *
* @since 2.1.0
*
* @global wpdb $wpdb WordPress database abstraction object.
@@ -1361,29 +1521,33 @@
* Check cache first. If options table goes away and we have true
* cached, oh well.
*/
- if ( wp_cache_get( 'is_blog_installed' ) )
+ if ( wp_cache_get( 'is_blog_installed' ) ) {
return true;
+ }
$suppress = $wpdb->suppress_errors();
if ( ! wp_installing() ) {
$alloptions = wp_load_alloptions();
}
// If siteurl is not set to autoload, check it specifically
- if ( !isset( $alloptions['siteurl'] ) )
+ if ( ! isset( $alloptions['siteurl'] ) ) {
$installed = $wpdb->get_var( "SELECT option_value FROM $wpdb->options WHERE option_name = 'siteurl'" );
- else
+ } else {
$installed = $alloptions['siteurl'];
+ }
$wpdb->suppress_errors( $suppress );
- $installed = !empty( $installed );
+ $installed = ! empty( $installed );
wp_cache_set( 'is_blog_installed', $installed );
- if ( $installed )
+ if ( $installed ) {
return true;
+ }
// If visiting repair.php, return true and let it take over.
- if ( defined( 'WP_REPAIRING' ) )
+ if ( defined( 'WP_REPAIRING' ) ) {
return true;
+ }
$suppress = $wpdb->suppress_errors();
@@ -1395,13 +1559,16 @@
$wp_tables = $wpdb->tables();
foreach ( $wp_tables as $table ) {
// The existence of custom user tables shouldn't suggest an insane state or prevent a clean installation.
- if ( defined( 'CUSTOM_USER_TABLE' ) && CUSTOM_USER_TABLE == $table )
+ if ( defined( 'CUSTOM_USER_TABLE' ) && CUSTOM_USER_TABLE == $table ) {
continue;
- if ( defined( 'CUSTOM_USER_META_TABLE' ) && CUSTOM_USER_META_TABLE == $table )
+ }
+ if ( defined( 'CUSTOM_USER_META_TABLE' ) && CUSTOM_USER_META_TABLE == $table ) {
continue;
-
- if ( ! $wpdb->get_results( "DESCRIBE $table;" ) )
+ }
+
+ if ( ! $wpdb->get_results( "DESCRIBE $table;" ) ) {
continue;
+ }
// One or more tables exist. We are insane.
@@ -1465,15 +1632,17 @@
* @param bool $echo Optional. Whether to display or return hidden form field. Default true.
* @return string Nonce field HTML markup.
*/
-function wp_nonce_field( $action = -1, $name = "_wpnonce", $referer = true , $echo = true ) {
- $name = esc_attr( $name );
+function wp_nonce_field( $action = -1, $name = '_wpnonce', $referer = true, $echo = true ) {
+ $name = esc_attr( $name );
$nonce_field = '<input type="hidden" id="' . $name . '" name="' . $name . '" value="' . wp_create_nonce( $action ) . '" />';
- if ( $referer )
+ if ( $referer ) {
$nonce_field .= wp_referer_field( false );
-
- if ( $echo )
+ }
+
+ if ( $echo ) {
echo $nonce_field;
+ }
return $nonce_field;
}
@@ -1490,10 +1659,11 @@
* @return string Referer field HTML markup.
*/
function wp_referer_field( $echo = true ) {
- $referer_field = '<input type="hidden" name="_wp_http_referer" value="'. esc_attr( wp_unslash( $_SERVER['REQUEST_URI'] ) ) . '" />';
-
- if ( $echo )
+ $referer_field = '<input type="hidden" name="_wp_http_referer" value="' . esc_attr( wp_unslash( $_SERVER['REQUEST_URI'] ) ) . '" />';
+
+ if ( $echo ) {
echo $referer_field;
+ }
return $referer_field;
}
@@ -1516,8 +1686,9 @@
$ref = 'previous' == $jump_back_to ? wp_get_referer() : wp_unslash( $_SERVER['REQUEST_URI'] );
}
$orig_referer_field = '<input type="hidden" name="_wp_original_http_referer" value="' . esc_attr( $ref ) . '" />';
- if ( $echo )
+ if ( $echo ) {
echo $orig_referer_field;
+ }
return $orig_referer_field;
}
@@ -1556,7 +1727,7 @@
function wp_get_raw_referer() {
if ( ! empty( $_REQUEST['_wp_http_referer'] ) ) {
return wp_unslash( $_REQUEST['_wp_http_referer'] );
- } else if ( ! empty( $_SERVER['HTTP_REFERER'] ) ) {
+ } elseif ( ! empty( $_SERVER['HTTP_REFERER'] ) ) {
return wp_unslash( $_SERVER['HTTP_REFERER'] );
}
@@ -1571,8 +1742,9 @@
* @return string|false False if no original referer or original referer if set.
*/
function wp_get_original_referer() {
- if ( ! empty( $_REQUEST['_wp_original_http_referer'] ) && function_exists( 'wp_validate_redirect' ) )
+ if ( ! empty( $_REQUEST['_wp_original_http_referer'] ) && function_exists( 'wp_validate_redirect' ) ) {
return wp_validate_redirect( wp_unslash( $_REQUEST['_wp_original_http_referer'] ), false );
+ }
return false;
}
@@ -1606,12 +1778,14 @@
* Safe mode fails with a trailing slash under certain PHP versions.
* Use rtrim() instead of untrailingslashit to avoid formatting.php dependency.
*/
- $target = rtrim($target, '/');
- if ( empty($target) )
+ $target = rtrim( $target, '/' );
+ if ( empty( $target ) ) {
$target = '/';
-
- if ( file_exists( $target ) )
+ }
+
+ if ( file_exists( $target ) ) {
return @is_dir( $target );
+ }
// We need to find the permissions of the parent folder that exists and inherit that.
$target_parent = dirname( $target );
@@ -1657,18 +1831,29 @@
*/
function path_is_absolute( $path ) {
/*
+ * Check to see if the path is a stream and check to see if its an actual
+ * path or file as realpath() does not support stream wrappers.
+ */
+ if ( wp_is_stream( $path ) && ( is_dir( $path ) || is_file( $path ) ) ) {
+ return true;
+ }
+
+ /*
* This is definitive if true but fails if $path does not exist or contains
* a symbolic link.
*/
- if ( realpath($path) == $path )
+ if ( realpath( $path ) == $path ) {
return true;
-
- if ( strlen($path) == 0 || $path[0] == '.' )
+ }
+
+ if ( strlen( $path ) == 0 || $path[0] == '.' ) {
return false;
+ }
// Windows allows absolute paths like this.
- if ( preg_match('#^[a-zA-Z]:\\\\#', $path) )
+ if ( preg_match( '#^[a-zA-Z]:\\\\#', $path ) ) {
return true;
+ }
// A path starting with / or \ is absolute; anything else is relative.
return ( $path[0] == '/' || $path[0] == '\\' );
@@ -1687,10 +1872,11 @@
* @return string The path with the base or absolute path.
*/
function path_join( $base, $path ) {
- if ( path_is_absolute($path) )
+ if ( path_is_absolute( $path ) ) {
return $path;
-
- return rtrim($base, '/') . '/' . ltrim($path, '/');
+ }
+
+ return rtrim( $base, '/' ) . '/' . ltrim( $path, '/' );
}
/**
@@ -1713,7 +1899,7 @@
$wrapper = '';
if ( wp_is_stream( $path ) ) {
list( $wrapper, $path ) = explode( '://', $path, 2 );
- $wrapper .= '://';
+ $wrapper .= '://';
}
// Standardise all paths to use /
@@ -1748,25 +1934,30 @@
*/
function get_temp_dir() {
static $temp = '';
- if ( defined('WP_TEMP_DIR') )
- return trailingslashit(WP_TEMP_DIR);
-
- if ( $temp )
+ if ( defined( 'WP_TEMP_DIR' ) ) {
+ return trailingslashit( WP_TEMP_DIR );
+ }
+
+ if ( $temp ) {
return trailingslashit( $temp );
-
- if ( function_exists('sys_get_temp_dir') ) {
+ }
+
+ if ( function_exists( 'sys_get_temp_dir' ) ) {
$temp = sys_get_temp_dir();
- if ( @is_dir( $temp ) && wp_is_writable( $temp ) )
+ if ( @is_dir( $temp ) && wp_is_writable( $temp ) ) {
return trailingslashit( $temp );
- }
-
- $temp = ini_get('upload_tmp_dir');
- if ( @is_dir( $temp ) && wp_is_writable( $temp ) )
+ }
+ }
+
+ $temp = ini_get( 'upload_tmp_dir' );
+ if ( @is_dir( $temp ) && wp_is_writable( $temp ) ) {
return trailingslashit( $temp );
+ }
$temp = WP_CONTENT_DIR . '/';
- if ( is_dir( $temp ) && wp_is_writable( $temp ) )
+ if ( is_dir( $temp ) && wp_is_writable( $temp ) ) {
return $temp;
+ }
return '/tmp/';
}
@@ -1785,10 +1976,11 @@
* @return bool Whether the path is writable.
*/
function wp_is_writable( $path ) {
- if ( 'WIN' === strtoupper( substr( PHP_OS, 0, 3 ) ) )
+ if ( 'WIN' === strtoupper( substr( PHP_OS, 0, 3 ) ) ) {
return win_is_writable( $path );
- else
+ } else {
return @is_writable( $path );
+ }
}
/**
@@ -1809,19 +2001,21 @@
*/
function win_is_writable( $path ) {
- if ( $path[strlen( $path ) - 1] == '/' ) { // if it looks like a directory, check a random file within the directory
- return win_is_writable( $path . uniqid( mt_rand() ) . '.tmp');
+ if ( $path[ strlen( $path ) - 1 ] == '/' ) { // if it looks like a directory, check a random file within the directory
+ return win_is_writable( $path . uniqid( mt_rand() ) . '.tmp' );
} elseif ( is_dir( $path ) ) { // If it's a directory (and not a file) check a random file within the directory
return win_is_writable( $path . '/' . uniqid( mt_rand() ) . '.tmp' );
}
// check tmp file for read/write capabilities
- $should_delete_tmp_file = !file_exists( $path );
- $f = @fopen( $path, 'a' );
- if ( $f === false )
+ $should_delete_tmp_file = ! file_exists( $path );
+ $f = @fopen( $path, 'a' );
+ if ( $f === false ) {
return false;
+ }
fclose( $f );
- if ( $should_delete_tmp_file )
+ if ( $should_delete_tmp_file ) {
unlink( $path );
+ }
return true;
}
@@ -1910,7 +2104,7 @@
if ( 0 === strpos( $uploads['basedir'], ABSPATH ) ) {
$error_path = str_replace( ABSPATH, '', $uploads['basedir'] ) . $uploads['subdir'];
} else {
- $error_path = basename( $uploads['basedir'] ) . $uploads['subdir'];
+ $error_path = wp_basename( $uploads['basedir'] ) . $uploads['subdir'];
}
$uploads['error'] = sprintf(
@@ -1937,7 +2131,7 @@
* @return array See wp_upload_dir()
*/
function _wp_upload_dir( $time = null ) {
- $siteurl = get_option( 'siteurl' );
+ $siteurl = get_option( 'siteurl' );
$upload_path = trim( get_option( 'upload_path' ) );
if ( empty( $upload_path ) || 'wp-content/uploads' == $upload_path ) {
@@ -1949,11 +2143,12 @@
$dir = $upload_path;
}
- if ( !$url = get_option( 'upload_url_path' ) ) {
- if ( empty($upload_path) || ( 'wp-content/uploads' == $upload_path ) || ( $upload_path == $dir ) )
+ if ( ! $url = get_option( 'upload_url_path' ) ) {
+ if ( empty( $upload_path ) || ( 'wp-content/uploads' == $upload_path ) || ( $upload_path == $dir ) ) {
$url = WP_CONTENT_URL . '/uploads';
- else
+ } else {
$url = trailingslashit( $siteurl ) . $upload_path;
+ }
}
/*
@@ -1978,10 +2173,11 @@
* had wp-content/uploads for the main site.)
*/
- if ( defined( 'MULTISITE' ) )
+ if ( defined( 'MULTISITE' ) ) {
$ms_dir = '/sites/' . get_current_blog_id();
- else
+ } else {
$ms_dir = '/' . get_current_blog_id();
+ }
$dir .= $ms_dir;
$url .= $ms_dir;
@@ -2001,10 +2197,11 @@
* rewriting in multisite, the resulting URL is /files. (#WP22702 for background.)
*/
- if ( defined( 'BLOGUPLOADDIR' ) )
+ if ( defined( 'BLOGUPLOADDIR' ) ) {
$dir = untrailingslashit( BLOGUPLOADDIR );
- else
+ } else {
$dir = ABSPATH . UPLOADS;
+ }
$url = trailingslashit( $siteurl ) . 'files';
}
}
@@ -2015,10 +2212,11 @@
$subdir = '';
if ( get_option( 'uploads_use_yearmonth_folders' ) ) {
// Generate the yearly and monthly dirs
- if ( !$time )
+ if ( ! $time ) {
$time = current_time( 'mysql' );
- $y = substr( $time, 0, 4 );
- $m = substr( $time, 5, 2 );
+ }
+ $y = substr( $time, 0, 4 );
+ $m = substr( $time, 5, 2 );
$subdir = "/$y/$m";
}
@@ -2054,10 +2252,10 @@
*/
function wp_unique_filename( $dir, $filename, $unique_filename_callback = null ) {
// Sanitize the file name before we begin processing.
- $filename = sanitize_file_name($filename);
+ $filename = sanitize_file_name( $filename );
// Separate the filename into a name and extension.
- $ext = pathinfo( $filename, PATHINFO_EXTENSION );
+ $ext = pathinfo( $filename, PATHINFO_EXTENSION );
$name = pathinfo( $filename, PATHINFO_BASENAME );
if ( $ext ) {
$ext = '.' . $ext;
@@ -2078,16 +2276,16 @@
$number = '';
// Change '.ext' to lower case.
- if ( $ext && strtolower($ext) != $ext ) {
- $ext2 = strtolower($ext);
- $filename2 = preg_replace( '|' . preg_quote($ext) . '$|', $ext2, $filename );
+ if ( $ext && strtolower( $ext ) != $ext ) {
+ $ext2 = strtolower( $ext );
+ $filename2 = preg_replace( '|' . preg_quote( $ext ) . '$|', $ext2, $filename );
// Check for both lower and upper case extension or image sub-sizes may be overwritten.
- while ( file_exists($dir . "/$filename") || file_exists($dir . "/$filename2") ) {
+ while ( file_exists( $dir . "/$filename" ) || file_exists( $dir . "/$filename2" ) ) {
$new_number = (int) $number + 1;
- $filename = str_replace( array( "-$number$ext", "$number$ext" ), "-$new_number$ext", $filename );
- $filename2 = str_replace( array( "-$number$ext2", "$number$ext2" ), "-$new_number$ext2", $filename2 );
- $number = $new_number;
+ $filename = str_replace( array( "-$number$ext", "$number$ext" ), "-$new_number$ext", $filename );
+ $filename2 = str_replace( array( "-$number$ext2", "$number$ext2" ), "-$new_number$ext2", $filename2 );
+ $number = $new_number;
}
/**
@@ -2108,7 +2306,7 @@
if ( '' == "$number$ext" ) {
$filename = "$filename-" . $new_number;
} else {
- $filename = str_replace( array( "-$number$ext", "$number$ext" ), "-" . $new_number . $ext, $filename );
+ $filename = str_replace( array( "-$number$ext", "$number$ext" ), '-' . $new_number . $ext, $filename );
}
$number = $new_number;
}
@@ -2142,20 +2340,24 @@
* @return array
*/
function wp_upload_bits( $name, $deprecated, $bits, $time = null ) {
- if ( !empty( $deprecated ) )
+ if ( ! empty( $deprecated ) ) {
_deprecated_argument( __FUNCTION__, '2.0.0' );
-
- if ( empty( $name ) )
+ }
+
+ if ( empty( $name ) ) {
return array( 'error' => __( 'Empty filename' ) );
+ }
$wp_filetype = wp_check_filetype( $name );
- if ( ! $wp_filetype['ext'] && ! current_user_can( 'unfiltered_upload' ) )
+ if ( ! $wp_filetype['ext'] && ! current_user_can( 'unfiltered_upload' ) ) {
return array( 'error' => __( 'Sorry, this file type is not permitted for security reasons.' ) );
+ }
$upload = wp_upload_dir( $time );
- if ( $upload['error'] !== false )
+ if ( $upload['error'] !== false ) {
return $upload;
+ }
/**
* Filters whether to treat the upload bits as an error.
@@ -2167,9 +2369,16 @@
*
* @param mixed $upload_bits_error An array of upload bits data, or a non-array error to return.
*/
- $upload_bits_error = apply_filters( 'wp_upload_bits', array( 'name' => $name, 'bits' => $bits, 'time' => $time ) );
- if ( !is_array( $upload_bits_error ) ) {
- $upload[ 'error' ] = $upload_bits_error;
+ $upload_bits_error = apply_filters(
+ 'wp_upload_bits',
+ array(
+ 'name' => $name,
+ 'bits' => $bits,
+ 'time' => $time,
+ )
+ );
+ if ( ! is_array( $upload_bits_error ) ) {
+ $upload['error'] = $upload_bits_error;
return $upload;
}
@@ -2177,10 +2386,11 @@
$new_file = $upload['path'] . "/$filename";
if ( ! wp_mkdir_p( dirname( $new_file ) ) ) {
- if ( 0 === strpos( $upload['basedir'], ABSPATH ) )
+ if ( 0 === strpos( $upload['basedir'], ABSPATH ) ) {
$error_path = str_replace( ABSPATH, '', $upload['basedir'] ) . $upload['subdir'];
- else
- $error_path = basename( $upload['basedir'] ) . $upload['subdir'];
+ } else {
+ $error_path = wp_basename( $upload['basedir'] ) . $upload['subdir'];
+ }
$message = sprintf(
/* translators: %s: directory path */
@@ -2191,15 +2401,16 @@
}
$ifp = @ fopen( $new_file, 'wb' );
- if ( ! $ifp )
+ if ( ! $ifp ) {
return array( 'error' => sprintf( __( 'Could not write file %s' ), $new_file ) );
+ }
@fwrite( $ifp, $bits );
fclose( $ifp );
clearstatcache();
// Set correct file permissions
- $stat = @ stat( dirname( $new_file ) );
+ $stat = @ stat( dirname( $new_file ) );
$perms = $stat['mode'] & 0007777;
$perms = $perms & 0000666;
@ chmod( $new_file, $perms );
@@ -2209,7 +2420,16 @@
$url = $upload['url'] . "/$filename";
/** This filter is documented in wp-admin/includes/file.php */
- return apply_filters( 'wp_handle_upload', array( 'file' => $new_file, 'url' => $url, 'type' => $wp_filetype['type'], 'error' => false ), 'sideload' );
+ return apply_filters(
+ 'wp_handle_upload',
+ array(
+ 'file' => $new_file,
+ 'url' => $url,
+ 'type' => $wp_filetype['type'],
+ 'error' => false,
+ ),
+ 'sideload'
+ );
}
/**
@@ -2224,9 +2444,11 @@
$ext = strtolower( $ext );
$ext2type = wp_get_ext_types();
- foreach ( $ext2type as $type => $exts )
- if ( in_array( $ext, $exts ) )
+ foreach ( $ext2type as $type => $exts ) {
+ if ( in_array( $ext, $exts ) ) {
return $type;
+ }
+ }
}
/**
@@ -2241,16 +2463,17 @@
* @return array Values with extension first and mime type.
*/
function wp_check_filetype( $filename, $mimes = null ) {
- if ( empty($mimes) )
+ if ( empty( $mimes ) ) {
$mimes = get_allowed_mime_types();
+ }
$type = false;
- $ext = false;
+ $ext = false;
foreach ( $mimes as $ext_preg => $mime_match ) {
$ext_preg = '!\.(' . $ext_preg . ')$!i';
if ( preg_match( $ext_preg, $filename, $ext_matches ) ) {
$type = $mime_match;
- $ext = $ext_matches[1];
+ $ext = $ext_matches[1];
break;
}
}
@@ -2282,8 +2505,8 @@
// Do basic extension validation and MIME mapping
$wp_filetype = wp_check_filetype( $filename, $mimes );
- $ext = $wp_filetype['ext'];
- $type = $wp_filetype['type'];
+ $ext = $wp_filetype['ext'];
+ $type = $wp_filetype['type'];
// We can't do any further validation without a file to work with
if ( ! file_exists( $file ) ) {
@@ -2306,28 +2529,31 @@
*
* @param array $mime_to_ext Array of image mime types and their matching extensions.
*/
- $mime_to_ext = apply_filters( 'getimagesize_mimes_to_exts', array(
- 'image/jpeg' => 'jpg',
- 'image/png' => 'png',
- 'image/gif' => 'gif',
- 'image/bmp' => 'bmp',
- 'image/tiff' => 'tif',
- ) );
+ $mime_to_ext = apply_filters(
+ 'getimagesize_mimes_to_exts',
+ array(
+ 'image/jpeg' => 'jpg',
+ 'image/png' => 'png',
+ 'image/gif' => 'gif',
+ 'image/bmp' => 'bmp',
+ 'image/tiff' => 'tif',
+ )
+ );
// Replace whatever is after the last period in the filename with the correct extension
if ( ! empty( $mime_to_ext[ $real_mime ] ) ) {
$filename_parts = explode( '.', $filename );
array_pop( $filename_parts );
$filename_parts[] = $mime_to_ext[ $real_mime ];
- $new_filename = implode( '.', $filename_parts );
+ $new_filename = implode( '.', $filename_parts );
if ( $new_filename != $filename ) {
$proper_filename = $new_filename; // Mark that it changed
}
// Redefine the extension / MIME
$wp_filetype = wp_check_filetype( $new_filename, $mimes );
- $ext = $wp_filetype['ext'];
- $type = $wp_filetype['type'];
+ $ext = $wp_filetype['ext'];
+ $type = $wp_filetype['type'];
} else {
// Reset $real_mime and try validating again.
$real_mime = false;
@@ -2337,21 +2563,82 @@
// Validate files that didn't get validated during previous checks.
if ( $type && ! $real_mime && extension_loaded( 'fileinfo' ) ) {
- $finfo = finfo_open( FILEINFO_MIME_TYPE );
+ $finfo = finfo_open( FILEINFO_MIME_TYPE );
$real_mime = finfo_file( $finfo, $file );
finfo_close( $finfo );
+ // fileinfo often misidentifies obscure files as one of these types
+ $nonspecific_types = array(
+ 'application/octet-stream',
+ 'application/encrypted',
+ 'application/CDFV2-encrypted',
+ 'application/zip',
+ );
+
/*
- * If $real_mime doesn't match what we're expecting, we need to do some extra
- * vetting of application mime types to make sure this type of file is allowed.
- * Other mime types are assumed to be safe, but should be considered unverified.
+ * If $real_mime doesn't match the content type we're expecting from the file's extension,
+ * we need to do some additional vetting. Media types and those listed in $nonspecific_types are
+ * allowed some leeway, but anything else must exactly match the real content type.
*/
- if ( $real_mime && ( $real_mime !== $type ) && ( 0 === strpos( $real_mime, 'application' ) ) ) {
- $allowed = get_allowed_mime_types();
-
- if ( ! in_array( $real_mime, $allowed ) ) {
+ if ( in_array( $real_mime, $nonspecific_types, true ) ) {
+ // File is a non-specific binary type. That's ok if it's a type that generally tends to be binary.
+ if ( ! in_array( substr( $type, 0, strcspn( $type, '/' ) ), array( 'application', 'video', 'audio' ) ) ) {
+ $type = $ext = false;
+ }
+ } elseif ( 0 === strpos( $real_mime, 'video/' ) || 0 === strpos( $real_mime, 'audio/' ) ) {
+ /*
+ * For these types, only the major type must match the real value.
+ * This means that common mismatches are forgiven: application/vnd.apple.numbers is often misidentified as application/zip,
+ * and some media files are commonly named with the wrong extension (.mov instead of .mp4)
+ */
+ if ( substr( $real_mime, 0, strcspn( $real_mime, '/' ) ) !== substr( $type, 0, strcspn( $type, '/' ) ) ) {
$type = $ext = false;
}
+ } elseif ( 'text/plain' === $real_mime ) {
+ // A few common file types are occasionally detected as text/plain; allow those.
+ if ( ! in_array(
+ $type,
+ array(
+ 'text/plain',
+ 'text/csv',
+ 'text/richtext',
+ 'text/tsv',
+ 'text/vtt',
+ )
+ )
+ ) {
+ $type = $ext = false;
+ }
+ } elseif ( 'text/rtf' === $real_mime ) {
+ // Special casing for RTF files.
+ if ( ! in_array(
+ $type,
+ array(
+ 'text/rtf',
+ 'text/plain',
+ 'application/rtf',
+ )
+ )
+ ) {
+ $type = $ext = false;
+ }
+ } else {
+ if ( $type !== $real_mime ) {
+ /*
+ * Everything else including image/* and application/*:
+ * If the real content type doesn't match the file extension, assume it's dangerous.
+ */
+ $type = $ext = false;
+ }
+ }
+ }
+
+ // The mime type must be allowed
+ if ( $type ) {
+ $allowed = get_allowed_mime_types();
+
+ if ( ! in_array( $type, $allowed ) ) {
+ $type = $ext = false;
}
}
@@ -2359,15 +2646,17 @@
* Filters the "real" file type of the given file.
*
* @since 3.0.0
+ * @since 5.1.0 The $real_mime parameter was added.
*
- * @param array $wp_check_filetype_and_ext File data array containing 'ext', 'type', and
- * 'proper_filename' keys.
- * @param string $file Full path to the file.
- * @param string $filename The name of the file (may differ from $file due to
- * $file being in a tmp directory).
- * @param array $mimes Key is the file extension with value as the mime type.
+ * @param array $wp_check_filetype_and_ext File data array containing 'ext', 'type', and
+ * 'proper_filename' keys.
+ * @param string $file Full path to the file.
+ * @param string $filename The name of the file (may differ from $file due to
+ * $file being in a tmp directory).
+ * @param array $mimes Key is the file extension with value as the mime type.
+ * @param string|bool $real_mime The actual mime type or false if the type cannot be determined.
*/
- return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes );
+ return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes, $real_mime );
}
/**
@@ -2389,10 +2678,10 @@
try {
if ( is_callable( 'exif_imagetype' ) ) {
$imagetype = exif_imagetype( $file );
- $mime = ( $imagetype ) ? image_type_to_mime_type( $imagetype ) : false;
+ $mime = ( $imagetype ) ? image_type_to_mime_type( $imagetype ) : false;
} elseif ( function_exists( 'getimagesize' ) ) {
$imagesize = getimagesize( $file );
- $mime = ( isset( $imagesize['mime'] ) ) ? $imagesize['mime'] : false;
+ $mime = ( isset( $imagesize['mime'] ) ) ? $imagesize['mime'] : false;
} else {
$mime = false;
}
@@ -2423,109 +2712,112 @@
* @param array $wp_get_mime_types Mime types keyed by the file extension regex
* corresponding to those types.
*/
- return apply_filters( 'mime_types', array(
- // Image formats.
- 'jpg|jpeg|jpe' => 'image/jpeg',
- 'gif' => 'image/gif',
- 'png' => 'image/png',
- 'bmp' => 'image/bmp',
- 'tiff|tif' => 'image/tiff',
- 'ico' => 'image/x-icon',
- // Video formats.
- 'asf|asx' => 'video/x-ms-asf',
- 'wmv' => 'video/x-ms-wmv',
- 'wmx' => 'video/x-ms-wmx',
- 'wm' => 'video/x-ms-wm',
- 'avi' => 'video/avi',
- 'divx' => 'video/divx',
- 'flv' => 'video/x-flv',
- 'mov|qt' => 'video/quicktime',
- 'mpeg|mpg|mpe' => 'video/mpeg',
- 'mp4|m4v' => 'video/mp4',
- 'ogv' => 'video/ogg',
- 'webm' => 'video/webm',
- 'mkv' => 'video/x-matroska',
- '3gp|3gpp' => 'video/3gpp', // Can also be audio
- '3g2|3gp2' => 'video/3gpp2', // Can also be audio
- // Text formats.
- 'txt|asc|c|cc|h|srt' => 'text/plain',
- 'csv' => 'text/csv',
- 'tsv' => 'text/tab-separated-values',
- 'ics' => 'text/calendar',
- 'rtx' => 'text/richtext',
- 'css' => 'text/css',
- 'htm|html' => 'text/html',
- 'vtt' => 'text/vtt',
- 'dfxp' => 'application/ttaf+xml',
- // Audio formats.
- 'mp3|m4a|m4b' => 'audio/mpeg',
- 'aac' => 'audio/aac',
- 'ra|ram' => 'audio/x-realaudio',
- 'wav' => 'audio/wav',
- 'ogg|oga' => 'audio/ogg',
- 'flac' => 'audio/flac',
- 'mid|midi' => 'audio/midi',
- 'wma' => 'audio/x-ms-wma',
- 'wax' => 'audio/x-ms-wax',
- 'mka' => 'audio/x-matroska',
- // Misc application formats.
- 'rtf' => 'application/rtf',
- 'js' => 'application/javascript',
- 'pdf' => 'application/pdf',
- 'swf' => 'application/x-shockwave-flash',
- 'class' => 'application/java',
- 'tar' => 'application/x-tar',
- 'zip' => 'application/zip',
- 'gz|gzip' => 'application/x-gzip',
- 'rar' => 'application/rar',
- '7z' => 'application/x-7z-compressed',
- 'exe' => 'application/x-msdownload',
- 'psd' => 'application/octet-stream',
- 'xcf' => 'application/octet-stream',
- // MS Office formats.
- 'doc' => 'application/msword',
- 'pot|pps|ppt' => 'application/vnd.ms-powerpoint',
- 'wri' => 'application/vnd.ms-write',
- 'xla|xls|xlt|xlw' => 'application/vnd.ms-excel',
- 'mdb' => 'application/vnd.ms-access',
- 'mpp' => 'application/vnd.ms-project',
- 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
- 'docm' => 'application/vnd.ms-word.document.macroEnabled.12',
- 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
- 'dotm' => 'application/vnd.ms-word.template.macroEnabled.12',
- 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
- 'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12',
- 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
- 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
- 'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12',
- 'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',
- 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
- 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12',
- 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
- 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12',
- 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
- 'potm' => 'application/vnd.ms-powerpoint.template.macroEnabled.12',
- 'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12',
- 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
- 'sldm' => 'application/vnd.ms-powerpoint.slide.macroEnabled.12',
- 'onetoc|onetoc2|onetmp|onepkg' => 'application/onenote',
- 'oxps' => 'application/oxps',
- 'xps' => 'application/vnd.ms-xpsdocument',
- // OpenOffice formats.
- 'odt' => 'application/vnd.oasis.opendocument.text',
- 'odp' => 'application/vnd.oasis.opendocument.presentation',
- 'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
- 'odg' => 'application/vnd.oasis.opendocument.graphics',
- 'odc' => 'application/vnd.oasis.opendocument.chart',
- 'odb' => 'application/vnd.oasis.opendocument.database',
- 'odf' => 'application/vnd.oasis.opendocument.formula',
- // WordPerfect formats.
- 'wp|wpd' => 'application/wordperfect',
- // iWork formats.
- 'key' => 'application/vnd.apple.keynote',
- 'numbers' => 'application/vnd.apple.numbers',
- 'pages' => 'application/vnd.apple.pages',
- ) );
+ return apply_filters(
+ 'mime_types',
+ array(
+ // Image formats.
+ 'jpg|jpeg|jpe' => 'image/jpeg',
+ 'gif' => 'image/gif',
+ 'png' => 'image/png',
+ 'bmp' => 'image/bmp',
+ 'tiff|tif' => 'image/tiff',
+ 'ico' => 'image/x-icon',
+ // Video formats.
+ 'asf|asx' => 'video/x-ms-asf',
+ 'wmv' => 'video/x-ms-wmv',
+ 'wmx' => 'video/x-ms-wmx',
+ 'wm' => 'video/x-ms-wm',
+ 'avi' => 'video/avi',
+ 'divx' => 'video/divx',
+ 'flv' => 'video/x-flv',
+ 'mov|qt' => 'video/quicktime',
+ 'mpeg|mpg|mpe' => 'video/mpeg',
+ 'mp4|m4v' => 'video/mp4',
+ 'ogv' => 'video/ogg',
+ 'webm' => 'video/webm',
+ 'mkv' => 'video/x-matroska',
+ '3gp|3gpp' => 'video/3gpp', // Can also be audio
+ '3g2|3gp2' => 'video/3gpp2', // Can also be audio
+ // Text formats.
+ 'txt|asc|c|cc|h|srt' => 'text/plain',
+ 'csv' => 'text/csv',
+ 'tsv' => 'text/tab-separated-values',
+ 'ics' => 'text/calendar',
+ 'rtx' => 'text/richtext',
+ 'css' => 'text/css',
+ 'htm|html' => 'text/html',
+ 'vtt' => 'text/vtt',
+ 'dfxp' => 'application/ttaf+xml',
+ // Audio formats.
+ 'mp3|m4a|m4b' => 'audio/mpeg',
+ 'aac' => 'audio/aac',
+ 'ra|ram' => 'audio/x-realaudio',
+ 'wav' => 'audio/wav',
+ 'ogg|oga' => 'audio/ogg',
+ 'flac' => 'audio/flac',
+ 'mid|midi' => 'audio/midi',
+ 'wma' => 'audio/x-ms-wma',
+ 'wax' => 'audio/x-ms-wax',
+ 'mka' => 'audio/x-matroska',
+ // Misc application formats.
+ 'rtf' => 'application/rtf',
+ 'js' => 'application/javascript',
+ 'pdf' => 'application/pdf',
+ 'swf' => 'application/x-shockwave-flash',
+ 'class' => 'application/java',
+ 'tar' => 'application/x-tar',
+ 'zip' => 'application/zip',
+ 'gz|gzip' => 'application/x-gzip',
+ 'rar' => 'application/rar',
+ '7z' => 'application/x-7z-compressed',
+ 'exe' => 'application/x-msdownload',
+ 'psd' => 'application/octet-stream',
+ 'xcf' => 'application/octet-stream',
+ // MS Office formats.
+ 'doc' => 'application/msword',
+ 'pot|pps|ppt' => 'application/vnd.ms-powerpoint',
+ 'wri' => 'application/vnd.ms-write',
+ 'xla|xls|xlt|xlw' => 'application/vnd.ms-excel',
+ 'mdb' => 'application/vnd.ms-access',
+ 'mpp' => 'application/vnd.ms-project',
+ 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+ 'docm' => 'application/vnd.ms-word.document.macroEnabled.12',
+ 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
+ 'dotm' => 'application/vnd.ms-word.template.macroEnabled.12',
+ 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+ 'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12',
+ 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
+ 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
+ 'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12',
+ 'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',
+ 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
+ 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12',
+ 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
+ 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12',
+ 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
+ 'potm' => 'application/vnd.ms-powerpoint.template.macroEnabled.12',
+ 'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12',
+ 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
+ 'sldm' => 'application/vnd.ms-powerpoint.slide.macroEnabled.12',
+ 'onetoc|onetoc2|onetmp|onepkg' => 'application/onenote',
+ 'oxps' => 'application/oxps',
+ 'xps' => 'application/vnd.ms-xpsdocument',
+ // OpenOffice formats.
+ 'odt' => 'application/vnd.oasis.opendocument.text',
+ 'odp' => 'application/vnd.oasis.opendocument.presentation',
+ 'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
+ 'odg' => 'application/vnd.oasis.opendocument.graphics',
+ 'odc' => 'application/vnd.oasis.opendocument.chart',
+ 'odb' => 'application/vnd.oasis.opendocument.database',
+ 'odf' => 'application/vnd.oasis.opendocument.formula',
+ // WordPerfect formats.
+ 'wp|wpd' => 'application/wordperfect',
+ // iWork formats.
+ 'key' => 'application/vnd.apple.keynote',
+ 'numbers' => 'application/vnd.apple.numbers',
+ 'pages' => 'application/vnd.apple.pages',
+ )
+ );
}
/**
@@ -2547,17 +2839,20 @@
* @param array $ext2type Multi-dimensional array with extensions for a default set
* of file types.
*/
- return apply_filters( 'ext2type', array(
- 'image' => array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'bmp', 'tif', 'tiff', 'ico' ),
- 'audio' => array( 'aac', 'ac3', 'aif', 'aiff', 'flac', 'm3a', 'm4a', 'm4b', 'mka', 'mp1', 'mp2', 'mp3', 'ogg', 'oga', 'ram', 'wav', 'wma' ),
- 'video' => array( '3g2', '3gp', '3gpp', 'asf', 'avi', 'divx', 'dv', 'flv', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'mpv', 'ogm', 'ogv', 'qt', 'rm', 'vob', 'wmv' ),
- 'document' => array( 'doc', 'docx', 'docm', 'dotm', 'odt', 'pages', 'pdf', 'xps', 'oxps', 'rtf', 'wp', 'wpd', 'psd', 'xcf' ),
- 'spreadsheet' => array( 'numbers', 'ods', 'xls', 'xlsx', 'xlsm', 'xlsb' ),
- 'interactive' => array( 'swf', 'key', 'ppt', 'pptx', 'pptm', 'pps', 'ppsx', 'ppsm', 'sldx', 'sldm', 'odp' ),
- 'text' => array( 'asc', 'csv', 'tsv', 'txt' ),
- 'archive' => array( 'bz2', 'cab', 'dmg', 'gz', 'rar', 'sea', 'sit', 'sqx', 'tar', 'tgz', 'zip', '7z' ),
- 'code' => array( 'css', 'htm', 'html', 'php', 'js' ),
- ) );
+ return apply_filters(
+ 'ext2type',
+ array(
+ 'image' => array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'bmp', 'tif', 'tiff', 'ico' ),
+ 'audio' => array( 'aac', 'ac3', 'aif', 'aiff', 'flac', 'm3a', 'm4a', 'm4b', 'mka', 'mp1', 'mp2', 'mp3', 'ogg', 'oga', 'ram', 'wav', 'wma' ),
+ 'video' => array( '3g2', '3gp', '3gpp', 'asf', 'avi', 'divx', 'dv', 'flv', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'mpv', 'ogm', 'ogv', 'qt', 'rm', 'vob', 'wmv' ),
+ 'document' => array( 'doc', 'docx', 'docm', 'dotm', 'odt', 'pages', 'pdf', 'xps', 'oxps', 'rtf', 'wp', 'wpd', 'psd', 'xcf' ),
+ 'spreadsheet' => array( 'numbers', 'ods', 'xls', 'xlsx', 'xlsm', 'xlsb' ),
+ 'interactive' => array( 'swf', 'key', 'ppt', 'pptx', 'pptm', 'pps', 'ppsx', 'ppsm', 'sldx', 'sldm', 'odp' ),
+ 'text' => array( 'asc', 'csv', 'tsv', 'txt' ),
+ 'archive' => array( 'bz2', 'cab', 'dmg', 'gz', 'rar', 'sea', 'sit', 'sqx', 'tar', 'tgz', 'zip', '7z' ),
+ 'code' => array( 'css', 'htm', 'html', 'php', 'js' ),
+ )
+ );
}
/**
@@ -2573,8 +2868,9 @@
$t = wp_get_mime_types();
unset( $t['swf'], $t['exe'] );
- if ( function_exists( 'current_user_can' ) )
+ if ( function_exists( 'current_user_can' ) ) {
$unfiltered = $user ? user_can( $user, 'unfiltered_html' ) : current_user_can( 'unfiltered_html' );
+ }
if ( empty( $unfiltered ) ) {
unset( $t['htm|html'], $t['js'] );
@@ -2610,9 +2906,9 @@
__( 'You are attempting to log out of %s' ),
get_bloginfo( 'name' )
);
- $html .= '</p><p>';
+ $html .= '</p><p>';
$redirect_to = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '';
- $html .= sprintf(
+ $html .= sprintf(
/* translators: %s: logout URL */
__( 'Do you really want to <a href="%s">log out</a>?' ),
wp_logout_url( $redirect_to )
@@ -2621,7 +2917,8 @@
$html = __( 'The link you followed has expired.' );
if ( wp_get_referer() ) {
$html .= '</p><p>';
- $html .= sprintf( '<a href="%s">%s</a>',
+ $html .= sprintf(
+ '<a href="%s">%s</a>',
esc_url( remove_query_arg( 'updated', wp_get_referer() ) ),
__( 'Please try again.' )
);
@@ -2632,7 +2929,7 @@
}
/**
- * Kill WordPress execution and display HTML message with error message.
+ * Kills WordPress execution and displays HTML page with an error message.
*
* This function complements the `die()` PHP function. The difference is that
* HTML will be displayed to the user. It is recommended to use this function
@@ -2646,6 +2943,9 @@
* @since 2.0.4
* @since 4.1.0 The `$title` and `$args` parameters were changed to optionally accept
* an integer to be used as the response code.
+ * @since 5.1.0 The `$link_url`, `$link_text`, and `$exit` arguments were added.
+ *
+ * @global WP_Query $wp_query Global WP_Query instance.
*
* @param string|WP_Error $message Optional. Error message. If this is a WP_Error object,
* and not an Ajax or XML-RPC request, the error's messages are used.
@@ -2659,13 +2959,21 @@
* as the response code. Default empty array.
*
* @type int $response The HTTP response code. Default 200 for Ajax requests, 500 otherwise.
+ * @type string $link_url A URL to include a link to. Only works in combination with $link_text.
+ * Default empty string.
+ * @type string $link_text A label for the link to include. Only works in combination with $link_url.
+ * Default empty string.
* @type bool $back_link Whether to include a link to go back. Default false.
* @type string $text_direction The text direction. This is only useful internally, when WordPress
* is still loading and the site's locale is not set up yet. Accepts 'rtl'.
* Default is the value of is_rtl().
+ * @type string $code Error code to use. Default is 'wp_die', or the main error code if $message
+ * is a WP_Error.
+ * @type bool $exit Whether to exit the process after completion. Default true.
* }
*/
function wp_die( $message = '', $title = '', $args = array() ) {
+ global $wp_query;
if ( is_int( $args ) ) {
$args = array( 'response' => $args );
@@ -2683,6 +2991,24 @@
* @param callable $function Callback function name.
*/
$function = apply_filters( 'wp_die_ajax_handler', '_ajax_wp_die_handler' );
+ } elseif ( wp_is_json_request() ) {
+ /**
+ * Filters the callback for killing WordPress execution for JSON requests.
+ *
+ * @since 5.1.0
+ *
+ * @param callable $function Callback function name.
+ */
+ $function = apply_filters( 'wp_die_json_handler', '_json_wp_die_handler' );
+ } elseif ( wp_is_jsonp_request() ) {
+ /**
+ * Filters the callback for killing WordPress execution for JSONP requests.
+ *
+ * @since 5.2.0
+ *
+ * @param callable $function Callback function name.
+ */
+ $function = apply_filters( 'wp_die_jsonp_handler', '_jsonp_wp_die_handler' );
} elseif ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) {
/**
* Filters the callback for killing WordPress execution for XML-RPC requests.
@@ -2692,9 +3018,22 @@
* @param callable $function Callback function name.
*/
$function = apply_filters( 'wp_die_xmlrpc_handler', '_xmlrpc_wp_die_handler' );
+ } elseif ( wp_is_xml_request()
+ || isset( $wp_query ) &&
+ ( function_exists( 'is_feed' ) && is_feed()
+ || function_exists( 'is_comment_feed' ) && is_comment_feed()
+ || function_exists( 'is_trackback' ) && is_trackback() ) ) {
+ /**
+ * Filters the callback for killing WordPress execution for XML requests.
+ *
+ * @since 5.2.0
+ *
+ * @param callable $function Callback function name.
+ */
+ $function = apply_filters( 'wp_die_xml_handler', '_xml_wp_die_handler' );
} else {
/**
- * Filters the callback for killing WordPress execution for all non-Ajax, non-XML-RPC requests.
+ * Filters the callback for killing WordPress execution for all non-Ajax, non-JSON, non-XML requests.
*
* @since 3.0.0
*
@@ -2707,10 +3046,10 @@
}
/**
- * Kills WordPress execution and display HTML message with error message.
- *
- * This is the default handler for wp_die if you want a custom one for your
- * site then you can overload using the {@see 'wp_die_handler'} filter in wp_die().
+ * Kills WordPress execution and displays HTML page with an error message.
+ *
+ * This is the default handler for wp_die(). If you want a custom one,
+ * you can override this using the {@see 'wp_die_handler'} filter in wp_die().
*
* @since 3.0.0
* @access private
@@ -2720,65 +3059,61 @@
* @param string|array $args Optional. Arguments to control behavior. Default empty array.
*/
function _default_wp_die_handler( $message, $title = '', $args = array() ) {
- $defaults = array( 'response' => 500 );
- $r = wp_parse_args($args, $defaults);
-
- $have_gettext = function_exists('__');
-
- if ( function_exists( 'is_wp_error' ) && is_wp_error( $message ) ) {
- if ( empty( $title ) ) {
- $error_data = $message->get_error_data();
- if ( is_array( $error_data ) && isset( $error_data['title'] ) )
- $title = $error_data['title'];
+ list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args );
+
+ if ( is_string( $message ) ) {
+ if ( ! empty( $r['additional_errors'] ) ) {
+ $message = array_merge(
+ array( $message ),
+ wp_list_pluck( $r['additional_errors'], 'message' )
+ );
+ $message = "<ul>\n\t\t<li>" . join( "</li>\n\t\t<li>", $message ) . "</li>\n\t</ul>";
+ } else {
+ $message = "<p>$message</p>";
}
- $errors = $message->get_error_messages();
- switch ( count( $errors ) ) {
- case 0 :
- $message = '';
- break;
- case 1 :
- $message = "<p>{$errors[0]}</p>";
- break;
- default :
- $message = "<ul>\n\t\t<li>" . join( "</li>\n\t\t<li>", $errors ) . "</li>\n\t</ul>";
- break;
+ }
+
+ $have_gettext = function_exists( '__' );
+
+ if ( ! empty( $r['link_url'] ) && ! empty( $r['link_text'] ) ) {
+ $link_url = $r['link_url'];
+ if ( function_exists( 'esc_url' ) ) {
+ $link_url = esc_url( $link_url );
}
- } elseif ( is_string( $message ) ) {
- $message = "<p>$message</p>";
+ $link_text = $r['link_text'];
+ $message .= "\n<p><a href='{$link_url}'>{$link_text}</a></p>";
}
if ( isset( $r['back_link'] ) && $r['back_link'] ) {
- $back_text = $have_gettext? __('« Back') : '« Back';
- $message .= "\n<p><a href='javascript:history.back()'>$back_text</a></p>";
+ $back_text = $have_gettext ? __( '« Back' ) : '« Back';
+ $message .= "\n<p><a href='javascript:history.back()'>$back_text</a></p>";
}
if ( ! did_action( 'admin_head' ) ) :
- if ( !headers_sent() ) {
+ if ( ! headers_sent() ) {
+ header( 'Content-Type: text/html; charset=utf-8' );
status_header( $r['response'] );
nocache_headers();
- header( 'Content-Type: text/html; charset=utf-8' );
}
- if ( empty($title) )
- $title = $have_gettext ? __('WordPress › Error') : 'WordPress › Error';
-
- $text_direction = 'ltr';
- if ( isset($r['text_direction']) && 'rtl' == $r['text_direction'] )
- $text_direction = 'rtl';
- elseif ( function_exists( 'is_rtl' ) && is_rtl() )
- $text_direction = 'rtl';
-?>
+ $text_direction = $r['text_direction'];
+ if ( function_exists( 'language_attributes' ) && function_exists( 'is_rtl' ) ) {
+ $dir_attr = get_language_attributes();
+ } else {
+ $dir_attr = "dir='$text_direction'";
+ }
+ ?>
<!DOCTYPE html>
-<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'"; ?>>
+<html xmlns="http://www.w3.org/1999/xhtml" <?php echo $dir_attr; ?>>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width">
- <?php
- if ( function_exists( 'wp_no_robots' ) ) {
- wp_no_robots();
- }
- ?>
- <title><?php echo $title ?></title>
+ <?php
+ if ( function_exists( 'wp_no_robots' ) ) {
+ wp_no_robots();
+ }
+ ?>
+ <title><?php echo $title; ?></title>
<style type="text/css">
html {
background: #f1f1f1;
@@ -2790,8 +3125,8 @@
margin: 2em auto;
padding: 1em 2em;
max-width: 700px;
- -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.13);
- box-shadow: 0 1px 3px rgba(0,0,0,0.13);
+ -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.13);
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.13);
}
h1 {
border-bottom: 1px solid #dadada;
@@ -2826,12 +3161,12 @@
}
a:focus {
color: #124964;
- -webkit-box-shadow:
- 0 0 0 1px #5b9dd9,
- 0 0 2px 1px rgba(30, 140, 190, .8);
- box-shadow:
- 0 0 0 1px #5b9dd9,
- 0 0 2px 1px rgba(30, 140, 190, .8);
+ -webkit-box-shadow:
+ 0 0 0 1px #5b9dd9,
+ 0 0 2px 1px rgba(30, 140, 190, 0.8);
+ box-shadow:
+ 0 0 0 1px #5b9dd9,
+ 0 0 2px 1px rgba(30, 140, 190, 0.8);
outline: none;
}
.button {
@@ -2856,7 +3191,7 @@
-webkit-box-shadow: 0 1px 0 #ccc;
box-shadow: 0 1px 0 #ccc;
- vertical-align: top;
+ vertical-align: top;
}
.button.button-large {
@@ -2872,21 +3207,21 @@
color: #23282d;
}
- .button:focus {
+ .button:focus {
border-color: #5b9dd9;
- -webkit-box-shadow: 0 0 3px rgba( 0, 115, 170, .8 );
- box-shadow: 0 0 3px rgba( 0, 115, 170, .8 );
+ -webkit-box-shadow: 0 0 3px rgba(0, 115, 170, 0.8);
+ box-shadow: 0 0 3px rgba(0, 115, 170, 0.8);
outline: none;
}
.button:active {
background: #eee;
border-color: #999;
- -webkit-box-shadow: inset 0 2px 5px -3px rgba( 0, 0, 0, 0.5 );
- box-shadow: inset 0 2px 5px -3px rgba( 0, 0, 0, 0.5 );
- -webkit-transform: translateY(1px);
- -ms-transform: translateY(1px);
- transform: translateY(1px);
+ -webkit-box-shadow: inset 0 2px 5px -3px rgba(0, 0, 0, 0.5);
+ box-shadow: inset 0 2px 5px -3px rgba(0, 0, 0, 0.5);
+ -webkit-transform: translateY(1px);
+ -ms-transform: translateY(1px);
+ transform: translateY(1px);
}
<?php
@@ -2901,14 +3236,138 @@
<?php echo $message; ?>
</body>
</html>
-<?php
- die();
-}
-
-/**
- * Kill WordPress execution and display XML message with error message.
- *
- * This is the handler for wp_die when processing XMLRPC requests.
+ <?php
+ if ( $r['exit'] ) {
+ die();
+ }
+}
+
+/**
+ * Kills WordPress execution and displays Ajax response with an error message.
+ *
+ * This is the handler for wp_die() when processing Ajax requests.
+ *
+ * @since 3.4.0
+ * @access private
+ *
+ * @param string $message Error message.
+ * @param string $title Optional. Error title (unused). Default empty.
+ * @param string|array $args Optional. Arguments to control behavior. Default empty array.
+ */
+function _ajax_wp_die_handler( $message, $title = '', $args = array() ) {
+ // Set default 'response' to 200 for AJAX requests.
+ $args = wp_parse_args(
+ $args,
+ array( 'response' => 200 )
+ );
+
+ list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args );
+
+ if ( ! headers_sent() ) {
+ // This is intentional. For backward-compatibility, support passing null here.
+ if ( null !== $args['response'] ) {
+ status_header( $r['response'] );
+ }
+ nocache_headers();
+ }
+
+ if ( is_scalar( $message ) ) {
+ $message = (string) $message;
+ } else {
+ $message = '0';
+ }
+
+ if ( $r['exit'] ) {
+ die( $message );
+ }
+
+ echo $message;
+}
+
+/**
+ * Kills WordPress execution and displays JSON response with an error message.
+ *
+ * This is the handler for wp_die() when processing JSON requests.
+ *
+ * @since 5.1.0
+ * @access private
+ *
+ * @param string $message Error message.
+ * @param string $title Optional. Error title. Default empty.
+ * @param string|array $args Optional. Arguments to control behavior. Default empty array.
+ */
+function _json_wp_die_handler( $message, $title = '', $args = array() ) {
+ list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args );
+
+ $data = array(
+ 'code' => $r['code'],
+ 'message' => $message,
+ 'data' => array(
+ 'status' => $r['response'],
+ ),
+ 'additional_errors' => $r['additional_errors'],
+ );
+
+ if ( ! headers_sent() ) {
+ header( 'Content-Type: application/json; charset=utf-8' );
+ if ( null !== $r['response'] ) {
+ status_header( $r['response'] );
+ }
+ nocache_headers();
+ }
+
+ echo wp_json_encode( $data );
+ if ( $r['exit'] ) {
+ die();
+ }
+}
+
+/**
+ * Kills WordPress execution and displays JSONP response with an error message.
+ *
+ * This is the handler for wp_die() when processing JSONP requests.
+ *
+ * @since 5.2.0
+ * @access private
+ *
+ * @param string $message Error message.
+ * @param string $title Optional. Error title. Default empty.
+ * @param string|array $args Optional. Arguments to control behavior. Default empty array.
+ */
+function _jsonp_wp_die_handler( $message, $title = '', $args = array() ) {
+ list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args );
+
+ $data = array(
+ 'code' => $r['code'],
+ 'message' => $message,
+ 'data' => array(
+ 'status' => $r['response'],
+ ),
+ 'additional_errors' => $r['additional_errors'],
+ );
+
+ if ( ! headers_sent() ) {
+ header( 'Content-Type: application/javascript; charset=utf-8' );
+ header( 'X-Content-Type-Options: nosniff' );
+ header( 'X-Robots-Tag: noindex' );
+ if ( null !== $r['response'] ) {
+ status_header( $r['response'] );
+ }
+ nocache_headers();
+ }
+
+ $result = wp_json_encode( $data );
+ $jsonp_callback = $_GET['_jsonp'];
+ echo '/**/' . $jsonp_callback . '(' . $result . ')';
+ if ( $r['exit'] ) {
+ die();
+ }
+}
+
+/**
+ * Kills WordPress execution and displays XML response with an error message.
+ *
+ * This is the handler for wp_die() when processing XMLRPC requests.
*
* @since 3.2.0
* @access private
@@ -2921,58 +3380,170 @@
*/
function _xmlrpc_wp_die_handler( $message, $title = '', $args = array() ) {
global $wp_xmlrpc_server;
- $defaults = array( 'response' => 500 );
-
- $r = wp_parse_args($args, $defaults);
+
+ list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args );
+
+ if ( ! headers_sent() ) {
+ nocache_headers();
+ }
if ( $wp_xmlrpc_server ) {
- $error = new IXR_Error( $r['response'] , $message);
+ $error = new IXR_Error( $r['response'], $message );
$wp_xmlrpc_server->output( $error->getXml() );
}
- die();
-}
-
-/**
- * Kill WordPress ajax execution.
- *
- * This is the handler for wp_die when processing Ajax requests.
- *
- * @since 3.4.0
+ if ( $r['exit'] ) {
+ die();
+ }
+}
+
+/**
+ * Kills WordPress execution and displays XML response with an error message.
+ *
+ * This is the handler for wp_die() when processing XML requests.
+ *
+ * @since 5.2.0
* @access private
*
* @param string $message Error message.
+ * @param string $title Optional. Error title. Default empty.
+ * @param string|array $args Optional. Arguments to control behavior. Default empty array.
+ */
+function _xml_wp_die_handler( $message, $title = '', $args = array() ) {
+ list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args );
+
+ $message = htmlspecialchars( $message );
+ $title = htmlspecialchars( $title );
+
+ $xml = <<<EOD
+<error>
+ <code>{$r['code']}</code>
+ <title><![CDATA[{$title}]]></title>
+ <message><![CDATA[{$message}]]></message>
+ <data>
+ <status>{$r['response']}</status>
+ </data>
+</error>
+
+EOD;
+
+ if ( ! headers_sent() ) {
+ header( 'Content-Type: text/xml; charset=utf-8' );
+ if ( null !== $r['response'] ) {
+ status_header( $r['response'] );
+ }
+ nocache_headers();
+ }
+
+ echo $xml;
+ if ( $r['exit'] ) {
+ die();
+ }
+}
+
+/**
+ * Kills WordPress execution and displays an error message.
+ *
+ * This is the handler for wp_die() when processing APP requests.
+ *
+ * @since 3.4.0
+ * @since 5.1.0 Added the $title and $args parameters.
+ * @access private
+ *
+ * @param string $message Optional. Response to print. Default empty.
* @param string $title Optional. Error title (unused). Default empty.
* @param string|array $args Optional. Arguments to control behavior. Default empty array.
*/
-function _ajax_wp_die_handler( $message, $title = '', $args = array() ) {
+function _scalar_wp_die_handler( $message = '', $title = '', $args = array() ) {
+ list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args );
+
+ if ( $r['exit'] ) {
+ if ( is_scalar( $message ) ) {
+ die( (string) $message );
+ }
+ die();
+ }
+
+ if ( is_scalar( $message ) ) {
+ echo (string) $message;
+ }
+}
+
+/**
+ * Processes arguments passed to wp_die() consistently for its handlers.
+ *
+ * @since 5.1.0
+ * @access private
+ *
+ * @param string $message Error message.
+ * @param string $title Optional. Error title. Default empty.
+ * @param string|array $args Optional. Arguments to control behavior. Default empty array.
+ * @return array List of processed $message string, $title string, and $args array.
+ */
+function _wp_die_process_input( $message, $title = '', $args = array() ) {
$defaults = array(
- 'response' => 200,
+ 'response' => 0,
+ 'code' => '',
+ 'exit' => true,
+ 'back_link' => false,
+ 'link_url' => '',
+ 'link_text' => '',
+ 'text_direction' => '',
+ 'additional_errors' => array(),
);
- $r = wp_parse_args( $args, $defaults );
-
- if ( ! headers_sent() && null !== $r['response'] ) {
- status_header( $r['response'] );
- }
-
- if ( is_scalar( $message ) )
- die( (string) $message );
- die( '0' );
-}
-
-/**
- * Kill WordPress execution.
- *
- * This is the handler for wp_die when processing APP requests.
- *
- * @since 3.4.0
- * @access private
- *
- * @param string $message Optional. Response to print. Default empty.
- */
-function _scalar_wp_die_handler( $message = '' ) {
- if ( is_scalar( $message ) )
- die( (string) $message );
- die();
+
+ $args = wp_parse_args( $args, $defaults );
+
+ if ( function_exists( 'is_wp_error' ) && is_wp_error( $message ) ) {
+ if ( ! empty( $message->errors ) ) {
+ $errors = array();
+ foreach ( (array) $message->errors as $error_code => $error_messages ) {
+ foreach ( (array) $error_messages as $error_message ) {
+ $errors[] = array(
+ 'code' => $error_code,
+ 'message' => $error_message,
+ 'data' => $message->get_error_data( $error_code ),
+ );
+ }
+ }
+
+ $message = $errors[0]['message'];
+ if ( empty( $args['code'] ) ) {
+ $args['code'] = $errors[0]['code'];
+ }
+ if ( empty( $args['response'] ) && is_array( $errors[0]['data'] ) && ! empty( $errors[0]['data']['status'] ) ) {
+ $args['response'] = $errors[0]['data']['status'];
+ }
+ if ( empty( $title ) && is_array( $errors[0]['data'] ) && ! empty( $errors[0]['data']['title'] ) ) {
+ $title = $errors[0]['data']['title'];
+ }
+
+ unset( $errors[0] );
+ $args['additional_errors'] = array_values( $errors );
+ } else {
+ $message = '';
+ }
+ }
+
+ $have_gettext = function_exists( '__' );
+
+ // The $title and these specific $args must always have a non-empty value.
+ if ( empty( $args['code'] ) ) {
+ $args['code'] = 'wp_die';
+ }
+ if ( empty( $args['response'] ) ) {
+ $args['response'] = 500;
+ }
+ if ( empty( $title ) ) {
+ $title = $have_gettext ? __( 'WordPress › Error' ) : 'WordPress › Error';
+ }
+ if ( empty( $args['text_direction'] ) || ! in_array( $args['text_direction'], array( 'ltr', 'rtl' ), true ) ) {
+ $args['text_direction'] = 'ltr';
+ if ( function_exists( 'is_rtl' ) && is_rtl() ) {
+ $args['text_direction'] = 'rtl';
+ }
+ }
+
+ return array( $message, $title, $args );
}
/**
@@ -3008,7 +3579,7 @@
// If json_encode() was successful, no need to do more sanity checking.
// ... unless we're in an old version of PHP, and json_encode() returned
// a string containing 'null'. Then we need to do more sanity checking.
- if ( false !== $json && ( version_compare( PHP_VERSION, '5.5', '>=' ) || false === strpos( $json, 'null' ) ) ) {
+ if ( false !== $json && ( version_compare( PHP_VERSION, '5.5', '>=' ) || false === strpos( $json, 'null' ) ) ) {
return $json;
}
@@ -3184,9 +3755,13 @@
echo wp_json_encode( $response );
if ( wp_doing_ajax() ) {
- wp_die( '', '', array(
- 'response' => null,
- ) );
+ wp_die(
+ '',
+ '',
+ array(
+ 'response' => null,
+ )
+ );
} else {
die;
}
@@ -3204,8 +3779,9 @@
function wp_send_json_success( $data = null, $status_code = null ) {
$response = array( 'success' => true );
- if ( isset( $data ) )
+ if ( isset( $data ) ) {
$response['data'] = $data;
+ }
wp_send_json( $response, $status_code );
}
@@ -3233,7 +3809,10 @@
$result = array();
foreach ( $data->errors as $code => $messages ) {
foreach ( $messages as $message ) {
- $result[] = array( 'code' => $code, 'message' => $message );
+ $result[] = array(
+ 'code' => $code,
+ 'message' => $message,
+ );
}
}
@@ -3284,8 +3863,9 @@
* @return string Homepage location.
*/
function _config_wp_home( $url = '' ) {
- if ( defined( 'WP_HOME' ) )
+ if ( defined( 'WP_HOME' ) ) {
return untrailingslashit( WP_HOME );
+ }
return $url;
}
@@ -3305,8 +3885,9 @@
* @return string The WordPress Site URL.
*/
function _config_wp_siteurl( $url = '' ) {
- if ( defined( 'WP_SITEURL' ) )
+ if ( defined( 'WP_SITEURL' ) ) {
return untrailingslashit( WP_SITEURL );
+ }
return $url;
}
@@ -3340,7 +3921,7 @@
function _mce_set_direction( $mce_init ) {
if ( is_rtl() ) {
$mce_init['directionality'] = 'rtl';
- $mce_init['rtl_ui'] = true;
+ $mce_init['rtl_ui'] = true;
if ( ! empty( $mce_init['plugins'] ) && strpos( $mce_init['plugins'], 'directionality' ) === false ) {
$mce_init['plugins'] .= ',directionality';
@@ -3381,56 +3962,57 @@
global $wpsmiliestrans, $wp_smiliessearch;
// don't bother setting up smilies if they are disabled
- if ( !get_option( 'use_smilies' ) )
+ if ( ! get_option( 'use_smilies' ) ) {
return;
-
- if ( !isset( $wpsmiliestrans ) ) {
+ }
+
+ if ( ! isset( $wpsmiliestrans ) ) {
$wpsmiliestrans = array(
- ':mrgreen:' => 'mrgreen.png',
- ':neutral:' => "\xf0\x9f\x98\x90",
- ':twisted:' => "\xf0\x9f\x98\x88",
- ':arrow:' => "\xe2\x9e\xa1",
- ':shock:' => "\xf0\x9f\x98\xaf",
- ':smile:' => "\xf0\x9f\x99\x82",
- ':???:' => "\xf0\x9f\x98\x95",
- ':cool:' => "\xf0\x9f\x98\x8e",
- ':evil:' => "\xf0\x9f\x91\xbf",
- ':grin:' => "\xf0\x9f\x98\x80",
- ':idea:' => "\xf0\x9f\x92\xa1",
- ':oops:' => "\xf0\x9f\x98\xb3",
- ':razz:' => "\xf0\x9f\x98\x9b",
- ':roll:' => "\xf0\x9f\x99\x84",
- ':wink:' => "\xf0\x9f\x98\x89",
- ':cry:' => "\xf0\x9f\x98\xa5",
- ':eek:' => "\xf0\x9f\x98\xae",
- ':lol:' => "\xf0\x9f\x98\x86",
- ':mad:' => "\xf0\x9f\x98\xa1",
- ':sad:' => "\xf0\x9f\x99\x81",
- '8-)' => "\xf0\x9f\x98\x8e",
- '8-O' => "\xf0\x9f\x98\xaf",
- ':-(' => "\xf0\x9f\x99\x81",
- ':-)' => "\xf0\x9f\x99\x82",
- ':-?' => "\xf0\x9f\x98\x95",
- ':-D' => "\xf0\x9f\x98\x80",
- ':-P' => "\xf0\x9f\x98\x9b",
- ':-o' => "\xf0\x9f\x98\xae",
- ':-x' => "\xf0\x9f\x98\xa1",
- ':-|' => "\xf0\x9f\x98\x90",
- ';-)' => "\xf0\x9f\x98\x89",
- // This one transformation breaks regular text with frequency.
- // '8)' => "\xf0\x9f\x98\x8e",
- '8O' => "\xf0\x9f\x98\xaf",
- ':(' => "\xf0\x9f\x99\x81",
- ':)' => "\xf0\x9f\x99\x82",
- ':?' => "\xf0\x9f\x98\x95",
- ':D' => "\xf0\x9f\x98\x80",
- ':P' => "\xf0\x9f\x98\x9b",
- ':o' => "\xf0\x9f\x98\xae",
- ':x' => "\xf0\x9f\x98\xa1",
- ':|' => "\xf0\x9f\x98\x90",
- ';)' => "\xf0\x9f\x98\x89",
- ':!:' => "\xe2\x9d\x97",
- ':?:' => "\xe2\x9d\x93",
+ ':mrgreen:' => 'mrgreen.png',
+ ':neutral:' => "\xf0\x9f\x98\x90",
+ ':twisted:' => "\xf0\x9f\x98\x88",
+ ':arrow:' => "\xe2\x9e\xa1",
+ ':shock:' => "\xf0\x9f\x98\xaf",
+ ':smile:' => "\xf0\x9f\x99\x82",
+ ':???:' => "\xf0\x9f\x98\x95",
+ ':cool:' => "\xf0\x9f\x98\x8e",
+ ':evil:' => "\xf0\x9f\x91\xbf",
+ ':grin:' => "\xf0\x9f\x98\x80",
+ ':idea:' => "\xf0\x9f\x92\xa1",
+ ':oops:' => "\xf0\x9f\x98\xb3",
+ ':razz:' => "\xf0\x9f\x98\x9b",
+ ':roll:' => "\xf0\x9f\x99\x84",
+ ':wink:' => "\xf0\x9f\x98\x89",
+ ':cry:' => "\xf0\x9f\x98\xa5",
+ ':eek:' => "\xf0\x9f\x98\xae",
+ ':lol:' => "\xf0\x9f\x98\x86",
+ ':mad:' => "\xf0\x9f\x98\xa1",
+ ':sad:' => "\xf0\x9f\x99\x81",
+ '8-)' => "\xf0\x9f\x98\x8e",
+ '8-O' => "\xf0\x9f\x98\xaf",
+ ':-(' => "\xf0\x9f\x99\x81",
+ ':-)' => "\xf0\x9f\x99\x82",
+ ':-?' => "\xf0\x9f\x98\x95",
+ ':-D' => "\xf0\x9f\x98\x80",
+ ':-P' => "\xf0\x9f\x98\x9b",
+ ':-o' => "\xf0\x9f\x98\xae",
+ ':-x' => "\xf0\x9f\x98\xa1",
+ ':-|' => "\xf0\x9f\x98\x90",
+ ';-)' => "\xf0\x9f\x98\x89",
+ // This one transformation breaks regular text with frequency.
+ // '8)' => "\xf0\x9f\x98\x8e",
+ '8O' => "\xf0\x9f\x98\xaf",
+ ':(' => "\xf0\x9f\x99\x81",
+ ':)' => "\xf0\x9f\x99\x82",
+ ':?' => "\xf0\x9f\x98\x95",
+ ':D' => "\xf0\x9f\x98\x80",
+ ':P' => "\xf0\x9f\x98\x9b",
+ ':o' => "\xf0\x9f\x98\xae",
+ ':x' => "\xf0\x9f\x98\xa1",
+ ':|' => "\xf0\x9f\x98\x90",
+ ';)' => "\xf0\x9f\x98\x89",
+ ':!:' => "\xe2\x9d\x97",
+ ':?:' => "\xe2\x9d\x93",
);
}
@@ -3444,9 +4026,9 @@
*
* @param array $wpsmiliestrans List of the smilies.
*/
- $wpsmiliestrans = apply_filters('smilies', $wpsmiliestrans);
-
- if (count($wpsmiliestrans) == 0) {
+ $wpsmiliestrans = apply_filters( 'smilies', $wpsmiliestrans );
+
+ if ( count( $wpsmiliestrans ) == 0 ) {
return;
}
@@ -3455,7 +4037,7 @@
* we match the longest possible smilie (:???: vs :?) as the regular
* expression used below is first-match
*/
- krsort($wpsmiliestrans);
+ krsort( $wpsmiliestrans );
$spaces = wp_spaces_regexp();
@@ -3464,21 +4046,21 @@
$subchar = '';
foreach ( (array) $wpsmiliestrans as $smiley => $img ) {
- $firstchar = substr($smiley, 0, 1);
- $rest = substr($smiley, 1);
+ $firstchar = substr( $smiley, 0, 1 );
+ $rest = substr( $smiley, 1 );
// new subpattern?
- if ($firstchar != $subchar) {
- if ($subchar != '') {
+ if ( $firstchar != $subchar ) {
+ if ( $subchar != '' ) {
$wp_smiliessearch .= ')(?=' . $spaces . '|$)'; // End previous "subpattern"
$wp_smiliessearch .= '|(?<=' . $spaces . '|^)'; // Begin another "subpattern"
}
- $subchar = $firstchar;
- $wp_smiliessearch .= preg_quote($firstchar, '/') . '(?:';
+ $subchar = $firstchar;
+ $wp_smiliessearch .= preg_quote( $firstchar, '/' ) . '(?:';
} else {
$wp_smiliessearch .= '|';
}
- $wp_smiliessearch .= preg_quote($rest, '/');
+ $wp_smiliessearch .= preg_quote( $rest, '/' );
}
$wp_smiliessearch .= ')(?=' . $spaces . '|$)/m';
@@ -3499,19 +4081,37 @@
* @return array Merged user defined values with defaults.
*/
function wp_parse_args( $args, $defaults = '' ) {
- if ( is_object( $args ) )
+ if ( is_object( $args ) ) {
$r = get_object_vars( $args );
- elseif ( is_array( $args ) )
+ } elseif ( is_array( $args ) ) {
$r =& $args;
- else
+ } else {
wp_parse_str( $args, $r );
-
- if ( is_array( $defaults ) )
+ }
+
+ if ( is_array( $defaults ) ) {
return array_merge( $defaults, $r );
+ }
return $r;
}
/**
+ * Cleans up an array, comma- or space-separated list of scalar values.
+ *
+ * @since 5.1.0
+ *
+ * @param array|string $list List of values.
+ * @return array Sanitized array of values.
+ */
+function wp_parse_list( $list ) {
+ if ( ! is_array( $list ) ) {
+ return preg_split( '/[\s,]+/', $list, -1, PREG_SPLIT_NO_EMPTY );
+ }
+
+ return $list;
+}
+
+/**
* Clean up an array, comma- or space-separated list of IDs.
*
* @since 3.0.0
@@ -3520,10 +4120,9 @@
* @return array Sanitized array of IDs.
*/
function wp_parse_id_list( $list ) {
- if ( !is_array($list) )
- $list = preg_split('/[\s,]+/', $list);
-
- return array_unique(array_map('absint', $list));
+ $list = wp_parse_list( $list );
+
+ return array_unique( array_map( 'absint', $list ) );
}
/**
@@ -3535,15 +4134,9 @@
* @return array Sanitized array of slugs.
*/
function wp_parse_slug_list( $list ) {
- if ( ! is_array( $list ) ) {
- $list = preg_split( '/[\s,]+/', $list );
- }
-
- foreach ( $list as $key => $value ) {
- $list[ $key ] = sanitize_title( $value );
- }
-
- return array_unique( $list );
+ $list = wp_parse_list( $list );
+
+ return array_unique( array_map( 'sanitize_title', $list ) );
}
/**
@@ -3557,9 +4150,11 @@
*/
function wp_array_slice_assoc( $array, $keys ) {
$slice = array();
- foreach ( $keys as $key )
- if ( isset( $array[ $key ] ) )
+ foreach ( $keys as $key ) {
+ if ( isset( $array[ $key ] ) ) {
$slice[ $key ] = $array[ $key ];
+ }
+ }
return $slice;
}
@@ -3577,7 +4172,7 @@
return false;
}
- $keys = array_keys( $data );
+ $keys = array_keys( $data );
$string_keys = array_filter( $keys, 'is_string' );
return count( $string_keys ) === 0;
}
@@ -3586,7 +4181,7 @@
* Filters a list of objects, based on a set of key => value arguments.
*
* @since 3.0.0
- * @since 4.7.0 Uses WP_List_Util class.
+ * @since 4.7.0 Uses `WP_List_Util` class.
*
* @param array $list An array of objects to filter
* @param array $args Optional. An array of key => value arguments to match
@@ -3619,7 +4214,7 @@
* Filters a list of objects, based on a set of key => value arguments.
*
* @since 3.1.0
- * @since 4.7.0 Uses WP_List_Util class.
+ * @since 4.7.0 Uses `WP_List_Util` class.
*
* @param array $list An array of objects to filter.
* @param array $args Optional. An array of key => value arguments to match
@@ -3647,7 +4242,7 @@
*
* @since 3.1.0
* @since 4.0.0 $index_key parameter added.
- * @since 4.7.0 Uses WP_List_Util class.
+ * @since 4.7.0 Uses `WP_List_Util` class.
*
* @param array $list List of objects or arrays
* @param int|string $field Field from the object to place instead of the entire object
@@ -3667,7 +4262,7 @@
*
* @since 4.7.0
*
- * @param array $list An array of objects to filter.
+ * @param array $list An array of objects to sort.
* @param string|array $orderby Optional. Either the field name to order by or an array
* of multiple orderby fields as $orderby => $order.
* @param string $order Optional. Either 'ASC' or 'DESC'. Only used if $orderby
@@ -3723,8 +4318,9 @@
function wp_widgets_add_menu() {
global $submenu;
- if ( ! current_theme_supports( 'widgets' ) )
+ if ( ! current_theme_supports( 'widgets' ) ) {
return;
+ }
$submenu['themes.php'][7] = array( __( 'Widgets' ), 'edit_theme_options', 'widgets.php' );
ksort( $submenu['themes.php'], SORT_NUMERIC );
@@ -3739,8 +4335,9 @@
*/
function wp_ob_end_flush_all() {
$levels = ob_get_level();
- for ($i=0; $i<$levels; $i++)
+ for ( $i = 0; $i < $levels; $i++ ) {
ob_end_flush();
+ }
}
/**
@@ -3773,27 +4370,12 @@
}
// If installing or in the admin, provide the verbose message.
- if ( wp_installing() || defined( 'WP_ADMIN' ) )
- wp_die($wpdb->error);
+ if ( wp_installing() || defined( 'WP_ADMIN' ) ) {
+ wp_die( $wpdb->error );
+ }
// Otherwise, be terse.
- status_header( 500 );
- nocache_headers();
- header( 'Content-Type: text/html; charset=utf-8' );
-?>
-<!DOCTYPE html>
-<html xmlns="http://www.w3.org/1999/xhtml"<?php if ( is_rtl() ) echo ' dir="rtl"'; ?>>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title><?php _e( 'Database Error' ); ?></title>
-
-</head>
-<body>
- <h1><?php _e( 'Error establishing a database connection' ); ?></h1>
-</body>
-</html>
-<?php
- die();
+ wp_die( '<h1>' . __( 'Error establishing a database connection' ) . '</h1>', __( 'Database Error' ) );
}
/**
@@ -3850,10 +4432,10 @@
if ( function_exists( '__' ) ) {
if ( ! is_null( $replacement ) ) {
/* translators: 1: PHP function name, 2: version number, 3: alternative function name */
- trigger_error( sprintf( __('%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.'), $function, $version, $replacement ) );
+ trigger_error( sprintf( __( '%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ), $function, $version, $replacement ) );
} else {
/* translators: 1: PHP function name, 2: version number */
- trigger_error( sprintf( __('%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.'), $function, $version ) );
+ trigger_error( sprintf( __( '%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.' ), $function, $version ) );
}
} else {
if ( ! is_null( $replacement ) ) {
@@ -3912,20 +4494,46 @@
if ( function_exists( '__' ) ) {
if ( ! empty( $parent_class ) ) {
/* translators: 1: PHP class name, 2: PHP parent class name, 3: version number, 4: __construct() method */
- 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.' ),
- $class, $parent_class, $version, '<pre>__construct()</pre>' ) );
+ 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.' ),
+ $class,
+ $parent_class,
+ $version,
+ '<pre>__construct()</pre>'
+ )
+ );
} else {
/* translators: 1: PHP class name, 2: version number, 3: __construct() method */
- trigger_error( sprintf( __( 'The called constructor method for %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ),
- $class, $version, '<pre>__construct()</pre>' ) );
+ trigger_error(
+ sprintf(
+ __( 'The called constructor method for %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ),
+ $class,
+ $version,
+ '<pre>__construct()</pre>'
+ )
+ );
}
} else {
if ( ! empty( $parent_class ) ) {
- 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.',
- $class, $parent_class, $version, '<pre>__construct()</pre>' ) );
+ 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.',
+ $class,
+ $parent_class,
+ $version,
+ '<pre>__construct()</pre>'
+ )
+ );
} else {
- trigger_error( sprintf( 'The called constructor method for %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.',
- $class, $version, '<pre>__construct()</pre>' ) );
+ trigger_error(
+ sprintf(
+ 'The called constructor method for %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.',
+ $class,
+ $version,
+ '<pre>__construct()</pre>'
+ )
+ );
}
}
}
@@ -3978,10 +4586,10 @@
if ( function_exists( '__' ) ) {
if ( ! is_null( $replacement ) ) {
/* translators: 1: PHP file name, 2: version number, 3: alternative file name */
- trigger_error( sprintf( __('%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.'), $file, $version, $replacement ) . $message );
+ trigger_error( sprintf( __( '%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ), $file, $version, $replacement ) . $message );
} else {
/* translators: 1: PHP file name, 2: version number */
- trigger_error( sprintf( __('%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.'), $file, $version ) . $message );
+ trigger_error( sprintf( __( '%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.' ), $file, $version ) . $message );
}
} else {
if ( ! is_null( $replacement ) ) {
@@ -4004,7 +4612,6 @@
* _deprecated_argument( __FUNCTION__, '3.0.0' );
* }
*
- *
* There is a hook deprecated_argument_run that will be called that can be used
* to get the backtrace up to what file and function used the deprecated
* argument.
@@ -4042,10 +4649,10 @@
if ( function_exists( '__' ) ) {
if ( ! is_null( $message ) ) {
/* translators: 1: PHP function name, 2: version number, 3: optional message regarding the change */
- trigger_error( sprintf( __('%1$s was called with an argument that is <strong>deprecated</strong> since version %2$s! %3$s'), $function, $version, $message ) );
+ trigger_error( sprintf( __( '%1$s was called with an argument that is <strong>deprecated</strong> since version %2$s! %3$s' ), $function, $version, $message ) );
} else {
/* translators: 1: PHP function name, 2: version number */
- 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 ) );
+ 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 ) );
}
} else {
if ( ! is_null( $message ) ) {
@@ -4142,10 +4749,14 @@
* Filters whether to trigger an error for _doing_it_wrong() calls.
*
* @since 3.1.0
+ * @since 5.1.0 Added the $function, $message and $version parameters.
*
- * @param bool $trigger Whether to trigger the error for _doing_it_wrong() calls. Default true.
+ * @param bool $trigger Whether to trigger the error for _doing_it_wrong() calls. Default true.
+ * @param string $function The function that was called.
+ * @param string $message A message explaining what has been done incorrectly.
+ * @param string $version The version of WordPress where the message was added.
*/
- if ( WP_DEBUG && apply_filters( 'doing_it_wrong_trigger_error', true ) ) {
+ if ( WP_DEBUG && apply_filters( 'doing_it_wrong_trigger_error', true, $function, $message, $version ) ) {
if ( function_exists( '__' ) ) {
if ( is_null( $version ) ) {
$version = '';
@@ -4154,7 +4765,8 @@
$version = sprintf( __( '(This message was added in version %s.)' ), $version );
}
/* translators: %s: Codex URL */
- $message .= ' ' . sprintf( __( 'Please see <a href="%s">Debugging in WordPress</a> for more information.' ),
+ $message .= ' ' . sprintf(
+ __( 'Please see <a href="%s">Debugging in WordPress</a> for more information.' ),
__( 'https://codex.wordpress.org/Debugging_in_WordPress' )
);
/* translators: Developer debugging message. 1: PHP function name, 2: Explanatory message, 3: Version information message */
@@ -4165,7 +4777,8 @@
} else {
$version = sprintf( '(This message was added in version %s.)', $version );
}
- $message .= sprintf( ' Please see <a href="%s">Debugging in WordPress</a> for more information.',
+ $message .= sprintf(
+ ' Please see <a href="%s">Debugging in WordPress</a> for more information.',
'https://codex.wordpress.org/Debugging_in_WordPress'
);
trigger_error( sprintf( '%1$s was called <strong>incorrectly</strong>. %2$s %3$s', $function, $message, $version ) );
@@ -4181,8 +4794,8 @@
* @return bool Whether the server is running lighttpd < 1.5.0.
*/
function is_lighttpd_before_150() {
- $server_parts = explode( '/', isset( $_SERVER['SERVER_SOFTWARE'] )? $_SERVER['SERVER_SOFTWARE'] : '' );
- $server_parts[1] = isset( $server_parts[1] )? $server_parts[1] : '';
+ $server_parts = explode( '/', isset( $_SERVER['SERVER_SOFTWARE'] ) ? $_SERVER['SERVER_SOFTWARE'] : '' );
+ $server_parts[1] = isset( $server_parts[1] ) ? $server_parts[1] : '';
return 'lighttpd' == $server_parts[0] && -1 == version_compare( $server_parts[1], '1.5.0' );
}
@@ -4197,22 +4810,25 @@
* @param bool $default Optional. The default return value if the module is not found. Default false.
* @return bool Whether the specified module is loaded.
*/
-function apache_mod_loaded($mod, $default = false) {
+function apache_mod_loaded( $mod, $default = false ) {
global $is_apache;
- if ( !$is_apache )
+ if ( ! $is_apache ) {
return false;
+ }
if ( function_exists( 'apache_get_modules' ) ) {
$mods = apache_get_modules();
- if ( in_array($mod, $mods) )
+ if ( in_array( $mod, $mods ) ) {
return true;
+ }
} elseif ( function_exists( 'phpinfo' ) && false === strpos( ini_get( 'disable_functions' ), 'phpinfo' ) ) {
ob_start();
- phpinfo(8);
+ phpinfo( 8 );
$phpinfo = ob_get_clean();
- if ( false !== strpos($phpinfo, $mod) )
- return true;
+ if ( false !== strpos( $phpinfo, $mod ) ) {
+ return true;
+ }
}
return $default;
}
@@ -4240,7 +4856,7 @@
* Lastly we make sure that PHP is running via FastCGI. This is important because if it runs
* via ISAPI then pretty permalinks will not work.
*/
- $supports_permalinks = class_exists( 'DOMDocument', false ) && isset($_SERVER['IIS_UrlRewriteModule']) && ( PHP_SAPI == 'cgi-fcgi' );
+ $supports_permalinks = class_exists( 'DOMDocument', false ) && isset( $_SERVER['IIS_UrlRewriteModule'] ) && ( PHP_SAPI == 'cgi-fcgi' );
}
/**
@@ -4285,12 +4901,14 @@
}
// Files not in the allowed file list are not allowed:
- if ( ! empty( $allowed_files ) && ! in_array( $file, $allowed_files ) )
+ if ( ! empty( $allowed_files ) && ! in_array( $file, $allowed_files ) ) {
return 3;
+ }
// Absolute Windows drive paths are not allowed:
- if (':' == substr( $file, 1, 1 ) )
+ if ( ':' == substr( $file, 1, 1 ) ) {
return 2;
+ }
return 0;
}
@@ -4308,9 +4926,9 @@
function force_ssl_admin( $force = null ) {
static $forced = false;
- if ( !is_null( $force ) ) {
+ if ( ! is_null( $force ) ) {
$old_forced = $forced;
- $forced = $force;
+ $forced = $force;
return $old_forced;
}
@@ -4328,17 +4946,17 @@
* @return string The guessed URL.
*/
function wp_guess_url() {
- if ( defined('WP_SITEURL') && '' != WP_SITEURL ) {
+ if ( defined( 'WP_SITEURL' ) && '' != WP_SITEURL ) {
$url = WP_SITEURL;
} else {
- $abspath_fix = str_replace( '\\', '/', ABSPATH );
+ $abspath_fix = str_replace( '\\', '/', ABSPATH );
$script_filename_dir = dirname( $_SERVER['SCRIPT_FILENAME'] );
// The request is for the admin
if ( strpos( $_SERVER['REQUEST_URI'], 'wp-admin' ) !== false || strpos( $_SERVER['REQUEST_URI'], 'wp-login.php' ) !== false ) {
$path = preg_replace( '#/(wp-admin/.*|wp-login.php)#i', '', $_SERVER['REQUEST_URI'] );
- // The request is for a file in ABSPATH
+ // The request is for a file in ABSPATH
} elseif ( $script_filename_dir . '/' == $abspath_fix ) {
// Strip off any file/query params in the path
$path = preg_replace( '#/[^/]*$#i', '', $_SERVER['PHP_SELF'] );
@@ -4348,22 +4966,22 @@
// Request is hitting a file inside ABSPATH
$directory = str_replace( ABSPATH, '', $script_filename_dir );
// Strip off the sub directory, and any file/query params
- $path = preg_replace( '#/' . preg_quote( $directory, '#' ) . '/[^/]*$#i', '' , $_SERVER['REQUEST_URI'] );
+ $path = preg_replace( '#/' . preg_quote( $directory, '#' ) . '/[^/]*$#i', '', $_SERVER['REQUEST_URI'] );
} elseif ( false !== strpos( $abspath_fix, $script_filename_dir ) ) {
// Request is hitting a file above ABSPATH
$subdirectory = substr( $abspath_fix, strpos( $abspath_fix, $script_filename_dir ) + strlen( $script_filename_dir ) );
// Strip off any file/query params from the path, appending the sub directory to the installation
- $path = preg_replace( '#/[^/]*$#i', '' , $_SERVER['REQUEST_URI'] ) . $subdirectory;
+ $path = preg_replace( '#/[^/]*$#i', '', $_SERVER['REQUEST_URI'] ) . $subdirectory;
} else {
$path = $_SERVER['REQUEST_URI'];
}
}
$schema = is_ssl() ? 'https://' : 'http://'; // set_url_scheme() is not defined yet
- $url = $schema . $_SERVER['HTTP_HOST'] . $path;
- }
-
- return rtrim($url, '/');
+ $url = $schema . $_SERVER['HTTP_HOST'] . $path;
+ }
+
+ return rtrim( $url, '/' );
}
/**
@@ -4386,8 +5004,9 @@
function wp_suspend_cache_addition( $suspend = null ) {
static $_suspend = false;
- if ( is_bool( $suspend ) )
+ if ( is_bool( $suspend ) ) {
$_suspend = $suspend;
+ }
return $_suspend;
}
@@ -4409,7 +5028,7 @@
function wp_suspend_cache_invalidation( $suspend = true ) {
global $_wp_suspend_cache_invalidation;
- $current_suspend = $_wp_suspend_cache_invalidation;
+ $current_suspend = $_wp_suspend_cache_invalidation;
$_wp_suspend_cache_invalidation = $suspend;
return $current_suspend;
}
@@ -4418,7 +5037,7 @@
* Determine whether a site is the main site of the current network.
*
* @since 3.0.0
- * @since 4.9.0 The $network_id parameter has been added.
+ * @since 4.9.0 The `$network_id` parameter was added.
*
* @param int $site_id Optional. Site ID to test. Defaults to current site.
* @param int $network_id Optional. Network ID of the network to check for.
@@ -4504,7 +5123,12 @@
// If the current network has an ID of 1, assume it is the main network.
$main_network_id = 1;
} else {
- $_networks = get_networks( array( 'fields' => 'ids', 'number' => 1 ) );
+ $_networks = get_networks(
+ array(
+ 'fields' => 'ids',
+ 'number' => 1,
+ )
+ );
$main_network_id = array_shift( $_networks );
}
@@ -4528,8 +5152,9 @@
* @return bool True if multisite and global terms enabled.
*/
function global_terms_enabled() {
- if ( ! is_multisite() )
+ if ( ! is_multisite() ) {
return false;
+ }
static $global_terms = null;
if ( is_null( $global_terms ) ) {
@@ -4545,15 +5170,48 @@
* @param null $enabled Whether global terms are enabled.
*/
$filter = apply_filters( 'global_terms_enabled', null );
- if ( ! is_null( $filter ) )
+ if ( ! is_null( $filter ) ) {
$global_terms = (bool) $filter;
- else
+ } else {
$global_terms = (bool) get_site_option( 'global_terms_enabled', false );
+ }
}
return $global_terms;
}
/**
+ * Determines whether site meta is enabled.
+ *
+ * This function checks whether the 'blogmeta' database table exists. The result is saved as
+ * a setting for the main network, making it essentially a global setting. Subsequent requests
+ * will refer to this setting instead of running the query.
+ *
+ * @since 5.1.0
+ *
+ * @global wpdb $wpdb WordPress database abstraction object.
+ *
+ * @return bool True if site meta is supported, false otherwise.
+ */
+function is_site_meta_supported() {
+ global $wpdb;
+
+ if ( ! is_multisite() ) {
+ return false;
+ }
+
+ $network_id = get_main_network_id();
+
+ $supported = get_network_option( $network_id, 'site_meta_supported', false );
+ if ( false === $supported ) {
+ $supported = $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->blogmeta}'" ) ? 1 : 0;
+
+ update_network_option( $network_id, 'site_meta_supported', $supported );
+ }
+
+ return (bool) $supported;
+}
+
+/**
* gmt_offset modification for smart timezone handling.
*
* Overrides the gmt_offset option if we have a timezone_string available.
@@ -4563,7 +5221,7 @@
* @return float|false Timezone GMT offset, false otherwise.
*/
function wp_timezone_override_offset() {
- if ( !$timezone_string = get_option( 'timezone_string' ) ) {
+ if ( ! $timezone_string = get_option( 'timezone_string' ) ) {
return false;
}
@@ -4639,12 +5297,12 @@
function wp_timezone_choice( $selected_zone, $locale = null ) {
static $mo_loaded = false, $locale_loaded = null;
- $continents = array( 'Africa', 'America', 'Antarctica', 'Arctic', 'Asia', 'Atlantic', 'Australia', 'Europe', 'Indian', 'Pacific');
+ $continents = array( 'Africa', 'America', 'Antarctica', 'Arctic', 'Asia', 'Atlantic', 'Australia', 'Europe', 'Indian', 'Pacific' );
// Load translations for continents and cities.
if ( ! $mo_loaded || $locale !== $locale_loaded ) {
$locale_loaded = $locale ? $locale : get_locale();
- $mofile = WP_LANG_DIR . '/continents-cities-' . $locale_loaded . '.mo';
+ $mofile = WP_LANG_DIR . '/continents-cities-' . $locale_loaded . '.mo';
unload_textdomain( 'continents-cities' );
load_textdomain( 'continents-cities', $mofile );
$mo_loaded = true;
@@ -4653,12 +5311,12 @@
$zonen = array();
foreach ( timezone_identifiers_list() as $zone ) {
$zone = explode( '/', $zone );
- if ( !in_array( $zone[0], $continents ) ) {
+ if ( ! in_array( $zone[0], $continents ) ) {
continue;
}
// This determines what gets set and translated - we don't translate Etc/* strings here, they are done later
- $exists = array(
+ $exists = array(
0 => ( isset( $zone[0] ) && $zone[0] ),
1 => ( isset( $zone[1] ) && $zone[1] ),
2 => ( isset( $zone[2] ) && $zone[2] ),
@@ -4667,14 +5325,16 @@
$exists[4] = ( $exists[1] && $exists[3] );
$exists[5] = ( $exists[2] && $exists[3] );
+ // phpcs:disable WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText
$zonen[] = array(
'continent' => ( $exists[0] ? $zone[0] : '' ),
'city' => ( $exists[1] ? $zone[1] : '' ),
'subcity' => ( $exists[2] ? $zone[2] : '' ),
't_continent' => ( $exists[3] ? translate( str_replace( '_', ' ', $zone[0] ), 'continents-cities' ) : '' ),
't_city' => ( $exists[4] ? translate( str_replace( '_', ' ', $zone[1] ), 'continents-cities' ) : '' ),
- 't_subcity' => ( $exists[5] ? translate( str_replace( '_', ' ', $zone[2] ), 'continents-cities' ) : '' )
+ 't_subcity' => ( $exists[5] ? translate( str_replace( '_', ' ', $zone[2] ), 'continents-cities' ) : '' ),
);
+ // phpcs:enable
}
usort( $zonen, '_wp_timezone_choice_usort_callback' );
@@ -4695,62 +5355,120 @@
// It's inside a continent group
// Continent optgroup
- if ( !isset( $zonen[$key - 1] ) || $zonen[$key - 1]['continent'] !== $zone['continent'] ) {
- $label = $zone['t_continent'];
- $structure[] = '<optgroup label="'. esc_attr( $label ) .'">';
+ if ( ! isset( $zonen[ $key - 1 ] ) || $zonen[ $key - 1 ]['continent'] !== $zone['continent'] ) {
+ $label = $zone['t_continent'];
+ $structure[] = '<optgroup label="' . esc_attr( $label ) . '">';
}
// Add the city to the value
$value[] = $zone['city'];
$display = $zone['t_city'];
- if ( !empty( $zone['subcity'] ) ) {
+ if ( ! empty( $zone['subcity'] ) ) {
// Add the subcity to the value
- $value[] = $zone['subcity'];
+ $value[] = $zone['subcity'];
$display .= ' - ' . $zone['t_subcity'];
}
}
// Build the value
- $value = join( '/', $value );
+ $value = join( '/', $value );
$selected = '';
if ( $value === $selected_zone ) {
$selected = 'selected="selected" ';
}
- $structure[] = '<option ' . $selected . 'value="' . esc_attr( $value ) . '">' . esc_html( $display ) . "</option>";
+ $structure[] = '<option ' . $selected . 'value="' . esc_attr( $value ) . '">' . esc_html( $display ) . '</option>';
// Close continent optgroup
- if ( !empty( $zone['city'] ) && ( !isset($zonen[$key + 1]) || (isset( $zonen[$key + 1] ) && $zonen[$key + 1]['continent'] !== $zone['continent']) ) ) {
+ if ( ! empty( $zone['city'] ) && ( ! isset( $zonen[ $key + 1 ] ) || ( isset( $zonen[ $key + 1 ] ) && $zonen[ $key + 1 ]['continent'] !== $zone['continent'] ) ) ) {
$structure[] = '</optgroup>';
}
}
// Do UTC
- $structure[] = '<optgroup label="'. esc_attr__( 'UTC' ) .'">';
- $selected = '';
- if ( 'UTC' === $selected_zone )
+ $structure[] = '<optgroup label="' . esc_attr__( 'UTC' ) . '">';
+ $selected = '';
+ if ( 'UTC' === $selected_zone ) {
$selected = 'selected="selected" ';
- $structure[] = '<option ' . $selected . 'value="' . esc_attr( 'UTC' ) . '">' . __('UTC') . '</option>';
+ }
+ $structure[] = '<option ' . $selected . 'value="' . esc_attr( 'UTC' ) . '">' . __( 'UTC' ) . '</option>';
$structure[] = '</optgroup>';
// Do manual UTC offsets
- $structure[] = '<optgroup label="'. esc_attr__( 'Manual Offsets' ) .'">';
- $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,
- 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);
+ $structure[] = '<optgroup label="' . esc_attr__( 'Manual Offsets' ) . '">';
+ $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,
+ 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,
+ );
foreach ( $offset_range as $offset ) {
- if ( 0 <= $offset )
+ if ( 0 <= $offset ) {
$offset_name = '+' . $offset;
- else
+ } else {
$offset_name = (string) $offset;
+ }
$offset_value = $offset_name;
- $offset_name = str_replace(array('.25','.5','.75'), array(':15',':30',':45'), $offset_name);
- $offset_name = 'UTC' . $offset_name;
+ $offset_name = str_replace( array( '.25', '.5', '.75' ), array( ':15', ':30', ':45' ), $offset_name );
+ $offset_name = 'UTC' . $offset_name;
$offset_value = 'UTC' . $offset_value;
- $selected = '';
- if ( $offset_value === $selected_zone )
+ $selected = '';
+ if ( $offset_value === $selected_zone ) {
$selected = 'selected="selected" ';
- $structure[] = '<option ' . $selected . 'value="' . esc_attr( $offset_value ) . '">' . esc_html( $offset_name ) . "</option>";
+ }
+ $structure[] = '<option ' . $selected . 'value="' . esc_attr( $offset_value ) . '">' . esc_html( $offset_name ) . '</option>';
}
$structure[] = '</optgroup>';
@@ -4770,7 +5488,7 @@
* @return string
*/
function _cleanup_header_comment( $str ) {
- return trim(preg_replace("/\s*(?:\*\/|\?>).*/", '', $str));
+ return trim( preg_replace( '/\s*(?:\*\/|\?>).*/', '', $str ) );
}
/**
@@ -4788,35 +5506,37 @@
$delete_timestamp = time() - ( DAY_IN_SECONDS * EMPTY_TRASH_DAYS );
- $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);
+ $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 );
foreach ( (array) $posts_to_delete as $post ) {
$post_id = (int) $post['post_id'];
- if ( !$post_id )
+ if ( ! $post_id ) {
continue;
-
- $del_post = get_post($post_id);
-
- if ( !$del_post || 'trash' != $del_post->post_status ) {
- delete_post_meta($post_id, '_wp_trash_meta_status');
- delete_post_meta($post_id, '_wp_trash_meta_time');
+ }
+
+ $del_post = get_post( $post_id );
+
+ if ( ! $del_post || 'trash' != $del_post->post_status ) {
+ delete_post_meta( $post_id, '_wp_trash_meta_status' );
+ delete_post_meta( $post_id, '_wp_trash_meta_time' );
} else {
- wp_delete_post($post_id);
+ wp_delete_post( $post_id );
}
}
- $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);
+ $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 );
foreach ( (array) $comments_to_delete as $comment ) {
$comment_id = (int) $comment['comment_id'];
- if ( !$comment_id )
+ if ( ! $comment_id ) {
continue;
-
- $del_comment = get_comment($comment_id);
-
- if ( !$del_comment || 'trash' != $del_comment->comment_approved ) {
- delete_comment_meta($comment_id, '_wp_trash_meta_time');
- delete_comment_meta($comment_id, '_wp_trash_meta_status');
+ }
+
+ $del_comment = get_comment( $comment_id );
+
+ if ( ! $del_comment || 'trash' != $del_comment->comment_approved ) {
+ delete_comment_meta( $comment_id, '_wp_trash_meta_time' );
+ delete_comment_meta( $comment_id, '_wp_trash_meta_status' );
} else {
wp_delete_comment( $del_comment );
}
@@ -4837,8 +5557,8 @@
*
* @since 2.9.0
*
- * @param string $file Path to the file.
- * @param array $default_headers List of headers, in the format array('HeaderKey' => 'Header Name').
+ * @param string $file Absolute path to the file.
+ * @param array $default_headers List of headers, in the format `array('HeaderKey' => 'Header Name')`.
* @param string $context Optional. If specified adds filter hook {@see 'extra_$context_headers'}.
* Default empty.
* @return array Array of file headers in `HeaderKey => Header Value` format.
@@ -4868,16 +5588,17 @@
*/
if ( $context && $extra_headers = apply_filters( "extra_{$context}_headers", array() ) ) {
$extra_headers = array_combine( $extra_headers, $extra_headers ); // keys equal values
- $all_headers = array_merge( $extra_headers, (array) $default_headers );
+ $all_headers = array_merge( $extra_headers, (array) $default_headers );
} else {
$all_headers = $default_headers;
}
foreach ( $all_headers as $field => $regex ) {
- if ( preg_match( '/^[ \t\/*#@]*' . preg_quote( $regex, '/' ) . ':(.*)$/mi', $file_data, $match ) && $match[1] )
+ if ( preg_match( '/^[ \t\/*#@]*' . preg_quote( $regex, '/' ) . ':(.*)$/mi', $file_data, $match ) && $match[1] ) {
$all_headers[ $field ] = _cleanup_header_comment( $match[1] );
- else
+ } else {
$all_headers[ $field ] = '';
+ }
}
return $all_headers;
@@ -4990,17 +5711,17 @@
*/
function _wp_mysql_week( $column ) {
switch ( $start_of_week = (int) get_option( 'start_of_week' ) ) {
- case 1 :
- return "WEEK( $column, 1 )";
- case 2 :
- case 3 :
- case 4 :
- case 5 :
- case 6 :
- return "WEEK( DATE_SUB( $column, INTERVAL $start_of_week DAY ), 0 )";
- case 0 :
- default :
- return "WEEK( $column, 0 )";
+ case 1:
+ return "WEEK( $column, 1 )";
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ return "WEEK( DATE_SUB( $column, INTERVAL $start_of_week DAY ), 0 )";
+ case 0:
+ default:
+ return "WEEK( $column, 0 )";
}
}
@@ -5020,8 +5741,9 @@
function wp_find_hierarchy_loop( $callback, $start, $start_parent, $callback_args = array() ) {
$override = is_null( $start_parent ) ? array() : array( $start => $start_parent );
- if ( !$arbitrary_loop_member = wp_find_hierarchy_loop_tortoise_hare( $callback, $start, $override, $callback_args ) )
+ if ( ! $arbitrary_loop_member = wp_find_hierarchy_loop_tortoise_hare( $callback, $start, $override, $callback_args ) ) {
return array();
+ }
return wp_find_hierarchy_loop_tortoise_hare( $callback, $arbitrary_loop_member, $override, $callback_args, true );
}
@@ -5048,26 +5770,28 @@
*/
function wp_find_hierarchy_loop_tortoise_hare( $callback, $start, $override = array(), $callback_args = array(), $_return_loop = false ) {
$tortoise = $hare = $evanescent_hare = $start;
- $return = array();
+ $return = array();
// Set evanescent_hare to one past hare
// Increment hare two steps
while (
$tortoise
&&
- ( $evanescent_hare = isset( $override[$hare] ) ? $override[$hare] : call_user_func_array( $callback, array_merge( array( $hare ), $callback_args ) ) )
+ ( $evanescent_hare = isset( $override[ $hare ] ) ? $override[ $hare ] : call_user_func_array( $callback, array_merge( array( $hare ), $callback_args ) ) )
&&
- ( $hare = isset( $override[$evanescent_hare] ) ? $override[$evanescent_hare] : call_user_func_array( $callback, array_merge( array( $evanescent_hare ), $callback_args ) ) )
+ ( $hare = isset( $override[ $evanescent_hare ] ) ? $override[ $evanescent_hare ] : call_user_func_array( $callback, array_merge( array( $evanescent_hare ), $callback_args ) ) )
) {
- if ( $_return_loop )
- $return[$tortoise] = $return[$evanescent_hare] = $return[$hare] = true;
+ if ( $_return_loop ) {
+ $return[ $tortoise ] = $return[ $evanescent_hare ] = $return[ $hare ] = true;
+ }
// tortoise got lapped - must be a loop
- if ( $tortoise == $evanescent_hare || $tortoise == $hare )
+ if ( $tortoise == $evanescent_hare || $tortoise == $hare ) {
return $_return_loop ? $return : $tortoise;
+ }
// Increment tortoise by one step
- $tortoise = isset( $override[$tortoise] ) ? $override[$tortoise] : call_user_func_array( $callback, array_merge( array( $tortoise ), $callback_args ) );
+ $tortoise = isset( $override[ $tortoise ] ) ? $override[ $tortoise ] : call_user_func_array( $callback, array_merge( array( $tortoise ), $callback_args ) );
}
return false;
@@ -5096,9 +5820,11 @@
*
* @staticvar array $protocols
*
- * @return array Array of allowed protocols. Defaults to an array containing 'http', 'https',
- * 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet',
- * 'mms', 'rtsp', 'svn', 'tel', 'fax', 'xmpp', 'webcal', and 'urn'.
+ * @return string[] Array of allowed protocols. Defaults to an array containing 'http', 'https',
+ * 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet',
+ * 'mms', 'rtsp', 'svn', 'tel', 'fax', 'xmpp', 'webcal', and 'urn'. This covers
+ * all common link protocols, except for 'javascript' which should not be
+ * allowed for untrusted users.
*/
function wp_allowed_protocols() {
static $protocols = array();
@@ -5129,6 +5855,8 @@
*
* @see https://core.trac.wordpress.org/ticket/19589
*
+ * @staticvar array $truncate_paths Array of paths to truncate.
+ *
* @param string $ignore_class Optional. A class to ignore all function calls within - useful
* when you want to just give info about the callee. Default null.
* @param int $skip_frames Optional. A number of stack frames to skip - useful for unwinding
@@ -5139,55 +5867,67 @@
* of individual calls.
*/
function wp_debug_backtrace_summary( $ignore_class = null, $skip_frames = 0, $pretty = true ) {
- if ( version_compare( PHP_VERSION, '5.2.5', '>=' ) )
+ static $truncate_paths;
+
+ if ( version_compare( PHP_VERSION, '5.2.5', '>=' ) ) {
$trace = debug_backtrace( false );
- else
+ } else {
$trace = debug_backtrace();
-
- $caller = array();
+ }
+
+ $caller = array();
$check_class = ! is_null( $ignore_class );
$skip_frames++; // skip this function
+ if ( ! isset( $truncate_paths ) ) {
+ $truncate_paths = array(
+ wp_normalize_path( WP_CONTENT_DIR ),
+ wp_normalize_path( ABSPATH ),
+ );
+ }
+
foreach ( $trace as $call ) {
if ( $skip_frames > 0 ) {
$skip_frames--;
} elseif ( isset( $call['class'] ) ) {
- if ( $check_class && $ignore_class == $call['class'] )
+ if ( $check_class && $ignore_class == $call['class'] ) {
continue; // Filter out calls
+ }
$caller[] = "{$call['class']}{$call['type']}{$call['function']}";
} else {
- if ( in_array( $call['function'], array( 'do_action', 'apply_filters' ) ) ) {
+ if ( in_array( $call['function'], array( 'do_action', 'apply_filters', 'do_action_ref_array', 'apply_filters_ref_array' ) ) ) {
$caller[] = "{$call['function']}('{$call['args'][0]}')";
} elseif ( in_array( $call['function'], array( 'include', 'include_once', 'require', 'require_once' ) ) ) {
- $caller[] = $call['function'] . "('" . str_replace( array( WP_CONTENT_DIR, ABSPATH ) , '', $call['args'][0] ) . "')";
+ $filename = isset( $call['args'][0] ) ? $call['args'][0] : '';
+ $caller[] = $call['function'] . "('" . str_replace( $truncate_paths, '', wp_normalize_path( $filename ) ) . "')";
} else {
$caller[] = $call['function'];
}
}
}
- if ( $pretty )
+ if ( $pretty ) {
return join( ', ', array_reverse( $caller ) );
- else
+ } else {
return $caller;
-}
-
-/**
- * Retrieve ids that are not already present in the cache.
+ }
+}
+
+/**
+ * Retrieve IDs that are not already present in the cache.
*
* @since 3.4.0
* @access private
*
- * @param array $object_ids ID list.
+ * @param int[] $object_ids Array of IDs.
* @param string $cache_key The cache bucket to check against.
- *
- * @return array List of ids not present in the cache.
+ * @return int[] Array of IDs not present in the cache.
*/
function _get_non_cached_ids( $object_ids, $cache_key ) {
$clean = array();
foreach ( $object_ids as $id ) {
$id = (int) $id;
- if ( !wp_cache_get( $id, $cache_key ) ) {
+ if ( ! wp_cache_get( $id, $cache_key ) ) {
$clean[] = $id;
}
}
@@ -5204,14 +5944,15 @@
* @return bool Whether the device is able to upload files.
*/
function _device_can_upload() {
- if ( ! wp_is_mobile() )
+ if ( ! wp_is_mobile() ) {
return true;
+ }
$ua = $_SERVER['HTTP_USER_AGENT'];
- if ( strpos($ua, 'iPhone') !== false
- || strpos($ua, 'iPad') !== false
- || strpos($ua, 'iPod') !== false ) {
+ if ( strpos( $ua, 'iPhone' ) !== false
+ || strpos( $ua, 'iPad' ) !== false
+ || strpos( $ua, 'iPod' ) !== false ) {
return preg_match( '#OS ([\d_]+) like Mac OS X#', $ua, $version ) && version_compare( $version[1], '6', '>=' );
}
@@ -5227,16 +5968,16 @@
* @return bool True if the path is a stream URL.
*/
function wp_is_stream( $path ) {
- if ( false === strpos( $path, '://' ) ) {
+ $scheme_separator = strpos( $path, '://' );
+
+ if ( false === $scheme_separator ) {
// $path isn't a stream
return false;
}
- $wrappers = stream_get_wrappers();
- $wrappers = array_map( 'preg_quote', $wrappers );
- $wrappers_re = '(' . join( '|', $wrappers ) . ')';
-
- return preg_match( "!^$wrappers_re://!", $path ) === 1;
+ $stream = substr( $path, 0, $scheme_separator );
+
+ return in_array( $stream, stream_get_wrappers(), true );
}
/**
@@ -5244,7 +5985,7 @@
*
* @since 3.5.0
*
- * @see checkdate()
+ * @link https://secure.php.net/manual/en/function.checkdate.php
*
* @param int $month Month number.
* @param int $day Day number.
@@ -5276,15 +6017,17 @@
* @since 3.6.0
*/
function wp_auth_check_load() {
- if ( ! is_admin() && ! is_user_logged_in() )
+ if ( ! is_admin() && ! is_user_logged_in() ) {
return;
-
- if ( defined( 'IFRAME_REQUEST' ) )
+ }
+
+ if ( defined( 'IFRAME_REQUEST' ) ) {
return;
+ }
$screen = get_current_screen();
$hidden = array( 'update', 'update-network', 'update-core', 'update-core-network', 'upgrade', 'upgrade-network', 'network' );
- $show = ! in_array( $screen->id, $hidden );
+ $show = ! in_array( $screen->id, $hidden );
/**
* Filters whether to load the authentication check.
@@ -5312,9 +6055,9 @@
* @since 3.6.0
*/
function wp_auth_check_html() {
- $login_url = wp_login_url();
+ $login_url = wp_login_url();
$current_domain = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'];
- $same_domain = ( strpos( $login_url, $current_domain ) === 0 );
+ $same_domain = ( strpos( $login_url, $current_domain ) === 0 );
/**
* Filters whether the authentication check originated at the same domain.
@@ -5324,7 +6067,7 @@
* @param bool $same_domain Whether the authentication check originated at the same domain.
*/
$same_domain = apply_filters( 'wp_auth_check_same_domain', $same_domain );
- $wrap_class = $same_domain ? 'hidden' : 'hidden fallback';
+ $wrap_class = $same_domain ? 'hidden' : 'hidden fallback';
?>
<div id="wp-auth-check-wrap" class="<?php echo $wrap_class; ?>">
@@ -5334,10 +6077,13 @@
<?php
if ( $same_domain ) {
- $login_src = add_query_arg( array(
- 'interim-login' => '1',
- 'wp_lang' => get_user_locale(),
- ), $login_url );
+ $login_src = add_query_arg(
+ array(
+ 'interim-login' => '1',
+ 'wp_lang' => get_user_locale(),
+ ),
+ $login_url
+ );
?>
<div id="wp-auth-check-form" class="loading" data-src="<?php echo esc_url( $login_src ); ?>"></div>
<?php
@@ -5345,9 +6091,9 @@
?>
<div class="wp-auth-fallback">
- <p><b class="wp-auth-fallback-expired" tabindex="0"><?php _e('Session expired'); ?></b></p>
- <p><a href="<?php echo esc_url( $login_url ); ?>" target="_blank"><?php _e('Please log in again.'); ?></a>
- <?php _e('The login page will open in a new window. After logging in you can close it and return to this page.'); ?></p>
+ <p><b class="wp-auth-fallback-expired" tabindex="0"><?php _e( 'Session expired' ); ?></b></p>
+ <p><a href="<?php echo esc_url( $login_url ); ?>" target="_blank"><?php _e( 'Please log in again.' ); ?></a>
+ <?php _e( 'The login page will open in a new tab. After logging in you can close it and return to this page.' ); ?></p>
</div>
</div>
</div>
@@ -5389,8 +6135,9 @@
* @return string Tag RegEx.
*/
function get_tag_regex( $tag ) {
- if ( empty( $tag ) )
+ if ( empty( $tag ) ) {
return;
+ }
return sprintf( '<%1$s[^<]*(?:>[\s\S]*<\/%1$s>|\s*\/>)', tag_escape( $tag ) );
}
@@ -5407,7 +6154,7 @@
* @return string The canonical form of the charset.
*/
function _canonical_charset( $charset ) {
- if ( 'utf-8' === strtolower( $charset ) || 'utf8' === strtolower( $charset) ) {
+ if ( 'utf-8' === strtolower( $charset ) || 'utf8' === strtolower( $charset ) ) {
return 'UTF-8';
}
@@ -5447,14 +6194,16 @@
* Default false.
*/
function mbstring_binary_safe_encoding( $reset = false ) {
- static $encodings = array();
+ static $encodings = array();
static $overloaded = null;
- if ( is_null( $overloaded ) )
+ if ( is_null( $overloaded ) ) {
$overloaded = function_exists( 'mb_internal_encoding' ) && ( ini_get( 'mbstring.func_overload' ) & 2 );
-
- if ( false === $overloaded )
+ }
+
+ if ( false === $overloaded ) {
return;
+ }
if ( ! $reset ) {
$encoding = mb_internal_encoding();
@@ -5532,10 +6281,23 @@
* @return bool True on success, false on failure.
*/
function wp_delete_file_from_directory( $file, $directory ) {
- $real_file = realpath( wp_normalize_path( $file ) );
- $real_directory = realpath( wp_normalize_path( $directory ) );
-
- if ( false === $real_file || false === $real_directory || strpos( wp_normalize_path( $real_file ), trailingslashit( wp_normalize_path( $real_directory ) ) ) !== 0 ) {
+ if ( wp_is_stream( $file ) ) {
+ $real_file = $file;
+ $real_directory = $directory;
+ } else {
+ $real_file = realpath( wp_normalize_path( $file ) );
+ $real_directory = realpath( wp_normalize_path( $directory ) );
+ }
+
+ if ( false !== $real_file ) {
+ $real_file = wp_normalize_path( $real_file );
+ }
+
+ if ( false !== $real_directory ) {
+ $real_directory = wp_normalize_path( $real_directory );
+ }
+
+ if ( false === $real_file || false === $real_directory || strpos( $real_file, trailingslashit( $real_directory ) ) !== 0 ) {
return false;
}
@@ -5581,21 +6343,21 @@
}
/**
- * Parses and formats a MySQL datetime (Y-m-d H:i:s) for ISO8601/RFC3339.
+ * Parses and formats a MySQL datetime (Y-m-d H:i:s) for ISO8601 (Y-m-d\TH:i:s).
*
* Explicitly strips timezones, as datetimes are not saved with any timezone
* information. Including any information on the offset could be misleading.
*
+ * Despite historical function name, the output does not conform to RFC3339 format,
+ * which must contain timezone.
+ *
* @since 4.4.0
*
* @param string $date_string Date string to parse and format.
- * @return string Date formatted for ISO8601/RFC3339.
+ * @return string Date formatted for ISO8601 without time zone.
*/
function mysql_to_rfc3339( $date_string ) {
- $formatted = mysql2date( 'c', $date_string, false );
-
- // Strip timezone information
- return preg_replace( '/(?:Z|[+-]\d{2}(?::\d{2})?)$/', '', $formatted );
+ return mysql2date( 'Y-m-d\TH:i:s', $date_string, false );
}
/**
@@ -5713,12 +6475,16 @@
* @return string UUID.
*/
function wp_generate_uuid4() {
- return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
- mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
+ return sprintf(
+ '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
+ mt_rand( 0, 0xffff ),
+ mt_rand( 0, 0xffff ),
mt_rand( 0, 0xffff ),
mt_rand( 0, 0x0fff ) | 0x4000,
mt_rand( 0, 0x3fff ) | 0x8000,
- mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff )
+ mt_rand( 0, 0xffff ),
+ mt_rand( 0, 0xffff ),
+ mt_rand( 0, 0xffff )
);
}
@@ -5728,7 +6494,8 @@
* @since 4.9.0
*
* @param mixed $uuid UUID to check.
- * @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`.
+ * @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`.
* @return bool The string is a valid UUID or false on failure.
*/
function wp_is_uuid( $uuid, $version = null ) {
@@ -5751,6 +6518,26 @@
}
/**
+ * Get unique ID.
+ *
+ * This is a PHP implementation of Underscore's uniqueId method. A static variable
+ * contains an integer that is incremented with each call. This number is returned
+ * with the optional prefix. As such the returned value is not universally unique,
+ * but it is unique across the life of the PHP process.
+ *
+ * @since 5.0.3
+ *
+ * @staticvar int $id_counter
+ *
+ * @param string $prefix Prefix for the returned ID.
+ * @return string Unique ID.
+ */
+function wp_unique_id( $prefix = '' ) {
+ static $id_counter = 0;
+ return $prefix . (string) ++$id_counter;
+}
+
+/**
* Get last changed date for the specified cache group.
*
* @since 4.7.0
@@ -5803,7 +6590,8 @@
}
/* translators: Do not translate OLD_EMAIL, NEW_EMAIL, SITENAME, SITEURL: those are placeholders. */
- $email_change_text = __( 'Hi,
+ $email_change_text = __(
+ 'Hi,
This notice confirms that the admin email address was changed on ###SITENAME###.
@@ -5813,12 +6601,13 @@
Regards,
All at ###SITENAME###
-###SITEURL###' );
+###SITEURL###'
+ );
$email_change_email = array(
'to' => $old_email,
/* translators: Site admin email change notification email subject. %s: Site title */
- 'subject' => __( '[%s] Notice of Admin Email Change' ),
+ 'subject' => __( '[%s] Admin Email Changed' ),
'message' => $email_change_text,
'headers' => '',
);
@@ -5850,13 +6639,18 @@
$email_change_email['message'] = str_replace( '###OLD_EMAIL###', $old_email, $email_change_email['message'] );
$email_change_email['message'] = str_replace( '###NEW_EMAIL###', $new_email, $email_change_email['message'] );
- $email_change_email['message'] = str_replace( '###SITENAME###', $site_name, $email_change_email['message'] );
- $email_change_email['message'] = str_replace( '###SITEURL###', home_url(), $email_change_email['message'] );
-
- wp_mail( $email_change_email['to'], sprintf(
- $email_change_email['subject'],
- $site_name
- ), $email_change_email['message'], $email_change_email['headers'] );
+ $email_change_email['message'] = str_replace( '###SITENAME###', $site_name, $email_change_email['message'] );
+ $email_change_email['message'] = str_replace( '###SITEURL###', home_url(), $email_change_email['message'] );
+
+ wp_mail(
+ $email_change_email['to'],
+ sprintf(
+ $email_change_email['subject'],
+ $site_name
+ ),
+ $email_change_email['message'],
+ $email_change_email['headers']
+ );
}
/**
@@ -5911,7 +6705,7 @@
// Partially anonymize the IP by reducing it to the corresponding network ID.
if ( function_exists( 'inet_pton' ) && function_exists( 'inet_ntop' ) ) {
$ip_addr = inet_ntop( inet_pton( $ip_addr ) & inet_pton( $netmask ) );
- if ( false === $ip_addr) {
+ if ( false === $ip_addr ) {
return '::';
}
} elseif ( ! $ipv6_fallback ) {
@@ -6050,9 +6844,12 @@
* @since 4.9.6
*/
function wp_privacy_delete_old_export_files() {
+ $exports_dir = wp_privacy_exports_dir();
+ if ( ! is_dir( $exports_dir ) ) {
+ return;
+ }
+
require_once( ABSPATH . 'wp-admin/includes/file.php' );
-
- $exports_dir = wp_privacy_exports_dir();
$export_files = list_files( $exports_dir, 100, array( 'index.html' ) );
/**
@@ -6075,3 +6872,296 @@
}
}
}
+
+/**
+ * Gets the URL to learn more about updating the PHP version the site is running on.
+ *
+ * This URL can be overridden by specifying an environment variable `WP_UPDATE_PHP_URL` or by using the
+ * {@see 'wp_update_php_url'} filter. Providing an empty string is not allowed and will result in the
+ * default URL being used. Furthermore the page the URL links to should preferably be localized in the
+ * site language.
+ *
+ * @since 5.1.0
+ *
+ * @return string URL to learn more about updating PHP.
+ */
+function wp_get_update_php_url() {
+ $default_url = wp_get_default_update_php_url();
+
+ $update_url = $default_url;
+ if ( false !== getenv( 'WP_UPDATE_PHP_URL' ) ) {
+ $update_url = getenv( 'WP_UPDATE_PHP_URL' );
+ }
+
+ /**
+ * Filters the URL to learn more about updating the PHP version the site is running on.
+ *
+ * Providing an empty string is not allowed and will result in the default URL being used. Furthermore
+ * the page the URL links to should preferably be localized in the site language.
+ *
+ * @since 5.1.0
+ *
+ * @param string $update_url URL to learn more about updating PHP.
+ */
+ $update_url = apply_filters( 'wp_update_php_url', $update_url );
+
+ if ( empty( $update_url ) ) {
+ $update_url = $default_url;
+ }
+
+ return $update_url;
+}
+
+/**
+ * Gets the default URL to learn more about updating the PHP version the site is running on.
+ *
+ * Do not use this function to retrieve this URL. Instead, use {@see wp_get_update_php_url()} when relying on the URL.
+ * This function does not allow modifying the returned URL, and is only used to compare the actually used URL with the
+ * default one.
+ *
+ * @since 5.1.0
+ * @access private
+ *
+ * @return string Default URL to learn more about updating PHP.
+ */
+function wp_get_default_update_php_url() {
+ return _x( 'https://wordpress.org/support/update-php/', 'localized PHP upgrade information page' );
+}
+
+/**
+ * Prints the default annotation for the web host altering the "Update PHP" page URL.
+ *
+ * This function is to be used after {@see wp_get_update_php_url()} to display a consistent
+ * annotation if the web host has altered the default "Update PHP" page URL.
+ *
+ * @since 5.1.0
+ * @since 5.2.0 Added the `$before` and `$after` parameters.
+ *
+ * @param string $before Markup to output before the annotation. Default `<p class="description">`.
+ * @param string $after Markup to output after the annotation. Default `</p>`.
+ */
+function wp_update_php_annotation( $before = '<p class="description">', $after = '</p>' ) {
+ $annotation = wp_get_update_php_annotation();
+
+ if ( $annotation ) {
+ echo $before . $annotation . $after;
+ }
+}
+
+/**
+ * Returns the default annotation for the web hosting altering the "Update PHP" page URL.
+ *
+ * This function is to be used after {@see wp_get_update_php_url()} to return a consistent
+ * annotation if the web host has altered the default "Update PHP" page URL.
+ *
+ * @since 5.2.0
+ *
+ * @return string $message Update PHP page annotation. An empty string if no custom URLs are provided.
+ */
+function wp_get_update_php_annotation() {
+ $update_url = wp_get_update_php_url();
+ $default_url = wp_get_default_update_php_url();
+
+ if ( $update_url === $default_url ) {
+ return '';
+ }
+
+ $annotation = sprintf(
+ /* translators: %s: default Update PHP page URL */
+ __( '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>.' ),
+ esc_url( $default_url )
+ );
+
+ return $annotation;
+}
+
+/**
+ * Gets the URL for directly updating the PHP version the site is running on.
+ *
+ * A URL will only be returned if the `WP_DIRECT_UPDATE_PHP_URL` environment variable is specified or
+ * by using the {@see 'wp_direct_php_update_url'} filter. This allows hosts to send users directly to
+ * the page where they can update PHP to a newer version.
+ *
+ * @since 5.1.1
+ *
+ * @return string URL for directly updating PHP or empty string.
+ */
+function wp_get_direct_php_update_url() {
+ $direct_update_url = '';
+
+ if ( false !== getenv( 'WP_DIRECT_UPDATE_PHP_URL' ) ) {
+ $direct_update_url = getenv( 'WP_DIRECT_UPDATE_PHP_URL' );
+ }
+
+ /**
+ * Filters the URL for directly updating the PHP version the site is running on from the host.
+ *
+ * @since 5.1.1
+ *
+ * @param string $direct_update_url URL for directly updating PHP.
+ */
+ $direct_update_url = apply_filters( 'wp_direct_php_update_url', $direct_update_url );
+
+ return $direct_update_url;
+}
+
+/**
+ * Display a button directly linking to a PHP update process.
+ *
+ * This provides hosts with a way for users to be sent directly to their PHP update process.
+ *
+ * The button is only displayed if a URL is returned by `wp_get_direct_php_update_url()`.
+ *
+ * @since 5.1.1
+ */
+function wp_direct_php_update_button() {
+ $direct_update_url = wp_get_direct_php_update_url();
+
+ if ( empty( $direct_update_url ) ) {
+ return;
+ }
+
+ echo '<p class="button-container">';
+ printf(
+ '<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>',
+ esc_url( $direct_update_url ),
+ __( 'Update PHP' ),
+ /* translators: accessibility text */
+ __( '(opens in a new tab)' )
+ );
+ echo '</p>';
+}
+
+/**
+ * Get the size of a directory.
+ *
+ * A helper function that is used primarily to check whether
+ * a blog has exceeded its allowed upload space.
+ *
+ * @since MU (3.0.0)
+ * @since 5.2.0 $max_execution_time parameter added.
+ *
+ * @param string $directory Full path of a directory.
+ * @param int $max_execution_time Maximum time to run before giving up. In seconds.
+ * The timeout is global and is measured from the moment WordPress started to load.
+ * @return int|false|null Size in bytes if a valid directory. False if not. Null if timeout.
+ */
+function get_dirsize( $directory, $max_execution_time = null ) {
+ $dirsize = get_transient( 'dirsize_cache' );
+
+ if ( is_array( $dirsize ) && isset( $dirsize[ $directory ]['size'] ) ) {
+ return $dirsize[ $directory ]['size'];
+ }
+
+ if ( ! is_array( $dirsize ) ) {
+ $dirsize = array();
+ }
+
+ // Exclude individual site directories from the total when checking the main site of a network
+ // as they are subdirectories and should not be counted.
+ if ( is_multisite() && is_main_site() ) {
+ $dirsize[ $directory ]['size'] = recurse_dirsize( $directory, $directory . '/sites', $max_execution_time );
+ } else {
+ $dirsize[ $directory ]['size'] = recurse_dirsize( $directory, null, $max_execution_time );
+ }
+
+ set_transient( 'dirsize_cache', $dirsize, HOUR_IN_SECONDS );
+ return $dirsize[ $directory ]['size'];
+}
+
+/**
+ * Get the size of a directory recursively.
+ *
+ * Used by get_dirsize() to get a directory's size when it contains
+ * other directories.
+ *
+ * @since MU (3.0.0)
+ * @since 4.3.0 $exclude parameter added.
+ * @since 5.2.0 $max_execution_time parameter added.
+ *
+ * @param string $directory Full path of a directory.
+ * @param string|array $exclude Optional. Full path of a subdirectory to exclude from the total, or array of paths.
+ * Expected without trailing slash(es).
+ * @param int $max_execution_time Maximum time to run before giving up. In seconds.
+ * The timeout is global and is measured from the moment WordPress started to load.
+ * @return int|false|null Size in bytes if a valid directory. False if not. Null if timeout.
+ */
+function recurse_dirsize( $directory, $exclude = null, $max_execution_time = null ) {
+ $size = 0;
+
+ $directory = untrailingslashit( $directory );
+
+ if ( ! file_exists( $directory ) || ! is_dir( $directory ) || ! is_readable( $directory ) ) {
+ return false;
+ }
+
+ if (
+ ( is_string( $exclude ) && $directory === $exclude ) ||
+ ( is_array( $exclude ) && in_array( $directory, $exclude, true ) )
+ ) {
+ return false;
+ }
+
+ if ( $max_execution_time === null ) {
+ // Keep the previous behavior but attempt to prevent fatal errors from timeout if possible.
+ if ( function_exists( 'ini_get' ) ) {
+ $max_execution_time = ini_get( 'max_execution_time' );
+ } else {
+ // Disable...
+ $max_execution_time = 0;
+ }
+
+ // Leave 1 second "buffer" for other operations if $max_execution_time has reasonable value.
+ if ( $max_execution_time > 10 ) {
+ $max_execution_time -= 1;
+ }
+ }
+
+ if ( $handle = opendir( $directory ) ) {
+ while ( ( $file = readdir( $handle ) ) !== false ) {
+ $path = $directory . '/' . $file;
+ if ( $file != '.' && $file != '..' ) {
+ if ( is_file( $path ) ) {
+ $size += filesize( $path );
+ } elseif ( is_dir( $path ) ) {
+ $handlesize = recurse_dirsize( $path, $exclude, $max_execution_time );
+ if ( $handlesize > 0 ) {
+ $size += $handlesize;
+ }
+ }
+
+ if ( $max_execution_time > 0 && microtime( true ) - WP_START_TIMESTAMP > $max_execution_time ) {
+ // Time exceeded. Give up instead of risking a fatal timeout.
+ $size = null;
+ break;
+ }
+ }
+ }
+ closedir( $handle );
+ }
+ return $size;
+}
+
+/**
+* Checks compatibility with the current WordPress version.
+*
+* @since 5.2.0
+*
+* @param string $required Minimum required WordPress version.
+* @return bool True if required version is compatible or empty, false if not.
+*/
+function is_wp_version_compatible( $required ) {
+ return empty( $required ) || version_compare( get_bloginfo( 'version' ), $required, '>=' );
+}
+
+/**
+ * Checks compatibility with the current PHP version.
+ *
+ * @since 5.2.0
+ *
+ * @param string $required Minimum required PHP version.
+ * @return bool True if required version is compatible or empty, false if not.
+ */
+function is_php_version_compatible( $required ) {
+ return empty( $required ) || version_compare( phpversion(), $required, '>=' );
+}