X-Git-Url: https://scripts.mit.edu/gitweb/autoinstalls/wordpress.git/blobdiff_plain/53f4633144ed68c8b8fb5861f992b5489894a940..446fc046ca303b25776b07134407239bdeafa3e6:/wp-includes/formatting.php diff --git a/wp-includes/formatting.php b/wp-includes/formatting.php index fa9551a3..97a290ad 100644 --- a/wp-includes/formatting.php +++ b/wp-includes/formatting.php @@ -216,63 +216,35 @@ function wptexturize( $text, $reset = false ) { // Look for shortcodes and HTML elements. - $tagnames = array_keys( $shortcode_tags ); - $tagregexp = join( '|', array_map( 'preg_quote', $tagnames ) ); - $tagregexp = "(?:$tagregexp)(?![\\w-])"; // Excerpt of get_shortcode_regex(). - - $comment_regex = - '!' // Start of comment, after the <. - . '(?:' // Unroll the loop: Consume everything until --> is found. - . '-(?!->)' // Dash not followed by end of comment. - . '[^\-]*+' // Consume non-dashes. - . ')*+' // Loop possessively. - . '(?:-->)?'; // End of comment. If not found, match all input. - - $shortcode_regex = - '\[' // Find start of shortcode. - . '[\/\[]?' // Shortcodes may begin with [/ or [[ - . $tagregexp // Only match registered shortcodes, because performance. - . '(?:' - . '[^\[\]<>]+' // Shortcodes do not contain other shortcodes. Quantifier critical. - . '|' - . '<[^\[\]>]*>' // HTML elements permitted. Prevents matching ] before >. - . ')*+' // Possessive critical. - . '\]' // Find end of shortcode. - . '\]?'; // Shortcodes may end with ]] - - $regex = - '/(' // Capture the entire match. - . '<' // Find start of element. - . '(?(?=!--)' // Is this a comment? - . $comment_regex // Find end of comment. - . '|' - . '[^>]*>' // Find end of element. - . ')' - . '|' - . $shortcode_regex // Find shortcodes. - . ')/s'; + preg_match_all( '@\[/?([^<>&/\[\]\x00-\x20=]++)@', $text, $matches ); + $tagnames = array_intersect( array_keys( $shortcode_tags ), $matches[1] ); + $found_shortcodes = ! empty( $tagnames ); + $shortcode_regex = $found_shortcodes ? _get_wptexturize_shortcode_regex( $tagnames ) : ''; + $regex = _get_wptexturize_split_regex( $shortcode_regex ); $textarr = preg_split( $regex, $text, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY ); foreach ( $textarr as &$curl ) { // Only call _wptexturize_pushpop_element if $curl is a delimiter. $first = $curl[0]; - if ( '<' === $first && ' ", "\n", $pee ); + if ( false !== strpos( $pee, '' ) ) { + $pee = str_replace( array( ' ', '' ), "\n", $pee ); + } return $pee; } @@ -610,6 +585,17 @@ function wpautop( $pee, $br = true ) { * @return array The formatted text. */ function wp_html_split( $input ) { + return preg_split( get_html_split_regex(), $input, -1, PREG_SPLIT_DELIM_CAPTURE ); +} + +/** + * Retrieve the regular expression for an HTML element. + * + * @since 4.4.0 + * + * @return string The regular expression + */ +function get_html_split_regex() { static $regex; if ( ! isset( $regex ) ) { @@ -630,22 +616,100 @@ function wp_html_split( $input ) { . ')*+' // Loop possessively. . '(?:]]>)?'; // End of comment. If not found, match all input. + $escaped = + '(?=' // Is the element escaped? + . '!--' + . '|' + . '!\[CDATA\[' + . ')' + . '(?(?=!-)' // If yes, which type? + . $comments + . '|' + . $cdata + . ')'; + $regex = '/(' // Capture the entire match. . '<' // Find start of element. - . '(?(?=!--)' // Is this a comment? - . $comments // Find end of comment. - . '|' - . '(?(?=!\[CDATA\[)' // Is this a comment? - . $cdata // Find end of comment. - . '|' - . '[^>]*>?' // Find end of element. If not found, match all input. - . ')' + . '(?' // Conditional expression follows. + . $escaped // Find end of escaped element. + . '|' // ... else ... + . '[^>]*>?' // Find end of normal element. . ')' - . ')/s'; + . ')/'; + } + + return $regex; +} + +/** + * Retrieve the combined regular expression for HTML and shortcodes. + * + * @access private + * @ignore + * @internal This function will be removed in 4.5.0 per Shortcode API Roadmap. + * @since 4.4.0 + * + * @param string $shortcode_regex The result from _get_wptexturize_shortcode_regex(). Optional. + * @return string The regular expression + */ +function _get_wptexturize_split_regex( $shortcode_regex = '' ) { + static $html_regex; + + if ( ! isset( $html_regex ) ) { + $comment_regex = + '!' // Start of comment, after the <. + . '(?:' // Unroll the loop: Consume everything until --> is found. + . '-(?!->)' // Dash not followed by end of comment. + . '[^\-]*+' // Consume non-dashes. + . ')*+' // Loop possessively. + . '(?:-->)?'; // End of comment. If not found, match all input. + + $html_regex = // Needs replaced with wp_html_split() per Shortcode API Roadmap. + '<' // Find start of element. + . '(?(?=!--)' // Is this a comment? + . $comment_regex // Find end of comment. + . '|' + . '[^>]*>?' // Find end of element. If not found, match all input. + . ')'; } - return preg_split( $regex, $input, -1, PREG_SPLIT_DELIM_CAPTURE ); + if ( empty( $shortcode_regex ) ) { + $regex = '/(' . $html_regex . ')/'; + } else { + $regex = '/(' . $html_regex . '|' . $shortcode_regex . ')/'; + } + + return $regex; +} + +/** + * Retrieve the regular expression for shortcodes. + * + * @access private + * @ignore + * @internal This function will be removed in 4.5.0 per Shortcode API Roadmap. + * @since 4.4.0 + * + * @param array $tagnames List of shortcodes to find. + * @return string The regular expression + */ +function _get_wptexturize_shortcode_regex( $tagnames ) { + $tagregexp = join( '|', array_map( 'preg_quote', $tagnames ) ); + $tagregexp = "(?:$tagregexp)(?=[\\s\\]\\/])"; // Excerpt of get_shortcode_regex(). + $regex = + '\[' // Find start of shortcode. + . '[\/\[]?' // Shortcodes may begin with [/ or [[ + . $tagregexp // Only match registered shortcodes, because performance. + . '(?:' + . '[^\[\]<>]+' // Shortcodes do not contain other shortcodes. Quantifier critical. + . '|' + . '<[^\[\]>]*>' // HTML elements permitted. Prevents matching ] before >. + . ')*+' // Possessive critical. + . '\]' // Find end of shortcode. + . '\]?'; // Shortcodes may end with ]] + + return $regex; } /** @@ -667,7 +731,7 @@ function wp_replace_in_html_tags( $haystack, $replace_pairs ) { // Extract $needle and $replace. foreach ( $replace_pairs as $needle => $replace ); - // Loop through delimeters (elements) only. + // Loop through delimiters (elements) only. for ( $i = 1, $c = count( $textarr ); $i < $c; $i += 2 ) { if ( false !== strpos( $textarr[$i], $needle ) ) { $textarr[$i] = str_replace( $needle, $replace, $textarr[$i] ); @@ -678,7 +742,7 @@ function wp_replace_in_html_tags( $haystack, $replace_pairs ) { // Extract all $needles. $needles = array_keys( $replace_pairs ); - // Loop through delimeters (elements) only. + // Loop through delimiters (elements) only. for ( $i = 1, $c = count( $textarr ); $i < $c; $i += 2 ) { foreach ( $needles as $needle ) { if ( false !== strpos( $textarr[$i], $needle ) ) { @@ -763,7 +827,7 @@ function shortcode_unautop( $pee ) { . ')' . '(?:' . $spaces . ')*+' // optional trailing whitespace . '<\\/p>' // closing paragraph - . '/s'; + . '/'; return preg_replace( $pattern, '$1', $pee ); } @@ -814,10 +878,14 @@ function seems_utf8( $str ) { * * @staticvar string $_charset * - * @param string $string The text which is to be encoded. - * @param int $quote_style Optional. Converts double quotes if set to ENT_COMPAT, both single and double if set to ENT_QUOTES or none if set to ENT_NOQUOTES. Also compatible with old values; converting single quotes if set to 'single', double if set to 'double' or both if otherwise set. Default is ENT_NOQUOTES. - * @param string $charset Optional. The character encoding of the string. Default is false. - * @param bool $double_encode Optional. Whether to encode existing html entities. Default is false. + * @param string $string The text which is to be encoded. + * @param int|string $quote_style Optional. Converts double quotes if set to ENT_COMPAT, + * both single and double if set to ENT_QUOTES or none if set to ENT_NOQUOTES. + * Also compatible with old values; converting single quotes if set to 'single', + * double if set to 'double' or both if otherwise set. + * Default is ENT_NOQUOTES. + * @param string $charset Optional. The character encoding of the string. Default is false. + * @param bool $double_encode Optional. Whether to encode existing html entities. Default is false. * @return string The encoded text with HTML entities. */ function _wp_specialchars( $string, $quote_style = ENT_NOQUOTES, $charset = false, $double_encode = false ) { @@ -1305,7 +1373,7 @@ function remove_accents( $string ) { */ function sanitize_file_name( $filename ) { $filename_raw = $filename; - $special_chars = array("?", "[", "]", "/", "\\", "=", "<", ">", ":", ";", ",", "'", "\"", "&", "$", "#", "*", "(", ")", "|", "~", "`", "!", "{", "}", chr(0)); + $special_chars = array("?", "[", "]", "/", "\\", "=", "<", ">", ":", ";", ",", "'", "\"", "&", "$", "#", "*", "(", ")", "|", "~", "`", "!", "{", "}", "%", "+", chr(0)); /** * Filter the list of characters to remove from a filename. * @@ -1516,12 +1584,12 @@ function sanitize_title_with_dashes( $title, $raw_title = '', $context = 'displa } $title = strtolower($title); - $title = preg_replace('/&.+?;/', '', $title); // kill entities - $title = str_replace('.', '-', $title); if ( 'save' == $context ) { // Convert nbsp, ndash and mdash to hyphens $title = str_replace( array( '%c2%a0', '%e2%80%93', '%e2%80%94' ), '-', $title ); + // Convert nbsp, ndash and mdash HTML entities to hyphens + $title = str_replace( array( ' ', ' ', '–', '–', '—', '—' ), '-', $title ); // Strip these characters entirely $title = str_replace( array( @@ -1544,6 +1612,9 @@ function sanitize_title_with_dashes( $title, $raw_title = '', $context = 'displa $title = str_replace( '%c3%97', 'x', $title ); } + $title = preg_replace('/&.+?;/', '', $title); // kill entities + $title = str_replace('.', '-', $title); + $title = preg_replace('/[^%a-z0-9 _-]/', '', $title); $title = preg_replace('/\s+/', '-', $title); $title = preg_replace('|-+|', '-', $title); @@ -1594,9 +1665,9 @@ function sanitize_html_class( $class, $fallback = '' ) { //Limit to A-Z,a-z,0-9,_,- $sanitized = preg_replace( '/[^A-Za-z0-9_-]/', '', $sanitized ); - if ( '' == $sanitized ) - $sanitized = $fallback; - + if ( '' == $sanitized && $fallback ) { + return sanitize_html_class( $fallback ); + } /** * Filter a sanitized HTML class string. * @@ -1837,12 +1908,15 @@ function force_balance_tags( $text ) { * it is simply a holder for the 'format_to_edit' filter. * * @since 0.71 + * @since 4.4.0 The `$richedit` parameter was renamed to `$rich_text` for clarity. * - * @param string $content The text about to be edited. - * @param bool $richedit Whether the $content should not pass through htmlspecialchars(). Default false (meaning it will be passed). + * @param string $content The text about to be edited. + * @param bool $rich_text Optional. Whether `$content` should be considered rich text, + * in which case it would not be passed through esc_textarea(). + * Default false. * @return string The text after the filter (and possibly htmlspecialchars()) has been run. */ -function format_to_edit( $content, $richedit = false ) { +function format_to_edit( $content, $rich_text = false ) { /** * Filter the text to be formatted for editing. * @@ -1851,7 +1925,7 @@ function format_to_edit( $content, $richedit = false ) { * @param string $content The text, prior to formatting for editing. */ $content = apply_filters( 'format_to_edit', $content ); - if ( ! $richedit ) + if ( ! $rich_text ) $content = esc_textarea( $content ); return $content; } @@ -1943,10 +2017,7 @@ function addslashes_gpc($gpc) { } /** - * Navigates through an array and removes slashes from the values. - * - * If an array is passed, the array_map() function causes a callback to pass the - * value back to the function. The slashes from this value will removed. + * Navigates through an array, object, or scalar, and removes slashes from the values. * * @since 2.0.0 * @@ -1954,43 +2025,55 @@ function addslashes_gpc($gpc) { * @return mixed Stripped value. */ function stripslashes_deep( $value ) { - if ( is_array($value) ) { - $value = array_map('stripslashes_deep', $value); - } elseif ( is_object($value) ) { - $vars = get_object_vars( $value ); - foreach ($vars as $key=>$data) { - $value->{$key} = stripslashes_deep( $data ); - } - } elseif ( is_string( $value ) ) { - $value = stripslashes($value); - } - - return $value; + return map_deep( $value, 'stripslashes_from_strings_only' ); } /** - * Navigates through an array and encodes the values to be used in a URL. + * Callback function for `stripslashes_deep()` which strips slashes from strings. + * + * @since 4.4.0 * + * @param mixed $value The array or string to be stripped. + * @return mixed $value The stripped value. + */ +function stripslashes_from_strings_only( $value ) { + return is_string( $value ) ? stripslashes( $value ) : $value; +} + +/** + * Navigates through an array, object, or scalar, and encodes the values to be used in a URL. * * @since 2.2.0 * - * @param array|string $value The array or string to be encoded. - * @return array|string $value The encoded array (or string from the callback). + * @param mixed $value The array or string to be encoded. + * @return mixed $value The encoded value. */ function urlencode_deep( $value ) { - return is_array( $value ) ? array_map( 'urlencode_deep', $value ) : urlencode( $value ); + return map_deep( $value, 'urlencode' ); } /** - * Navigates through an array and raw encodes the values to be used in a URL. + * Navigates through an array, object, or scalar, and raw-encodes the values to be used in a URL. * * @since 3.4.0 * - * @param array|string $value The array or string to be encoded. - * @return array|string $value The encoded array (or string from the callback). + * @param mixed $value The array or string to be encoded. + * @return mixed $value The encoded value. */ function rawurlencode_deep( $value ) { - return is_array( $value ) ? array_map( 'rawurlencode_deep', $value ) : rawurlencode( $value ); + return map_deep( $value, 'rawurlencode' ); +} + +/** + * Navigates through an array, object, or scalar, and decodes URL-encoded values + * + * @since 4.4.0 + * + * @param mixed $value The array or string to be decoded. + * @return mixed $value The decoded value. + */ +function urldecode_deep( $value ) { + return map_deep( $value, 'urldecode' ); } /** @@ -2071,15 +2154,17 @@ function _make_web_ftp_clickable_cb( $matches ) { $ret = ''; $dest = $matches[2]; $dest = 'http://' . $dest; - $dest = esc_url($dest); - if ( empty($dest) ) - return $matches[0]; // removed trailing [.,;:)] from URL if ( in_array( substr($dest, -1), array('.', ',', ';', ':', ')') ) === true ) { $ret = substr($dest, -1); $dest = substr($dest, 0, strlen($dest)-1); } + + $dest = esc_url($dest); + if ( empty($dest) ) + return $matches[0]; + return $matches[1] . "$dest$ret"; } @@ -2117,9 +2202,9 @@ function make_clickable( $text ) { $nested_code_pre = 0; // Keep track of how many levels link is nested inside
 or 
 	foreach ( $textarr as $piece ) {
 
-		if ( preg_match( '|^]|i', $piece ) || preg_match( '|^]|i', $piece ) )
+		if ( preg_match( '|^]|i', $piece ) || preg_match( '|^]|i', $piece ) || preg_match( '|^]|i', $piece ) || preg_match( '|^]|i', $piece ) )
 			$nested_code_pre++;
-		elseif ( ( '' === strtolower( $piece ) || '
' === strtolower( $piece ) ) && $nested_code_pre ) + elseif ( $nested_code_pre && ( '' === strtolower( $piece ) || '' === strtolower( $piece ) || '' === strtolower( $piece ) || '' === strtolower( $piece ) ) ) $nested_code_pre--; if ( $nested_code_pre || empty( $piece ) || ( $piece[0] === '<' && ! preg_match( '|^<\s*[\w]{1,20}+://|', $piece ) ) ) { @@ -2253,8 +2338,30 @@ function wp_rel_nofollow( $text ) { */ function wp_rel_nofollow_callback( $matches ) { $text = $matches[1]; - $text = str_replace(array(' rel="nofollow"', " rel='nofollow'"), '', $text); - return ""; + $atts = shortcode_parse_atts( $matches[1] ); + $rel = 'nofollow'; + + if ( preg_match( '%href=["\'](' . preg_quote( set_url_scheme( home_url(), 'http' ) ) . ')%i', $text ) || + preg_match( '%href=["\'](' . preg_quote( set_url_scheme( home_url(), 'https' ) ) . ')%i', $text ) + ) { + return ""; + } + + if ( ! empty( $atts['rel'] ) ) { + $parts = array_map( 'trim', explode( ' ', $atts['rel'] ) ); + if ( false === array_search( 'nofollow', $parts ) ) { + $parts[] = 'nofollow'; + } + $rel = implode( ' ', $parts ); + unset( $atts['rel'] ); + + $html = ''; + foreach ( $atts as $name => $value ) { + $html .= "{$name}=\"$value\" "; + } + $text = trim( $html ); + } + return ""; } /** @@ -2383,7 +2490,6 @@ function is_email( $email, $deprecated = false ) { * * @param bool $is_email Whether the email address has passed the is_email() checks. Default false. * @param string $email The email address being checked. - * @param string $message An explanatory message to the user. * @param string $context Context under which the email was tested. */ return apply_filters( 'is_email', false, $email, 'email_too_short' ); @@ -2496,13 +2602,19 @@ function get_gmt_from_date( $string, $format = 'Y-m-d H:i:s' ) { $tz = get_option( 'timezone_string' ); if ( $tz ) { $datetime = date_create( $string, new DateTimeZone( $tz ) ); - if ( ! $datetime ) + if ( ! $datetime ) { return gmdate( $format, 0 ); + } $datetime->setTimezone( new DateTimeZone( 'UTC' ) ); $string_gmt = $datetime->format( $format ); } else { - if ( ! preg_match( '#([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,2}) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})#', $string, $matches ) ) - return gmdate( $format, 0 ); + if ( ! preg_match( '#([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,2}) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})#', $string, $matches ) ) { + $datetime = strtotime( $string ); + if ( false === $datetime ) { + return gmdate( $format, 0 ); + } + return gmdate( $format, $datetime ); + } $string_time = gmmktime( $matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1] ); $string_gmt = gmdate( $format, $string_time - get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ); } @@ -2593,23 +2705,6 @@ function iso8601_to_datetime( $date_string, $timezone = 'user' ) { } } -/** - * Adds a element attributes to open links in new windows. - * - * Comment text in popup windows should be filtered through this. Right now it's - * a moderately dumb function, ideally it would detect whether a target or rel - * attribute was already there and adjust its actions accordingly. - * - * @since 0.71 - * - * @param string $text Content to replace links to open in a new window. - * @return string Content that has filtered links. - */ -function popuplinks( $text ) { - $text = preg_replace('//i', "", $text); - return $text; -} - /** * Strips out all characters that are not allowable in an email. * @@ -2747,13 +2842,13 @@ function human_time_diff( $from, $to = '' ) { if ( $days <= 1 ) $days = 1; $since = sprintf( _n( '%s day', '%s days', $days ), $days ); - } elseif ( $diff < 30 * DAY_IN_SECONDS && $diff >= WEEK_IN_SECONDS ) { + } elseif ( $diff < MONTH_IN_SECONDS && $diff >= WEEK_IN_SECONDS ) { $weeks = round( $diff / WEEK_IN_SECONDS ); if ( $weeks <= 1 ) $weeks = 1; $since = sprintf( _n( '%s week', '%s weeks', $weeks ), $weeks ); - } elseif ( $diff < YEAR_IN_SECONDS && $diff >= 30 * DAY_IN_SECONDS ) { - $months = round( $diff / ( 30 * DAY_IN_SECONDS ) ); + } elseif ( $diff < YEAR_IN_SECONDS && $diff >= MONTH_IN_SECONDS ) { + $months = round( $diff / MONTH_IN_SECONDS ); if ( $months <= 1 ) $months = 1; $since = sprintf( _n( '%s month', '%s months', $months ), $months ); @@ -3187,7 +3282,11 @@ function ent2ncr( $text ) { * * @since 4.3.0 * - * @param string $text The text to be formatted. + * @see _WP_Editors::editor() + * + * @param string $text The text to be formatted. + * @param string $default_editor The default editor for the current user. + * It is usually either 'html' or 'tinymce'. * @return string The formatted text after filter is applied. */ function format_for_editor( $text, $default_editor = null ) { @@ -3200,7 +3299,9 @@ function format_for_editor( $text, $default_editor = null ) { * * @since 4.3.0 * - * @param string $text The formatted text. + * @param string $text The formatted text. + * @param string $default_editor The default editor for the current user. + * It is usually either 'html' or 'tinymce'. */ return apply_filters( 'format_for_editor', $text, $default_editor ); } @@ -3240,7 +3341,7 @@ function _deep_replace( $search, $subject ) { * * @since 2.8.0 * - * @global wpdb $wpdb + * @global wpdb $wpdb WordPress database abstraction object. * * @param string|array $data Unescaped data * @return string|array Escaped data @@ -3270,14 +3371,22 @@ function esc_url( $url, $protocols = null, $_context = 'display' ) { if ( '' == $url ) return $url; - $url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\\x80-\\xff]|i', '', $url); + + $url = str_replace( ' ', '%20', $url ); + $url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\[\]\\x80-\\xff]|i', '', $url); + + if ( '' === $url ) { + return $url; + } + if ( 0 !== stripos( $url, 'mailto:' ) ) { $strip = array('%0d', '%0a', '%0D', '%0A'); $url = _deep_replace($strip, $url); } + $url = str_replace(';//', '://', $url); /* If the URL doesn't appear to contain a scheme, we - * presume it needs http:// appended (unless a relative + * presume it needs http:// prepended (unless a relative * link starting with /, # or ? or a php file). */ if ( strpos($url, ':') === false && ! in_array( $url[0], array( '/', '#', '?' ) ) && @@ -3291,6 +3400,43 @@ function esc_url( $url, $protocols = null, $_context = 'display' ) { $url = str_replace( "'", ''', $url ); } + if ( ( false !== strpos( $url, '[' ) ) || ( false !== strpos( $url, ']' ) ) ) { + + $parsed = wp_parse_url( $url ); + $front = ''; + + if ( isset( $parsed['scheme'] ) ) { + $front .= $parsed['scheme'] . '://'; + } elseif ( '/' === $url[0] ) { + $front .= '//'; + } + + if ( isset( $parsed['user'] ) ) { + $front .= $parsed['user']; + } + + if ( isset( $parsed['pass'] ) ) { + $front .= ':' . $parsed['pass']; + } + + if ( isset( $parsed['user'] ) || isset( $parsed['pass'] ) ) { + $front .= '@'; + } + + if ( isset( $parsed['host'] ) ) { + $front .= $parsed['host']; + } + + if ( isset( $parsed['port'] ) ) { + $front .= ':' . $parsed['port']; + } + + $end_dirty = str_replace( $front, '', $url ); + $end_clean = str_replace( array( '[', ']' ), array( '%5B', '%5D' ), $end_dirty ); + $url = str_replace( $end_dirty, $end_clean, $url ); + + } + if ( '/' === $url[0] ) { $good_protocol_url = $url; } else { @@ -3479,7 +3625,7 @@ function tag_escape( $tag_name ) { * @return string Absolute path. */ function wp_make_link_relative( $link ) { - return preg_replace( '|^(https?:)?//[^/]+(/.*)|i', '$2', $link ); + return preg_replace( '|^(https?:)?//[^/]+(/?.*)|i', '$2', $link ); } /** @@ -3490,7 +3636,7 @@ function wp_make_link_relative( $link ) { * * @since 2.0.5 * - * @global wpdb $wpdb + * @global wpdb $wpdb WordPress database abstraction object. * * @param string $option The name of the option. * @param string $value The unsanitised value. @@ -3520,6 +3666,8 @@ function sanitize_option( $option, $value ) { case 'thumbnail_size_h': case 'medium_size_w': case 'medium_size_h': + case 'medium_large_size_w': + case 'medium_large_size_h': case 'large_size_w': case 'large_size_h': case 'mailserver_port': @@ -3561,7 +3709,6 @@ function sanitize_option( $option, $value ) { if ( is_wp_error( $value ) ) { $error = $value->get_error_message(); } else { - $value = wp_kses_post( $value ); $value = esc_html( $value ); } break; @@ -3735,6 +3882,34 @@ function sanitize_option( $option, $value ) { return apply_filters( "sanitize_option_{$option}", $value, $option, $original_value ); } +/** + * Maps a function to all non-iterable elements of an array or an object. + * + * This is similar to `array_walk_recursive()` but acts upon objects too. + * + * @since 4.4.0 + * + * @param mixed $value The array, object, or scalar. + * @param callable $callback The function to map onto $value. + * @return mixed The value with the callback applied to all non-arrays and non-objects inside it. + */ +function map_deep( $value, $callback ) { + if ( is_array( $value ) ) { + foreach ( $value as $index => $item ) { + $value[ $index ] = map_deep( $item, $callback ); + } + } elseif ( is_object( $value ) ) { + $object_vars = get_object_vars( $value ); + foreach ( $object_vars as $property_name => $property_value ) { + $value->$property_name = map_deep( $property_value, $callback ); + } + } else { + $value = call_user_func( $callback, $value ); + } + + return $value; +} + /** * Parses a string into variables to be stored in an array. * @@ -3983,7 +4158,7 @@ function _links_add_base( $m ) { return $m[1] . '=' . $m[2] . ( preg_match( '#^(\w{1,20}):#', $m[3], $protocol ) && in_array( $protocol[1], wp_allowed_protocols() ) ? $m[3] : - WP_HTTP::make_absolute_url( $m[3], $_links_add_base ) + WP_Http::make_absolute_url( $m[3], $_links_add_base ) ) . $m[2]; } @@ -4136,6 +4311,9 @@ function wp_basename( $path, $suffix = '' ) { * @since 3.0.0 * * @staticvar string|false $dblq + * + * @param string $text The text to be modified. + * @return string The modified text. */ function capital_P_dangit( $text ) { // Simple replacement for titles @@ -4357,7 +4535,7 @@ function print_emoji_detection_script() { * * @param string The emoji base URL. */ - 'baseUrl' => apply_filters( 'emoji_url', set_url_scheme( '//s.w.org/images/core/emoji/72x72/' ) ), + 'baseUrl' => apply_filters( 'emoji_url', 'https://s.w.org/images/core/emoji/72x72/' ), /** * Filter the extension of the emoji files. @@ -4404,7 +4582,7 @@ function print_emoji_detection_script() { ?> $length ) { + $short_url = substr( $short_url, 0, $length - 3 ) . '…'; + } + return $short_url; +}