diff -r c7c34916027a -r 177826044cd9 wp/wp-includes/functions.php --- 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( '/(?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 = ''; - 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 = ''; - - if ( $echo ) + $referer_field = ''; + + 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 = ''; - 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 .= '
'; + $html .= '
'; $redirect_to = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : ''; - $html .= sprintf( + $html .= sprintf( /* translators: %s: logout URL */ __( 'Do you really want to log out?' ), wp_logout_url( $redirect_to ) @@ -2621,7 +2917,8 @@ $html = __( 'The link you followed has expired.' ); if ( wp_get_referer() ) { $html .= '
'; - $html .= sprintf( '%s', + $html .= sprintf( + '%s', 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 = "
$message
"; } - $errors = $message->get_error_messages(); - switch ( count( $errors ) ) { - case 0 : - $message = ''; - break; - case 1 : - $message = "{$errors[0]}
"; - break; - default : - $message = "$message
"; + $link_text = $r['link_text']; + $message .= "\n"; } if ( isset( $r['back_link'] ) && $r['back_link'] ) { - $back_text = $have_gettext? __('« Back') : '« Back'; - $message .= "\n"; + $back_text = $have_gettext ? __( '« Back' ) : '« Back'; + $message .= "\n"; } 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'"; + } + ?> -> +> - -