* 'cause today's effort makes it worth tomorrow's "holiday"...
*
* Becomes:
*
* ’cause today’s effort makes it worth tomorrow’s “holiday”…
*
* Code within certain html blocks are skipped.
*
* @since 0.71
* @uses $wp_cockneyreplace Array of formatted entities for certain common phrases
*
* @param string $text The text to be formatted
* @param bool $reset Set to true for unit testing. Translated patterns will reset.
* @return string The string replaced with html entities
*/
function wptexturize($text, $reset = false) {
global $wp_cockneyreplace, $shortcode_tags;
static $static_characters, $static_replacements, $dynamic_characters, $dynamic_replacements,
$default_no_texturize_tags, $default_no_texturize_shortcodes, $run_texturize = true;
// If there's nothing to do, just stop.
if ( empty( $text ) || false === $run_texturize ) {
return $text;
}
// Set up static variables. Run once only.
if ( $reset || ! isset( $static_characters ) ) {
/**
* Filter whether to skip running wptexturize().
*
* Passing false to the filter will effectively short-circuit wptexturize().
* returning the original text passed to the function instead.
*
* The filter runs only once, the first time wptexturize() is called.
*
* @since 4.0.0
*
* @see wptexturize()
*
* @param bool $run_texturize Whether to short-circuit wptexturize().
*/
$run_texturize = apply_filters( 'run_wptexturize', $run_texturize );
if ( false === $run_texturize ) {
return $text;
}
/* translators: opening curly double quote */
$opening_quote = _x( '“', 'opening curly double quote' );
/* translators: closing curly double quote */
$closing_quote = _x( '”', 'closing curly double quote' );
/* translators: apostrophe, for example in 'cause or can't */
$apos = _x( '’', 'apostrophe' );
/* translators: prime, for example in 9' (nine feet) */
$prime = _x( '′', 'prime' );
/* translators: double prime, for example in 9" (nine inches) */
$double_prime = _x( '″', 'double prime' );
/* translators: opening curly single quote */
$opening_single_quote = _x( '‘', 'opening curly single quote' );
/* translators: closing curly single quote */
$closing_single_quote = _x( '’', 'closing curly single quote' );
/* translators: en dash */
$en_dash = _x( '–', 'en dash' );
/* translators: em dash */
$em_dash = _x( '—', 'em dash' );
$default_no_texturize_tags = array('pre', 'code', 'kbd', 'style', 'script', 'tt');
$default_no_texturize_shortcodes = array('code');
// if a plugin has provided an autocorrect array, use it
if ( isset($wp_cockneyreplace) ) {
$cockney = array_keys($wp_cockneyreplace);
$cockneyreplace = array_values($wp_cockneyreplace);
} elseif ( "'" != $apos ) { // Only bother if we're doing a replacement.
$cockney = array( "'tain't", "'twere", "'twas", "'tis", "'twill", "'til", "'bout", "'nuff", "'round", "'cause" );
$cockneyreplace = array( $apos . "tain" . $apos . "t", $apos . "twere", $apos . "twas", $apos . "tis", $apos . "twill", $apos . "til", $apos . "bout", $apos . "nuff", $apos . "round", $apos . "cause" );
} else {
$cockney = $cockneyreplace = array();
}
$static_characters = array_merge( array( '...', '``', '\'\'', ' (tm)' ), $cockney );
$static_replacements = array_merge( array( '…', $opening_quote, $closing_quote, ' ™' ), $cockneyreplace );
// Pattern-based replacements of characters.
// Sort the remaining patterns into several arrays for performance tuning.
$dynamic_characters = array( 'apos' => array(), 'quote' => array(), 'dash' => array() );
$dynamic_replacements = array( 'apos' => array(), 'quote' => array(), 'dash' => array() );
$dynamic = array();
$spaces = wp_spaces_regexp();
// '99' and '99" are ambiguous among other patterns; assume it's an abbreviated year at the end of a quotation.
if ( "'" !== $apos || "'" !== $closing_single_quote ) {
$dynamic[ '/\'(\d\d)\'(?=\Z|[.,)}\-\]]|>|' . $spaces . ')/' ] = $apos . '$1' . $closing_single_quote;
}
if ( "'" !== $apos || '"' !== $closing_quote ) {
$dynamic[ '/\'(\d\d)"(?=\Z|[.,)}\-\]]|>|' . $spaces . ')/' ] = $apos . '$1' . $closing_quote;
}
// '99 '99s '99's (apostrophe) But never '9 or '99% or '999 or '99.0.
if ( "'" !== $apos ) {
$dynamic[ '/\'(?=\d\d(?:\Z|(?![%\d]|[.,]\d)))/' ] = $apos;
}
// Quoted Numbers like '0.42'
if ( "'" !== $opening_single_quote && "'" !== $closing_single_quote ) {
$dynamic[ '/(?<=\A|' . $spaces . ')\'(\d[.,\d]*)\'/' ] = $opening_single_quote . '$1' . $closing_single_quote;
}
// Single quote at start, or preceded by (, {, <, [, ", -, or spaces.
if ( "'" !== $opening_single_quote ) {
$dynamic[ '/(?<=\A|[([{"\-]|<|' . $spaces . ')\'/' ] = $opening_single_quote;
}
// Apostrophe in a word. No spaces, double apostrophes, or other punctuation.
if ( "'" !== $apos ) {
$dynamic[ '/(? is found.
. '-(?!->)' // Dash not followed by end of comment.
. '[^\-]*+' // Consume non-dashes.
. ')*+' // Loop possessively.
. '-->'; // End of comment.
$regex = '/(' // Capture the entire match.
. '<' // Find start of element.
. '(?(?=!--)' // Is this a comment?
. $comment_regex // Find end of comment
. '|'
. '[^>]+>' // Find end of element
. ')'
. '|'
. '\[' // 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 ]]
. ')/s';
$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 && '>' === substr( $curl, -1 ) ) {
// This is an HTML delimiter.
if ( ' " ) );
if ( strpos( $pee, '', $pee );
}
if ( strpos( $pee, '' ) !== false ) {
// no P/BR around param and embed
$pee = preg_replace( '|(|', '', $pee );
$pee = preg_replace( '%\s*(?(?:param|embed)[^>]*>)\s*%', '$1', $pee );
}
if ( strpos( $pee, '
\s*(?' . $allblocks . '[^>]*>)!', "$1", $pee); $pee = preg_replace('!(?' . $allblocks . '[^>]*>)\s*
!', "$1", $pee); if ( $br ) { $pee = preg_replace_callback('/<(script|style).*?<\/\\1>/s', '_autop_newline_preservation_helper', $pee); $pee = preg_replace('|(?)\s*\n|', ">...<
>. * * @since 2.9.0 * * @param string $pee The content. * @return string The filtered content. */ function shortcode_unautop( $pee ) { global $shortcode_tags; if ( empty( $shortcode_tags ) || !is_array( $shortcode_tags ) ) { return $pee; } $tagregexp = join( '|', array_map( 'preg_quote', array_keys( $shortcode_tags ) ) ); $spaces = wp_spaces_regexp(); $pattern = '/' . '' // Opening paragraph . '(?:' . $spaces . ')*+' // Optional leading whitespace . '(' // 1: The shortcode . '\\[' // Opening bracket . "($tagregexp)" // 2: Shortcode name . '(?![\\w-])' // Not followed by word character or hyphen // Unroll the loop: Inside the opening shortcode tag . '[^\\]\\/]*' // Not a closing bracket or forward slash . '(?:' . '\\/(?!\\])' // A forward slash not followed by a closing bracket . '[^\\]\\/]*' // Not a closing bracket or forward slash . ')*?' . '(?:' . '\\/\\]' // Self closing tag and closing bracket . '|' . '\\]' // Closing bracket . '(?:' // Unroll the loop: Optionally, anything between the opening and closing shortcode tags . '[^\\[]*+' // Not an opening bracket . '(?:' . '\\[(?!\\/\\2\\])' // An opening bracket not followed by the closing shortcode tag . '[^\\[]*+' // Not an opening bracket . ')*+' . '\\[\\/\\2\\]' // Closing shortcode tag . ')?' . ')' . ')' . '(?:' . $spaces . ')*+' // optional trailing whitespace . '<\\/p>' // closing paragraph . '/s'; return preg_replace( $pattern, '$1', $pee ); } /** * Checks to see if a string is utf8 encoded. * * NOTE: This function checks for 5-Byte sequences, UTF8 * has Bytes Sequences with a maximum length of 4. * * @author bmorel at ssi dot fr (modified) * @since 1.2.1 * * @param string $str The string to be checked * @return bool True if $str fits a UTF-8 model, false otherwise. */ function seems_utf8($str) { mbstring_binary_safe_encoding(); $length = strlen($str); reset_mbstring_encoding(); for ($i=0; $i < $length; $i++) { $c = ord($str[$i]); if ($c < 0x80) $n = 0; # 0bbbbbbb elseif (($c & 0xE0) == 0xC0) $n=1; # 110bbbbb elseif (($c & 0xF0) == 0xE0) $n=2; # 1110bbbb elseif (($c & 0xF8) == 0xF0) $n=3; # 11110bbb elseif (($c & 0xFC) == 0xF8) $n=4; # 111110bb elseif (($c & 0xFE) == 0xFC) $n=5; # 1111110b else return false; # Does not match any model for ($j=0; $j<$n; $j++) { # n bytes matching 10bbbbbb follow ? if ((++$i == $length) || ((ord($str[$i]) & 0xC0) != 0x80)) return false; } } return true; } /** * Converts a number of special characters into their HTML entities. * * Specifically deals with: &, <, >, ", and '. * * $quote_style can be set to ENT_COMPAT to encode " to * ", or ENT_QUOTES to do both. Default is ENT_NOQUOTES where no quotes are encoded. * * @since 1.2.2 * @access private * * @param string $string The text which is to be encoded. * @param mixed $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 boolean $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 ) { $string = (string) $string; if ( 0 === strlen( $string ) ) return ''; // Don't bother if there are no specialchars - saves some processing if ( ! preg_match( '/[&<>"\']/', $string ) ) return $string; // Account for the previous behaviour of the function when the $quote_style is not an accepted value if ( empty( $quote_style ) ) $quote_style = ENT_NOQUOTES; elseif ( ! in_array( $quote_style, array( 0, 2, 3, 'single', 'double' ), true ) ) $quote_style = ENT_QUOTES; // Store the site charset as a static to avoid multiple calls to wp_load_alloptions() if ( ! $charset ) { static $_charset; if ( ! isset( $_charset ) ) { $alloptions = wp_load_alloptions(); $_charset = isset( $alloptions['blog_charset'] ) ? $alloptions['blog_charset'] : ''; } $charset = $_charset; } if ( in_array( $charset, array( 'utf8', 'utf-8', 'UTF8' ) ) ) $charset = 'UTF-8'; $_quote_style = $quote_style; if ( $quote_style === 'double' ) { $quote_style = ENT_COMPAT; $_quote_style = ENT_COMPAT; } elseif ( $quote_style === 'single' ) { $quote_style = ENT_NOQUOTES; } // Handle double encoding ourselves if ( $double_encode ) { $string = @htmlspecialchars( $string, $quote_style, $charset ); } else { // Decode & into & $string = wp_specialchars_decode( $string, $_quote_style ); // Guarantee every &entity; is valid or re-encode the & $string = wp_kses_normalize_entities( $string ); // Now re-encode everything except &entity; $string = preg_split( '/(?x?[0-9a-z]+;)/i', $string, -1, PREG_SPLIT_DELIM_CAPTURE ); for ( $i = 0; $i < count( $string ); $i += 2 ) $string[$i] = @htmlspecialchars( $string[$i], $quote_style, $charset ); $string = implode( '', $string ); } // Backwards compatibility if ( 'single' === $_quote_style ) $string = str_replace( "'", ''', $string ); return $string; } /** * Converts a number of HTML entities into their special characters. * * Specifically deals with: &, <, >, ", and '. * * $quote_style can be set to ENT_COMPAT to decode " entities, * or ENT_QUOTES to do both " and '. Default is ENT_NOQUOTES where no quotes are decoded. * * @since 2.8.0 * * @param string $string The text which is to be decoded. * @param mixed $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 _wp_specialchars() values; converting single quotes if set to 'single', double if set to 'double' or both if otherwise set. Default is ENT_NOQUOTES. * @return string The decoded text without HTML entities. */ function wp_specialchars_decode( $string, $quote_style = ENT_NOQUOTES ) { $string = (string) $string; if ( 0 === strlen( $string ) ) { return ''; } // Don't bother if there are no entities - saves a lot of processing if ( strpos( $string, '&' ) === false ) { return $string; } // Match the previous behaviour of _wp_specialchars() when the $quote_style is not an accepted value if ( empty( $quote_style ) ) { $quote_style = ENT_NOQUOTES; } elseif ( !in_array( $quote_style, array( 0, 2, 3, 'single', 'double' ), true ) ) { $quote_style = ENT_QUOTES; } // More complete than get_html_translation_table( HTML_SPECIALCHARS ) $single = array( ''' => '\'', ''' => '\'' ); $single_preg = array( '/*39;/' => ''', '/*27;/i' => ''' ); $double = array( '"' => '"', '"' => '"', '"' => '"' ); $double_preg = array( '/*34;/' => '"', '/*22;/i' => '"' ); $others = array( '<' => '<', '<' => '<', '>' => '>', '>' => '>', '&' => '&', '&' => '&', '&' => '&' ); $others_preg = array( '/*60;/' => '<', '/*62;/' => '>', '/*38;/' => '&', '/*26;/i' => '&' ); if ( $quote_style === ENT_QUOTES ) { $translation = array_merge( $single, $double, $others ); $translation_preg = array_merge( $single_preg, $double_preg, $others_preg ); } elseif ( $quote_style === ENT_COMPAT || $quote_style === 'double' ) { $translation = array_merge( $double, $others ); $translation_preg = array_merge( $double_preg, $others_preg ); } elseif ( $quote_style === 'single' ) { $translation = array_merge( $single, $others ); $translation_preg = array_merge( $single_preg, $others_preg ); } elseif ( $quote_style === ENT_NOQUOTES ) { $translation = $others; $translation_preg = $others_preg; } // Remove zero padding on numeric entities $string = preg_replace( array_keys( $translation_preg ), array_values( $translation_preg ), $string ); // Replace characters according to translation table return strtr( $string, $translation ); } /** * Checks for invalid UTF8 in a string. * * @since 2.8.0 * * @param string $string The text which is to be checked. * @param boolean $strip Optional. Whether to attempt to strip out invalid UTF8. Default is false. * @return string The checked text. */ function wp_check_invalid_utf8( $string, $strip = false ) { $string = (string) $string; if ( 0 === strlen( $string ) ) { return ''; } // Store the site charset as a static to avoid multiple calls to get_option() static $is_utf8; if ( !isset( $is_utf8 ) ) { $is_utf8 = in_array( get_option( 'blog_charset' ), array( 'utf8', 'utf-8', 'UTF8', 'UTF-8' ) ); } if ( !$is_utf8 ) { return $string; } // Check for support for utf8 in the installed PCRE library once and store the result in a static static $utf8_pcre; if ( !isset( $utf8_pcre ) ) { $utf8_pcre = @preg_match( '/^./u', 'a' ); } // We can't demand utf8 in the PCRE installation, so just return the string in those cases if ( !$utf8_pcre ) { return $string; } // preg_match fails when it encounters invalid UTF8 in $string if ( 1 === @preg_match( '/^./us', $string ) ) { return $string; } // Attempt to strip the bad chars if requested (not recommended) if ( $strip && function_exists( 'iconv' ) ) { return iconv( 'utf-8', 'utf-8', $string ); } return ''; } /** * Encode the Unicode values to be used in the URI. * * @since 1.5.0 * * @param string $utf8_string * @param int $length Max length of the string * @return string String with Unicode encoded for URI. */ function utf8_uri_encode( $utf8_string, $length = 0 ) { $unicode = ''; $values = array(); $num_octets = 1; $unicode_length = 0; mbstring_binary_safe_encoding(); $string_length = strlen( $utf8_string ); reset_mbstring_encoding(); for ($i = 0; $i < $string_length; $i++ ) { $value = ord( $utf8_string[ $i ] ); if ( $value < 128 ) { if ( $length && ( $unicode_length >= $length ) ) break; $unicode .= chr($value); $unicode_length++; } else { if ( count( $values ) == 0 ) $num_octets = ( $value < 224 ) ? 2 : 3; $values[] = $value; if ( $length && ( $unicode_length + ($num_octets * 3) ) > $length ) break; if ( count( $values ) == $num_octets ) { if ($num_octets == 3) { $unicode .= '%' . dechex($values[0]) . '%' . dechex($values[1]) . '%' . dechex($values[2]); $unicode_length += 9; } else { $unicode .= '%' . dechex($values[0]) . '%' . dechex($values[1]); $unicode_length += 6; } $values = array(); $num_octets = 1; } } } return $unicode; } /** * Converts all accent characters to ASCII characters. * * If there are no accent characters, then the string given is just returned. * * @since 1.2.1 * * @param string $string Text that might have accent characters * @return string Filtered string with replaced "nice" characters. */ function remove_accents($string) { if ( !preg_match('/[\x80-\xff]/', $string) ) return $string; if (seems_utf8($string)) { $chars = array( // Decompositions for Latin-1 Supplement chr(194).chr(170) => 'a', chr(194).chr(186) => 'o', chr(195).chr(128) => 'A', chr(195).chr(129) => 'A', chr(195).chr(130) => 'A', chr(195).chr(131) => 'A', chr(195).chr(132) => 'A', chr(195).chr(133) => 'A', chr(195).chr(134) => 'AE',chr(195).chr(135) => 'C', chr(195).chr(136) => 'E', chr(195).chr(137) => 'E', chr(195).chr(138) => 'E', chr(195).chr(139) => 'E', chr(195).chr(140) => 'I', chr(195).chr(141) => 'I', chr(195).chr(142) => 'I', chr(195).chr(143) => 'I', chr(195).chr(144) => 'D', chr(195).chr(145) => 'N', chr(195).chr(146) => 'O', chr(195).chr(147) => 'O', chr(195).chr(148) => 'O', chr(195).chr(149) => 'O', chr(195).chr(150) => 'O', chr(195).chr(153) => 'U', chr(195).chr(154) => 'U', chr(195).chr(155) => 'U', chr(195).chr(156) => 'U', chr(195).chr(157) => 'Y', chr(195).chr(158) => 'TH',chr(195).chr(159) => 's', chr(195).chr(160) => 'a', chr(195).chr(161) => 'a', chr(195).chr(162) => 'a', chr(195).chr(163) => 'a', chr(195).chr(164) => 'a', chr(195).chr(165) => 'a', chr(195).chr(166) => 'ae',chr(195).chr(167) => 'c', chr(195).chr(168) => 'e', chr(195).chr(169) => 'e', chr(195).chr(170) => 'e', chr(195).chr(171) => 'e', chr(195).chr(172) => 'i', chr(195).chr(173) => 'i', chr(195).chr(174) => 'i', chr(195).chr(175) => 'i', chr(195).chr(176) => 'd', chr(195).chr(177) => 'n', chr(195).chr(178) => 'o', chr(195).chr(179) => 'o', chr(195).chr(180) => 'o', chr(195).chr(181) => 'o', chr(195).chr(182) => 'o', chr(195).chr(184) => 'o', chr(195).chr(185) => 'u', chr(195).chr(186) => 'u', chr(195).chr(187) => 'u', chr(195).chr(188) => 'u', chr(195).chr(189) => 'y', chr(195).chr(190) => 'th', chr(195).chr(191) => 'y', chr(195).chr(152) => 'O', // Decompositions for Latin Extended-A chr(196).chr(128) => 'A', chr(196).chr(129) => 'a', chr(196).chr(130) => 'A', chr(196).chr(131) => 'a', chr(196).chr(132) => 'A', chr(196).chr(133) => 'a', chr(196).chr(134) => 'C', chr(196).chr(135) => 'c', chr(196).chr(136) => 'C', chr(196).chr(137) => 'c', chr(196).chr(138) => 'C', chr(196).chr(139) => 'c', chr(196).chr(140) => 'C', chr(196).chr(141) => 'c', chr(196).chr(142) => 'D', chr(196).chr(143) => 'd', chr(196).chr(144) => 'D', chr(196).chr(145) => 'd', chr(196).chr(146) => 'E', chr(196).chr(147) => 'e', chr(196).chr(148) => 'E', chr(196).chr(149) => 'e', chr(196).chr(150) => 'E', chr(196).chr(151) => 'e', chr(196).chr(152) => 'E', chr(196).chr(153) => 'e', chr(196).chr(154) => 'E', chr(196).chr(155) => 'e', chr(196).chr(156) => 'G', chr(196).chr(157) => 'g', chr(196).chr(158) => 'G', chr(196).chr(159) => 'g', chr(196).chr(160) => 'G', chr(196).chr(161) => 'g', chr(196).chr(162) => 'G', chr(196).chr(163) => 'g', chr(196).chr(164) => 'H', chr(196).chr(165) => 'h', chr(196).chr(166) => 'H', chr(196).chr(167) => 'h', chr(196).chr(168) => 'I', chr(196).chr(169) => 'i', chr(196).chr(170) => 'I', chr(196).chr(171) => 'i', chr(196).chr(172) => 'I', chr(196).chr(173) => 'i', chr(196).chr(174) => 'I', chr(196).chr(175) => 'i', chr(196).chr(176) => 'I', chr(196).chr(177) => 'i', chr(196).chr(178) => 'IJ',chr(196).chr(179) => 'ij', chr(196).chr(180) => 'J', chr(196).chr(181) => 'j', chr(196).chr(182) => 'K', chr(196).chr(183) => 'k', chr(196).chr(184) => 'k', chr(196).chr(185) => 'L', chr(196).chr(186) => 'l', chr(196).chr(187) => 'L', chr(196).chr(188) => 'l', chr(196).chr(189) => 'L', chr(196).chr(190) => 'l', chr(196).chr(191) => 'L', chr(197).chr(128) => 'l', chr(197).chr(129) => 'L', chr(197).chr(130) => 'l', chr(197).chr(131) => 'N', chr(197).chr(132) => 'n', chr(197).chr(133) => 'N', chr(197).chr(134) => 'n', chr(197).chr(135) => 'N', chr(197).chr(136) => 'n', chr(197).chr(137) => 'N', chr(197).chr(138) => 'n', chr(197).chr(139) => 'N', chr(197).chr(140) => 'O', chr(197).chr(141) => 'o', chr(197).chr(142) => 'O', chr(197).chr(143) => 'o', chr(197).chr(144) => 'O', chr(197).chr(145) => 'o', chr(197).chr(146) => 'OE',chr(197).chr(147) => 'oe', chr(197).chr(148) => 'R',chr(197).chr(149) => 'r', chr(197).chr(150) => 'R',chr(197).chr(151) => 'r', chr(197).chr(152) => 'R',chr(197).chr(153) => 'r', chr(197).chr(154) => 'S',chr(197).chr(155) => 's', chr(197).chr(156) => 'S',chr(197).chr(157) => 's', chr(197).chr(158) => 'S',chr(197).chr(159) => 's', chr(197).chr(160) => 'S', chr(197).chr(161) => 's', chr(197).chr(162) => 'T', chr(197).chr(163) => 't', chr(197).chr(164) => 'T', chr(197).chr(165) => 't', chr(197).chr(166) => 'T', chr(197).chr(167) => 't', chr(197).chr(168) => 'U', chr(197).chr(169) => 'u', chr(197).chr(170) => 'U', chr(197).chr(171) => 'u', chr(197).chr(172) => 'U', chr(197).chr(173) => 'u', chr(197).chr(174) => 'U', chr(197).chr(175) => 'u', chr(197).chr(176) => 'U', chr(197).chr(177) => 'u', chr(197).chr(178) => 'U', chr(197).chr(179) => 'u', chr(197).chr(180) => 'W', chr(197).chr(181) => 'w', chr(197).chr(182) => 'Y', chr(197).chr(183) => 'y', chr(197).chr(184) => 'Y', chr(197).chr(185) => 'Z', chr(197).chr(186) => 'z', chr(197).chr(187) => 'Z', chr(197).chr(188) => 'z', chr(197).chr(189) => 'Z', chr(197).chr(190) => 'z', chr(197).chr(191) => 's', // Decompositions for Latin Extended-B chr(200).chr(152) => 'S', chr(200).chr(153) => 's', chr(200).chr(154) => 'T', chr(200).chr(155) => 't', // Euro Sign chr(226).chr(130).chr(172) => 'E', // GBP (Pound) Sign chr(194).chr(163) => '', // Vowels with diacritic (Vietnamese) // unmarked chr(198).chr(160) => 'O', chr(198).chr(161) => 'o', chr(198).chr(175) => 'U', chr(198).chr(176) => 'u', // grave accent chr(225).chr(186).chr(166) => 'A', chr(225).chr(186).chr(167) => 'a', chr(225).chr(186).chr(176) => 'A', chr(225).chr(186).chr(177) => 'a', chr(225).chr(187).chr(128) => 'E', chr(225).chr(187).chr(129) => 'e', chr(225).chr(187).chr(146) => 'O', chr(225).chr(187).chr(147) => 'o', chr(225).chr(187).chr(156) => 'O', chr(225).chr(187).chr(157) => 'o', chr(225).chr(187).chr(170) => 'U', chr(225).chr(187).chr(171) => 'u', chr(225).chr(187).chr(178) => 'Y', chr(225).chr(187).chr(179) => 'y', // hook chr(225).chr(186).chr(162) => 'A', chr(225).chr(186).chr(163) => 'a', chr(225).chr(186).chr(168) => 'A', chr(225).chr(186).chr(169) => 'a', chr(225).chr(186).chr(178) => 'A', chr(225).chr(186).chr(179) => 'a', chr(225).chr(186).chr(186) => 'E', chr(225).chr(186).chr(187) => 'e', chr(225).chr(187).chr(130) => 'E', chr(225).chr(187).chr(131) => 'e', chr(225).chr(187).chr(136) => 'I', chr(225).chr(187).chr(137) => 'i', chr(225).chr(187).chr(142) => 'O', chr(225).chr(187).chr(143) => 'o', chr(225).chr(187).chr(148) => 'O', chr(225).chr(187).chr(149) => 'o', chr(225).chr(187).chr(158) => 'O', chr(225).chr(187).chr(159) => 'o', chr(225).chr(187).chr(166) => 'U', chr(225).chr(187).chr(167) => 'u', chr(225).chr(187).chr(172) => 'U', chr(225).chr(187).chr(173) => 'u', chr(225).chr(187).chr(182) => 'Y', chr(225).chr(187).chr(183) => 'y', // tilde chr(225).chr(186).chr(170) => 'A', chr(225).chr(186).chr(171) => 'a', chr(225).chr(186).chr(180) => 'A', chr(225).chr(186).chr(181) => 'a', chr(225).chr(186).chr(188) => 'E', chr(225).chr(186).chr(189) => 'e', chr(225).chr(187).chr(132) => 'E', chr(225).chr(187).chr(133) => 'e', chr(225).chr(187).chr(150) => 'O', chr(225).chr(187).chr(151) => 'o', chr(225).chr(187).chr(160) => 'O', chr(225).chr(187).chr(161) => 'o', chr(225).chr(187).chr(174) => 'U', chr(225).chr(187).chr(175) => 'u', chr(225).chr(187).chr(184) => 'Y', chr(225).chr(187).chr(185) => 'y', // acute accent chr(225).chr(186).chr(164) => 'A', chr(225).chr(186).chr(165) => 'a', chr(225).chr(186).chr(174) => 'A', chr(225).chr(186).chr(175) => 'a', chr(225).chr(186).chr(190) => 'E', chr(225).chr(186).chr(191) => 'e', chr(225).chr(187).chr(144) => 'O', chr(225).chr(187).chr(145) => 'o', chr(225).chr(187).chr(154) => 'O', chr(225).chr(187).chr(155) => 'o', chr(225).chr(187).chr(168) => 'U', chr(225).chr(187).chr(169) => 'u', // dot below chr(225).chr(186).chr(160) => 'A', chr(225).chr(186).chr(161) => 'a', chr(225).chr(186).chr(172) => 'A', chr(225).chr(186).chr(173) => 'a', chr(225).chr(186).chr(182) => 'A', chr(225).chr(186).chr(183) => 'a', chr(225).chr(186).chr(184) => 'E', chr(225).chr(186).chr(185) => 'e', chr(225).chr(187).chr(134) => 'E', chr(225).chr(187).chr(135) => 'e', chr(225).chr(187).chr(138) => 'I', chr(225).chr(187).chr(139) => 'i', chr(225).chr(187).chr(140) => 'O', chr(225).chr(187).chr(141) => 'o', chr(225).chr(187).chr(152) => 'O', chr(225).chr(187).chr(153) => 'o', chr(225).chr(187).chr(162) => 'O', chr(225).chr(187).chr(163) => 'o', chr(225).chr(187).chr(164) => 'U', chr(225).chr(187).chr(165) => 'u', chr(225).chr(187).chr(176) => 'U', chr(225).chr(187).chr(177) => 'u', chr(225).chr(187).chr(180) => 'Y', chr(225).chr(187).chr(181) => 'y', // Vowels with diacritic (Chinese, Hanyu Pinyin) chr(201).chr(145) => 'a', // macron chr(199).chr(149) => 'U', chr(199).chr(150) => 'u', // acute accent chr(199).chr(151) => 'U', chr(199).chr(152) => 'u', // caron chr(199).chr(141) => 'A', chr(199).chr(142) => 'a', chr(199).chr(143) => 'I', chr(199).chr(144) => 'i', chr(199).chr(145) => 'O', chr(199).chr(146) => 'o', chr(199).chr(147) => 'U', chr(199).chr(148) => 'u', chr(199).chr(153) => 'U', chr(199).chr(154) => 'u', // grave accent chr(199).chr(155) => 'U', chr(199).chr(156) => 'u', ); // Used for locale-specific rules $locale = get_locale(); if ( 'de_DE' == $locale ) { $chars[ chr(195).chr(132) ] = 'Ae'; $chars[ chr(195).chr(164) ] = 'ae'; $chars[ chr(195).chr(150) ] = 'Oe'; $chars[ chr(195).chr(182) ] = 'oe'; $chars[ chr(195).chr(156) ] = 'Ue'; $chars[ chr(195).chr(188) ] = 'ue'; $chars[ chr(195).chr(159) ] = 'ss'; } elseif ( 'da_DK' === $locale ) { $chars[ chr(195).chr(134) ] = 'Ae'; $chars[ chr(195).chr(166) ] = 'ae'; $chars[ chr(195).chr(152) ] = 'Oe'; $chars[ chr(195).chr(184) ] = 'oe'; $chars[ chr(195).chr(133) ] = 'Aa'; $chars[ chr(195).chr(165) ] = 'aa'; } $string = strtr($string, $chars); } else { // Assume ISO-8859-1 if not UTF-8 $chars['in'] = chr(128).chr(131).chr(138).chr(142).chr(154).chr(158) .chr(159).chr(162).chr(165).chr(181).chr(192).chr(193).chr(194) .chr(195).chr(196).chr(197).chr(199).chr(200).chr(201).chr(202) .chr(203).chr(204).chr(205).chr(206).chr(207).chr(209).chr(210) .chr(211).chr(212).chr(213).chr(214).chr(216).chr(217).chr(218) .chr(219).chr(220).chr(221).chr(224).chr(225).chr(226).chr(227) .chr(228).chr(229).chr(231).chr(232).chr(233).chr(234).chr(235) .chr(236).chr(237).chr(238).chr(239).chr(241).chr(242).chr(243) .chr(244).chr(245).chr(246).chr(248).chr(249).chr(250).chr(251) .chr(252).chr(253).chr(255); $chars['out'] = "EfSZszYcYuAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy"; $string = strtr($string, $chars['in'], $chars['out']); $double_chars['in'] = array(chr(140), chr(156), chr(198), chr(208), chr(222), chr(223), chr(230), chr(240), chr(254)); $double_chars['out'] = array('OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th'); $string = str_replace($double_chars['in'], $double_chars['out'], $string); } return $string; } /** * Sanitizes a filename, replacing whitespace with dashes. * * Removes special characters that are illegal in filenames on certain * operating systems and special characters requiring special escaping * to manipulate at the command line. Replaces spaces and consecutive * dashes with a single dash. Trims period, dash and underscore from beginning * and end of filename. It is not guaranteed that this function will return a * filename that is allowed to be uploaded. * * @since 2.1.0 * * @param string $filename The filename to be sanitized * @return string The sanitized filename */ function sanitize_file_name( $filename ) { $filename_raw = $filename; $special_chars = array("?", "[", "]", "/", "\\", "=", "<", ">", ":", ";", ",", "'", "\"", "&", "$", "#", "*", "(", ")", "|", "~", "`", "!", "{", "}", chr(0)); /** * Filter the list of characters to remove from a filename. * * @since 2.8.0 * * @param array $special_chars Characters to remove. * @param string $filename_raw Filename as it was passed into sanitize_file_name(). */ $special_chars = apply_filters( 'sanitize_file_name_chars', $special_chars, $filename_raw ); $filename = preg_replace( "#\x{00a0}#siu", ' ', $filename ); $filename = str_replace($special_chars, '', $filename); $filename = str_replace( array( '%20', '+' ), '-', $filename ); $filename = preg_replace('/[\s-]+/', '-', $filename); $filename = trim($filename, '.-_'); if ( false === strpos( $filename, '.' ) ) { $mime_types = wp_get_mime_types(); $filetype = wp_check_filetype( 'test.' . $filename, $mime_types ); if ( $filetype['ext'] === $filename ) { $filename = 'unnamed-file.' . $filetype['ext']; } } // Split the filename into a base and extension[s] $parts = explode('.', $filename); // Return if only one extension if ( count( $parts ) <= 2 ) { /** * Filter a sanitized filename string. * * @since 2.8.0 * * @param string $filename Sanitized filename. * @param string $filename_raw The filename prior to sanitization. */ return apply_filters( 'sanitize_file_name', $filename, $filename_raw ); } // Process multiple extensions $filename = array_shift($parts); $extension = array_pop($parts); $mimes = get_allowed_mime_types(); /* * Loop over any intermediate extensions. Postfix them with a trailing underscore * if they are a 2 - 5 character long alpha string not in the extension whitelist. */ foreach ( (array) $parts as $part) { $filename .= '.' . $part; if ( preg_match("/^[a-zA-Z]{2,5}\d?$/", $part) ) { $allowed = false; foreach ( $mimes as $ext_preg => $mime_match ) { $ext_preg = '!^(' . $ext_preg . ')$!i'; if ( preg_match( $ext_preg, $part ) ) { $allowed = true; break; } } if ( !$allowed ) $filename .= '_'; } } $filename .= '.' . $extension; /** This filter is documented in wp-includes/formatting.php */ return apply_filters('sanitize_file_name', $filename, $filename_raw); } /** * Sanitizes a username, stripping out unsafe characters. * * Removes tags, octets, entities, and if strict is enabled, will only keep * alphanumeric, _, space, ., -, @. After sanitizing, it passes the username, * raw username (the username in the parameter), and the value of $strict as * parameters for the 'sanitize_user' filter. * * @since 2.0.0 * * @param string $username The username to be sanitized. * @param bool $strict If set limits $username to specific characters. Default false. * @return string The sanitized username, after passing through filters. */ function sanitize_user( $username, $strict = false ) { $raw_username = $username; $username = wp_strip_all_tags( $username ); $username = remove_accents( $username ); // Kill octets $username = preg_replace( '|%([a-fA-F0-9][a-fA-F0-9])|', '', $username ); $username = preg_replace( '/&.+?;/', '', $username ); // Kill entities // If strict, reduce to ASCII for max portability. if ( $strict ) $username = preg_replace( '|[^a-z0-9 _.\-@]|i', '', $username ); $username = trim( $username ); // Consolidate contiguous whitespace $username = preg_replace( '|\s+|', ' ', $username ); /** * Filter a sanitized username string. * * @since 2.0.1 * * @param string $username Sanitized username. * @param string $raw_username The username prior to sanitization. * @param bool $strict Whether to limit the sanitization to specific characters. Default false. */ return apply_filters( 'sanitize_user', $username, $raw_username, $strict ); } /** * Sanitizes a string key. * * Keys are used as internal identifiers. Lowercase alphanumeric characters, dashes and underscores are allowed. * * @since 3.0.0 * * @param string $key String key * @return string Sanitized key */ function sanitize_key( $key ) { $raw_key = $key; $key = strtolower( $key ); $key = preg_replace( '/[^a-z0-9_\-]/', '', $key ); /** * Filter a sanitized key string. * * @since 3.0.0 * * @param string $key Sanitized key. * @param string $raw_key The key prior to sanitization. */ return apply_filters( 'sanitize_key', $key, $raw_key ); } /** * Sanitizes a title, or returns a fallback title. * * Specifically, HTML and PHP tags are stripped. Further actions can be added * via the plugin API. If $title is empty and $fallback_title is set, the latter * will be used. * * @since 1.0.0 * * @param string $title The string to be sanitized. * @param string $fallback_title Optional. A title to use if $title is empty. * @param string $context Optional. The operation for which the string is sanitized * @return string The sanitized string. */ function sanitize_title( $title, $fallback_title = '', $context = 'save' ) { $raw_title = $title; if ( 'save' == $context ) $title = remove_accents($title); /** * Filter a sanitized title string. * * @since 1.2.0 * * @param string $title Sanitized title. * @param string $raw_title The title prior to sanitization. * @param string $context The context for which the title is being sanitized. */ $title = apply_filters( 'sanitize_title', $title, $raw_title, $context ); if ( '' === $title || false === $title ) $title = $fallback_title; return $title; } /** * Sanitizes a title with the 'query' context. * * Used for querying the database for a value from URL. * * @since 3.1.0 * @uses sanitize_title() * * @param string $title The string to be sanitized. * @return string The sanitized string. */ function sanitize_title_for_query( $title ) { return sanitize_title( $title, '', 'query' ); } /** * Sanitizes a title, replacing whitespace and a few other characters with dashes. * * Limits the output to alphanumeric characters, underscore (_) and dash (-). * Whitespace becomes a dash. * * @since 1.2.0 * * @param string $title The title to be sanitized. * @param string $raw_title Optional. Not used. * @param string $context Optional. The operation for which the string is sanitized. * @return string The sanitized title. */ function sanitize_title_with_dashes( $title, $raw_title = '', $context = 'display' ) { $title = strip_tags($title); // Preserve escaped octets. $title = preg_replace('|%([a-fA-F0-9][a-fA-F0-9])|', '---$1---', $title); // Remove percent signs that are not part of an octet. $title = str_replace('%', '', $title); // Restore octets. $title = preg_replace('|---([a-fA-F0-9][a-fA-F0-9])---|', '%$1', $title); if (seems_utf8($title)) { if (function_exists('mb_strtolower')) { $title = mb_strtolower($title, 'UTF-8'); } $title = utf8_uri_encode($title, 200); } $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 ); // Strip these characters entirely $title = str_replace( array( // iexcl and iquest '%c2%a1', '%c2%bf', // angle quotes '%c2%ab', '%c2%bb', '%e2%80%b9', '%e2%80%ba', // curly quotes '%e2%80%98', '%e2%80%99', '%e2%80%9c', '%e2%80%9d', '%e2%80%9a', '%e2%80%9b', '%e2%80%9e', '%e2%80%9f', // copy, reg, deg, hellip and trade '%c2%a9', '%c2%ae', '%c2%b0', '%e2%80%a6', '%e2%84%a2', // acute accents '%c2%b4', '%cb%8a', '%cc%81', '%cd%81', // grave accent, macron, caron '%cc%80', '%cc%84', '%cc%8c', ), '', $title ); // Convert times to x $title = str_replace( '%c3%97', 'x', $title ); } $title = preg_replace('/[^%a-z0-9 _-]/', '', $title); $title = preg_replace('/\s+/', '-', $title); $title = preg_replace('|-+|', '-', $title); $title = trim($title, '-'); return $title; } /** * Ensures a string is a valid SQL 'order by' clause. * * Accepts one or more columns, with or without a sort order (ASC / DESC). * e.g. 'column_1', 'column_1, column_2', 'column_1 ASC, column_2 DESC' etc. * * Also accepts 'RAND()'. * * @since 2.5.1 * * @param string $orderby Order by clause to be validated. * @return string|bool Returns $orderby if valid, false otherwise. */ function sanitize_sql_orderby( $orderby ) { if ( preg_match( '/^\s*(([a-z0-9_]+|`[a-z0-9_]+`)(\s+(ASC|DESC))?\s*(,\s*(?=[a-z0-9_`])|$))+$/i', $orderby ) || preg_match( '/^\s*RAND\(\s*\)\s*$/i', $orderby ) ) { return $orderby; } return false; } /** * Sanitizes an HTML classname to ensure it only contains valid characters. * * Strips the string down to A-Z,a-z,0-9,_,-. If this results in an empty * string then it will return the alternative value supplied. * * @todo Expand to support the full range of CDATA that a class attribute can contain. * * @since 2.8.0 * * @param string $class The classname to be sanitized * @param string $fallback Optional. The value to return if the sanitization ends up as an empty string. * Defaults to an empty string. * @return string The sanitized value */ function sanitize_html_class( $class, $fallback = '' ) { //Strip out any % encoded octets $sanitized = preg_replace( '|%[a-fA-F0-9][a-fA-F0-9]|', '', $class ); //Limit to A-Z,a-z,0-9,_,- $sanitized = preg_replace( '/[^A-Za-z0-9_-]/', '', $sanitized ); if ( '' == $sanitized ) $sanitized = $fallback; /** * Filter a sanitized HTML class string. * * @since 2.8.0 * * @param string $sanitized The sanitized HTML class. * @param string $class HTML class before sanitization. * @param string $fallback The fallback string. */ return apply_filters( 'sanitize_html_class', $sanitized, $class, $fallback ); } /** * Converts a number of characters from a string. * * Metadata tags <