2004-02-09 01:57:02 -05:00
< ? php
2008-08-17 07:29:43 -04:00
/**
2009-12-08 14:59:34 -05:00
* Main WordPress Formatting API .
2008-08-17 07:29:43 -04:00
*
2008-08-27 02:49:21 -04:00
* Handles many functions for formatting output .
2008-08-17 07:29:43 -04:00
*
* @ package WordPress
2013-02-01 13:07:08 -05:00
*/
2004-02-09 01:57:02 -05:00
2008-08-17 07:29:43 -04:00
/**
* Replaces common plain text characters into formatted entities
*
2008-08-30 17:28:11 -04:00
* As an example ,
2014-11-24 00:30:25 -05:00
*
* 'cause today' s effort makes it worth tomorrow ' s " holiday " ...
*
2008-08-17 07:29:43 -04:00
* Becomes :
2014-11-24 00:30:25 -05:00
*
* & #8217;cause today’s effort makes it worth tomorrow’s “holiday” …
*
2008-08-27 02:49:21 -04:00
* Code within certain html blocks are skipped .
2008-08-17 07:29:43 -04:00
*
* @ since 0.71
* @ uses $wp_cockneyreplace Array of formatted entities for certain common phrases
*
* @ param string $text The text to be formatted
2014-06-17 13:57:14 -04:00
* @ param bool $reset Set to true for unit testing . Translated patterns will reset .
2008-08-17 07:29:43 -04:00
* @ return string The string replaced with html entities
*/
2014-06-17 13:57:14 -04:00
function wptexturize ( $text , $reset = false ) {
2014-11-20 09:28:23 -05:00
global $wp_cockneyreplace , $shortcode_tags ;
2012-01-31 09:28:30 -05:00
static $static_characters , $static_replacements , $dynamic_characters , $dynamic_replacements ,
2014-06-09 21:46:14 -04:00
$default_no_texturize_tags , $default_no_texturize_shortcodes , $run_texturize = true ;
2014-06-17 13:57:14 -04:00
// If there's nothing to do, just stop.
if ( empty ( $text ) || false === $run_texturize ) {
2014-06-09 21:46:14 -04:00
return $text ;
}
2010-01-15 17:11:12 -05:00
2014-06-17 13:57:14 -04:00
// Set up static variables. Run once only.
if ( $reset || ! isset ( $static_characters ) ) {
2014-06-10 02:29:14 -04:00
/**
2014-07-13 21:02:15 -04:00
* Filter whether to skip running wptexturize () .
2014-06-10 02:29:14 -04:00
*
2014-07-13 21:02:15 -04:00
* Passing false to the filter will effectively short - circuit wptexturize () .
2014-06-10 02:29:14 -04:00
* returning the original text passed to the function instead .
*
2014-07-13 21:02:15 -04:00
* The filter runs only once , the first time wptexturize () is called .
2014-06-10 02:29:14 -04:00
*
* @ since 4.0 . 0
*
2014-07-13 21:02:15 -04:00
* @ see wptexturize ()
*
* @ param bool $run_texturize Whether to short - circuit wptexturize () .
2014-06-10 02:29:14 -04:00
*/
2014-06-09 21:46:14 -04:00
$run_texturize = apply_filters ( 'run_wptexturize' , $run_texturize );
if ( false === $run_texturize ) {
return $text ;
}
2012-01-31 09:06:32 -05:00
/* 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' );
2011-11-06 13:31:54 -05:00
/* translators: en dash */
2012-01-31 09:06:32 -05:00
$en_dash = _x ( '–' , 'en dash' );
2011-11-06 13:31:54 -05:00
/* translators: em dash */
2012-01-31 09:06:32 -05:00
$em_dash = _x ( '—' , 'em dash' );
2009-09-14 10:03:32 -04:00
2009-10-21 17:57:27 -04:00
$default_no_texturize_tags = array ( 'pre' , 'code' , 'kbd' , 'style' , 'script' , 'tt' );
$default_no_texturize_shortcodes = array ( 'code' );
2009-09-14 10:03:32 -04:00
2009-10-21 17:57:27 -04:00
// if a plugin has provided an autocorrect array, use it
if ( isset ( $wp_cockneyreplace ) ) {
2015-01-20 13:44:26 -05:00
$cockney = array_keys ( $wp_cockneyreplace );
$cockneyreplace = array_values ( $wp_cockneyreplace );
2012-01-31 09:06:32 -05:00
} elseif ( " ' " != $apos ) { // Only bother if we're doing a replacement.
2015-01-20 13:44:26 -05:00
$cockney = array ( " 'tain't " , " 'twere " , " 'twas " , " 'tis " , " 'twill " , " 'til " , " 'bout " , " 'nuff " , " 'round " , " 'cause " , " 'em " );
$cockneyreplace = array ( $apos . " tain " . $apos . " t " , $apos . " twere " , $apos . " twas " , $apos . " tis " , $apos . " twill " , $apos . " til " , $apos . " bout " , $apos . " nuff " , $apos . " round " , $apos . " cause " , $apos . " em " );
2009-10-21 17:57:27 -04:00
} else {
2012-01-31 09:06:32 -05:00
$cockney = $cockneyreplace = array ();
}
2014-06-10 10:22:15 -04:00
$static_characters = array_merge ( array ( '...' , '``' , '\'\'' , ' (tm)' ), $cockney );
$static_replacements = array_merge ( array ( '…' , $opening_quote , $closing_quote , ' ™' ), $cockneyreplace );
2012-01-31 09:06:32 -05:00
2014-03-29 03:16:16 -04:00
// Pattern-based replacements of characters.
2014-07-03 21:15:15 -04:00
// 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 () );
2012-01-31 09:06:32 -05:00
$dynamic = array ();
2014-07-03 21:15:15 -04:00
$spaces = wp_spaces_regexp ();
2014-03-29 03:16:16 -04:00
2014-06-17 16:14:15 -04:00
// '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 ) {
2014-07-03 12:22:14 -04:00
$dynamic [ '/\'(\d\d)\'(?=\Z|[.,)}\-\]]|>|' . $spaces . ')/' ] = $apos . '$1' . $closing_single_quote ;
2014-06-17 13:41:15 -04:00
}
2014-06-17 16:14:15 -04:00
if ( " ' " !== $apos || '"' !== $closing_quote ) {
2014-07-03 12:22:14 -04:00
$dynamic [ '/\'(\d\d)"(?=\Z|[.,)}\-\]]|>|' . $spaces . ')/' ] = $apos . '$1' . $closing_quote ;
2014-06-17 16:14:15 -04:00
}
2014-06-17 16:19:14 -04:00
// '99 '99s '99's (apostrophe) But never '9 or '99% or '999 or '99.0.
2014-06-17 13:41:15 -04:00
if ( " ' " !== $apos ) {
2014-06-17 16:19:14 -04:00
$dynamic [ '/\'(?=\d\d(?:\Z|(?![%\d]|[.,]\d)))/' ] = $apos ;
2014-06-17 13:41:15 -04:00
}
2014-07-03 21:15:15 -04:00
// Quoted Numbers like '0.42'
2014-06-09 22:43:14 -04:00
if ( " ' " !== $opening_single_quote && " ' " !== $closing_single_quote ) {
2014-06-17 16:19:14 -04:00
$dynamic [ '/(?<=\A|' . $spaces . ')\'(\d[.,\d]*)\'/' ] = $opening_single_quote . '$1' . $closing_single_quote ;
2014-06-09 22:43:14 -04:00
}
2014-06-10 10:22:15 -04:00
// Single quote at start, or preceded by (, {, <, [, ", -, or spaces.
2014-03-29 05:00:15 -04:00
if ( " ' " !== $opening_single_quote ) {
2014-07-03 12:22:14 -04:00
$dynamic [ '/(?<=\A|[([{"\-]|<|' . $spaces . ')\'/' ] = $opening_single_quote ;
2014-03-29 05:00:15 -04:00
}
2014-03-29 03:16:16 -04:00
2014-06-17 13:57:14 -04:00
// Apostrophe in a word. No spaces, double apostrophes, or other punctuation.
2014-06-17 16:14:15 -04:00
if ( " ' " !== $apos ) {
2014-07-03 12:22:14 -04:00
$dynamic [ '/(?<!' . $spaces . ')\'(?!\Z|[.,:;"\'(){}[\]\-]|&[lg]t;|' . $spaces . ')/' ] = $apos ;
2014-06-10 10:14:17 -04:00
}
2014-03-29 03:16:16 -04:00
// 9' (prime)
2014-03-29 05:00:15 -04:00
if ( " ' " !== $prime ) {
2014-03-29 03:16:16 -04:00
$dynamic [ '/(?<=\d)\'/' ] = $prime ;
2014-03-29 05:00:15 -04:00
}
2014-03-29 03:16:16 -04:00
2014-07-03 21:15:15 -04:00
// Single quotes followed by spaces or ending punctuation.
if ( " ' " !== $closing_single_quote ) {
$dynamic [ '/\'(?=\Z|[.,)}\-\]]|>|' . $spaces . ')/' ] = $closing_single_quote ;
}
$dynamic_characters [ 'apos' ] = array_keys ( $dynamic );
$dynamic_replacements [ 'apos' ] = array_values ( $dynamic );
$dynamic = array ();
2014-09-04 11:23:16 -04:00
2014-07-03 21:15:15 -04:00
// Quoted Numbers like "42"
if ( '"' !== $opening_quote && '"' !== $closing_quote ) {
$dynamic [ '/(?<=\A|' . $spaces . ')"(\d[.,\d]*)"/' ] = $opening_quote . '$1' . $closing_quote ;
}
// 9" (double prime)
if ( '"' !== $double_prime ) {
$dynamic [ '/(?<=\d)"/' ] = $double_prime ;
}
2014-06-10 10:22:15 -04:00
// Double quote at start, or preceded by (, {, <, [, -, or spaces, and not followed by spaces.
2014-03-29 05:00:15 -04:00
if ( '"' !== $opening_quote ) {
2014-07-03 12:22:14 -04:00
$dynamic [ '/(?<=\A|[([{\-]|<|' . $spaces . ')"(?!' . $spaces . ')/' ] = $opening_quote ;
2014-03-29 05:00:15 -04:00
}
2014-03-29 03:16:16 -04:00
// Any remaining double quotes.
2014-03-29 05:00:15 -04:00
if ( '"' !== $closing_quote ) {
2014-03-29 03:16:16 -04:00
$dynamic [ '/"/' ] = $closing_quote ;
2014-03-29 05:00:15 -04:00
}
2014-09-04 11:23:16 -04:00
2014-07-03 21:15:15 -04:00
$dynamic_characters [ 'quote' ] = array_keys ( $dynamic );
$dynamic_replacements [ 'quote' ] = array_values ( $dynamic );
$dynamic = array ();
2014-09-04 11:23:16 -04:00
2014-06-09 22:09:15 -04:00
// Dashes and spaces
2014-06-10 10:22:15 -04:00
$dynamic [ '/---/' ] = $em_dash ;
2015-01-15 22:54:24 -05:00
$dynamic [ '/(?<=^|' . $spaces . ')--(?=$|' . $spaces . ')/' ] = $em_dash ;
2014-06-09 22:09:15 -04:00
$dynamic [ '/(?<!xn)--/' ] = $en_dash ;
2015-01-15 22:54:24 -05:00
$dynamic [ '/(?<=^|' . $spaces . ')-(?=$|' . $spaces . ')/' ] = $en_dash ;
2014-06-09 22:09:15 -04:00
2014-07-03 21:15:15 -04:00
$dynamic_characters [ 'dash' ] = array_keys ( $dynamic );
$dynamic_replacements [ 'dash' ] = array_values ( $dynamic );
2006-11-21 17:00:10 -05:00
}
2004-02-09 01:57:02 -05:00
2012-07-09 01:03:53 -04:00
// Must do this every time in case plugins use these filters in a context sensitive manner
2013-11-30 13:36:10 -05:00
/**
* Filter the list of HTML elements not to texturize .
*
* @ since 2.8 . 0
*
* @ param array $default_no_texturize_tags An array of HTML element names .
*/
2014-06-25 13:49:14 -04:00
$no_texturize_tags = apply_filters ( 'no_texturize_tags' , $default_no_texturize_tags );
2013-11-30 13:36:10 -05:00
/**
* Filter the list of shortcodes not to texturize .
*
* @ since 2.8 . 0
*
* @ param array $default_no_texturize_shortcodes An array of shortcode names .
*/
2014-06-25 13:49:14 -04:00
$no_texturize_shortcodes = apply_filters ( 'no_texturize_shortcodes' , $default_no_texturize_shortcodes );
2009-04-20 14:18:39 -04:00
2009-10-21 17:57:27 -04:00
$no_texturize_tags_stack = array ();
$no_texturize_shortcodes_stack = array ();
2004-02-09 01:57:02 -05:00
2014-06-10 10:34:13 -04:00
// Look for shortcodes and HTML elements.
2014-11-20 09:28:23 -05:00
$tagnames = array_keys ( $shortcode_tags );
$tagregexp = join ( '|' , array_map ( 'preg_quote' , $tagnames ) );
$tagregexp = " (?: $tagregexp )(?![ \\ w-]) " ; // Excerpt of get_shortcode_regex().
2014-10-10 22:33:18 -04:00
$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.
2014-09-29 00:07:15 -04:00
$shortcode_regex =
2014-11-20 09:28:23 -05:00
'\[' // 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 ]]
2014-10-10 22:33:18 -04:00
$regex =
'/(' // Capture the entire match.
. '<' // Find start of element.
. '(?(?=!--)' // Is this a comment?
. $comment_regex // Find end of comment.
. '|'
2015-04-01 15:09:28 -04:00
. '[^>]*>' // Find end of element.
2014-10-10 22:33:18 -04:00
. ')'
. '|'
. $shortcode_regex // Find shortcodes.
. ')/s' ;
2014-06-10 10:34:13 -04:00
$textarr = preg_split ( $regex , $text , - 1 , PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
2011-04-13 13:11:35 -04:00
foreach ( $textarr as & $curl ) {
2014-08-12 23:56:17 -04:00
// Only call _wptexturize_pushpop_element if $curl is a delimiter.
2011-04-13 13:11:35 -04:00
$first = $curl [ 0 ];
2014-09-29 00:07:15 -04:00
if ( '<' === $first && '<!--' === substr ( $curl , 0 , 4 ) ) {
// This is an HTML comment delimeter.
2014-06-10 10:34:13 -04:00
2014-09-29 00:07:15 -04:00
continue ;
} elseif ( '<' === $first && '>' === substr ( $curl , - 1 ) ) {
// This is an HTML element delimiter.
_wptexturize_pushpop_element ( $curl , $no_texturize_tags_stack , $no_texturize_tags );
2014-06-10 10:34:13 -04:00
2014-07-06 04:50:18 -04:00
} elseif ( '' === trim ( $curl ) ) {
2014-08-12 23:56:17 -04:00
// This is a newline between delimiters. Performance improves when we check this.
2014-07-06 04:50:18 -04:00
continue ;
2014-09-29 00:07:15 -04:00
} elseif ( '[' === $first && 1 === preg_match ( '/^' . $shortcode_regex . '$/' , $curl ) ) {
2014-08-12 23:56:17 -04:00
// This is a shortcode delimiter.
2014-06-10 10:34:13 -04:00
2014-09-17 11:14:17 -04:00
if ( '[[' !== substr ( $curl , 0 , 2 ) && ']]' !== substr ( $curl , - 2 ) ) {
// Looks like a normal shortcode.
_wptexturize_pushpop_element ( $curl , $no_texturize_shortcodes_stack , $no_texturize_shortcodes );
} else {
// Looks like an escaped shortcode.
continue ;
}
2014-07-06 04:50:18 -04:00
2014-06-25 13:49:14 -04:00
} elseif ( empty ( $no_texturize_shortcodes_stack ) && empty ( $no_texturize_tags_stack ) ) {
2014-08-12 23:56:17 -04:00
// This is neither a delimiter, nor is this content inside of no_texturize pairs. Do texturize.
2014-03-29 03:16:16 -04:00
2014-06-25 13:49:14 -04:00
$curl = str_replace ( $static_characters , $static_replacements , $curl );
2014-07-03 21:15:15 -04:00
if ( false !== strpos ( $curl , " ' " ) ) {
$curl = preg_replace ( $dynamic_characters [ 'apos' ], $dynamic_replacements [ 'apos' ], $curl );
}
if ( false !== strpos ( $curl , '"' ) ) {
$curl = preg_replace ( $dynamic_characters [ 'quote' ], $dynamic_replacements [ 'quote' ], $curl );
}
if ( false !== strpos ( $curl , '-' ) ) {
$curl = preg_replace ( $dynamic_characters [ 'dash' ], $dynamic_replacements [ 'dash' ], $curl );
}
2014-03-29 03:16:16 -04:00
2014-06-09 22:18:15 -04:00
// 9x9 (times), but never 0x9999
2014-12-06 16:24:23 -05:00
if ( 1 === preg_match ( '/(?<=\d)x\d/' , $curl ) ) {
2014-03-29 03:16:16 -04:00
// Searching for a digit is 10 times more expensive than for the x, so we avoid doing this one!
2014-12-06 16:24:23 -05:00
$curl = preg_replace ( '/\b(\d(?(?<=0)[\d\.,]+|[\d\.,]*))x(\d[\d\.,]*)\b/' , '$1×$2' , $curl );
2014-03-29 03:16:16 -04:00
}
2004-02-09 01:57:02 -05:00
}
}
2014-06-25 13:49:14 -04:00
$text = implode ( '' , $textarr );
// Replace each & with & unless it already looks like an entity.
$text = preg_replace ( '/&(?!#(?:\d+|x[a-f0-9]+);|[a-z1-4]{1,8};)/i' , '&' , $text );
return $text ;
2004-02-09 01:57:02 -05:00
}
2009-10-21 17:57:27 -04:00
/**
* Search for disabled element tags . Push element to stack on tag open and pop
2014-06-25 13:49:14 -04:00
* on tag close .
*
* Assumes first char of $text is tag opening and last char is tag closing .
* Assumes second char of $text is optionally '/' to indicate closing as in </ html >.
2009-10-21 17:57:27 -04:00
*
* @ since 2.9 . 0
2013-02-01 13:07:08 -05:00
* @ access private
2009-10-21 17:57:27 -04:00
*
2014-11-24 00:30:25 -05:00
* @ param string $text Text to check . Must be a tag like `<html>` or `[shortcode]` .
2014-06-25 13:49:14 -04:00
* @ param array $stack List of open tag elements .
* @ param array $disabled_elements The tag names to match against . Spaces are not allowed in tag names .
2009-10-21 17:57:27 -04:00
*/
2014-06-25 13:49:14 -04:00
function _wptexturize_pushpop_element ( $text , & $stack , $disabled_elements ) {
// Is it an opening tag or closing tag?
if ( '/' !== $text [ 1 ] ) {
$opening_tag = true ;
$name_offset = 1 ;
} elseif ( 0 == count ( $stack ) ) {
// Stack is empty. Just stop.
return ;
} else {
$opening_tag = false ;
$name_offset = 2 ;
}
// Parse out the tag name.
$space = strpos ( $text , ' ' );
2014-09-17 11:14:17 -04:00
if ( false === $space ) {
2014-06-25 13:49:14 -04:00
$space = - 1 ;
} else {
$space -= $name_offset ;
}
$tag = substr ( $text , $name_offset , $space );
// Handle disabled tags.
if ( in_array ( $tag , $disabled_elements ) ) {
if ( $opening_tag ) {
2009-10-21 17:57:27 -04:00
/*
* This disables texturize until we find a closing tag of our type
* ( e . g . < pre > ) even if there was invalid nesting before that
2010-01-15 17:11:12 -05:00
*
2009-10-21 17:57:27 -04:00
* Example : in the case < pre > sadsadasd </ code > " baba " </ pre >
* " baba " won ' t be texturize
*/
2014-06-25 13:49:14 -04:00
array_push ( $stack , $tag );
} elseif ( end ( $stack ) == $tag ) {
array_pop ( $stack );
2009-05-15 17:37:18 -04:00
}
}
}
2008-08-17 07:29:43 -04:00
/**
2008-08-27 02:49:21 -04:00
* Replaces double line - breaks with paragraph elements .
2008-08-17 07:29:43 -04:00
*
2008-08-27 02:49:21 -04:00
* A group of regex replaces used to identify text formatted with newlines and
2015-03-20 15:47:27 -04:00
* replace double line - breaks with HTML paragraph tags . The remaining line - breaks
* after conversion become << br />> tags , unless $br is set to '0' or 'false' .
2008-08-17 07:29:43 -04:00
*
* @ since 0.71
*
* @ param string $pee The text which has to be formatted .
2015-03-20 15:47:27 -04:00
* @ param bool $br Optional . If set , this will convert all remaining line - breaks
* after paragraphing . Default true .
2008-08-27 02:49:21 -04:00
* @ return string Text which has been converted into correct paragraph tags .
2008-08-17 07:29:43 -04:00
*/
2012-03-28 11:43:31 -04:00
function wpautop ( $pee , $br = true ) {
$pre_tags = array ();
2009-12-01 02:46:36 -05:00
2009-04-22 03:37:24 -04:00
if ( trim ( $pee ) === '' )
return '' ;
2012-03-28 11:43:31 -04:00
2015-03-20 15:47:27 -04:00
// Just to make things a little easier, pad the end.
$pee = $pee . " \n " ;
2012-03-28 11:43:31 -04:00
2015-03-20 15:47:27 -04:00
/*
* Pre tags shouldn ' t be touched by autop .
* Replace pre tags with placeholders and bring them back after autop .
*/
2012-03-28 11:43:31 -04:00
if ( strpos ( $pee , '<pre' ) !== false ) {
$pee_parts = explode ( '</pre>' , $pee );
$last_pee = array_pop ( $pee_parts );
$pee = '' ;
$i = 0 ;
foreach ( $pee_parts as $pee_part ) {
$start = strpos ( $pee_part , '<pre' );
// Malformed html?
if ( $start === false ) {
$pee .= $pee_part ;
continue ;
}
$name = " <pre wp-pre-tag- $i ></pre> " ;
$pre_tags [ $name ] = substr ( $pee_part , $start ) . '</pre>' ;
$pee .= substr ( $pee_part , 0 , $start ) . $name ;
$i ++ ;
}
$pee .= $last_pee ;
}
2015-03-20 15:47:27 -04:00
// Change multiple <br>s into two line breaks, which will turn into paragraphs.
2004-02-09 01:57:02 -05:00
$pee = preg_replace ( '|<br />\s*<br />|' , " \n \n " , $pee );
2015-03-20 15:47:27 -04:00
2015-01-15 19:27:21 -05:00
$allblocks = '(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|form|map|area|blockquote|address|math|style|p|h[1-6]|hr|fieldset|legend|section|article|aside|hgroup|header|footer|nav|figure|figcaption|details|menu|summary)' ;
2015-03-20 15:47:27 -04:00
// Add a single line break above block-level opening tags.
2006-11-30 18:32:45 -05:00
$pee = preg_replace ( '!(<' . $allblocks . '[^>]*>)!' , " \n $ 1 " , $pee );
2015-03-20 15:47:27 -04:00
// Add a double line break below block-level closing tags.
2006-11-30 18:32:45 -05:00
$pee = preg_replace ( '!(</' . $allblocks . '>)!' , " $ 1 \n \n " , $pee );
2014-02-04 19:46:12 -05:00
2015-03-20 15:47:27 -04:00
// Standardize newline characters to "\n".
$pee = str_replace ( array ( " \r \n " , " \r " ), " \n " , $pee );
// Collapse line breaks before and after <option> elements so they don't get autop'd.
2014-07-28 15:44:18 -04:00
if ( strpos ( $pee , '<option' ) !== false ) {
2014-07-28 15:55:16 -04:00
$pee = preg_replace ( '|\s*<option|' , '<option' , $pee );
$pee = preg_replace ( '|</option>\s*|' , '</option>' , $pee );
2014-07-28 15:44:18 -04:00
}
2015-03-20 15:47:27 -04:00
/*
* Collapse line breaks inside < object > elements , before < param > and < embed > elements
* so they don 't get autop' d .
*/
2014-02-04 19:46:12 -05:00
if ( strpos ( $pee , '</object>' ) !== false ) {
$pee = preg_replace ( '|(<object[^>]*>)\s*|' , '$1' , $pee );
$pee = preg_replace ( '|\s*</object>|' , '</object>' , $pee );
$pee = preg_replace ( '%\s*(</?(?:param|embed)[^>]*>)\s*%' , '$1' , $pee );
}
2015-03-20 15:47:27 -04:00
/*
* Collapse line breaks inside < audio > and < video > elements ,
* before and after < source > and < track > elements .
*/
2014-02-04 19:46:12 -05:00
if ( strpos ( $pee , '<source' ) !== false || strpos ( $pee , '<track' ) !== false ) {
$pee = preg_replace ( '%([<\[](?:audio|video)[^>\]]*[>\]])\s*%' , '$1' , $pee );
$pee = preg_replace ( '%\s*([<\[]/(?:audio|video)[>\]])%' , '$1' , $pee );
$pee = preg_replace ( '%\s*(<(?:source|track)[^>]*>)\s*%' , '$1' , $pee );
2008-01-17 10:44:05 -05:00
}
2014-02-04 19:46:12 -05:00
2015-03-20 15:47:27 -04:00
// Remove more than two contiguous line breaks.
$pee = preg_replace ( " / \n \n +/ " , " \n \n " , $pee );
// Split up the contents into an array of strings, separated by double line breaks.
2008-10-20 15:25:02 -04:00
$pees = preg_split ( '/\n\s*\n/' , $pee , - 1 , PREG_SPLIT_NO_EMPTY );
2015-03-20 15:47:27 -04:00
// Reset $pee prior to rebuilding.
2008-10-20 15:25:02 -04:00
$pee = '' ;
2014-02-04 19:46:12 -05:00
2015-03-20 15:47:27 -04:00
// Rebuild the content as a string, wrapping every bit with a <p>.
2014-02-04 19:46:12 -05:00
foreach ( $pees as $tinkle ) {
2008-10-20 15:25:02 -04:00
$pee .= '<p>' . trim ( $tinkle , " \n " ) . " </p> \n " ;
2014-02-04 19:46:12 -05:00
}
2015-03-20 15:47:27 -04:00
// Under certain strange conditions it could create a P of entirely whitespace.
$pee = preg_replace ( '|<p>\s*</p>|' , '' , $pee );
// Add a closing <p> inside <div>, <address>, or <form> tag if missing.
2009-02-08 11:08:02 -05:00
$pee = preg_replace ( '!<p>([^<]+)</(div|address|form)>!' , " <p> $ 1</p></ $ 2> " , $pee );
2015-03-20 15:47:27 -04:00
// If an opening or closing block element tag is wrapped in a <p>, unwrap it.
$pee = preg_replace ( '!<p>\s*(</?' . $allblocks . '[^>]*>)\s*</p>!' , " $ 1 " , $pee );
// In some cases <li> may get wrapped in <p>, fix them.
$pee = preg_replace ( " |<p>(<li.+?)</p>| " , " $ 1 " , $pee );
// If a <blockquote> is wrapped with a <p>, move it inside the <blockquote>.
2004-02-09 01:57:02 -05:00
$pee = preg_replace ( '|<p><blockquote([^>]*)>|i' , " <blockquote $ 1><p> " , $pee );
$pee = str_replace ( '</blockquote></p>' , '</p></blockquote>' , $pee );
2015-03-20 15:47:27 -04:00
// If an opening or closing block element tag is preceded by an opening <p> tag, remove it.
2006-11-30 18:32:45 -05:00
$pee = preg_replace ( '!<p>\s*(</?' . $allblocks . '[^>]*>)!' , " $ 1 " , $pee );
2015-03-20 15:47:27 -04:00
// If an opening or closing block element tag is followed by a closing <p> tag, remove it.
2006-11-30 18:32:45 -05:00
$pee = preg_replace ( '!(</?' . $allblocks . '[^>]*>)\s*</p>!' , " $ 1 " , $pee );
2014-02-04 19:46:12 -05:00
2015-03-20 15:47:27 -04:00
// Optionally insert line breaks.
2012-03-28 11:43:31 -04:00
if ( $br ) {
2015-03-20 15:47:27 -04:00
// Replace newlines that shouldn't be touched with a placeholder.
2010-11-11 17:50:36 -05:00
$pee = preg_replace_callback ( '/<(script|style).*?<\/\\1>/s' , '_autop_newline_preservation_helper' , $pee );
2015-03-20 15:47:27 -04:00
// Replace any new line characters that aren't preceded by a <br /> with a <br />.
$pee = preg_replace ( '|(?<!<br />)\s*\n|' , " <br /> \n " , $pee );
// Replace newline placeholders with newlines.
2006-07-04 19:16:04 -04:00
$pee = str_replace ( '<WPPreserveNewline />' , " \n " , $pee );
}
2014-02-04 19:46:12 -05:00
2015-03-20 15:47:27 -04:00
// If a <br /> tag is after an opening or closing block tag, remove it.
2006-11-30 18:32:45 -05:00
$pee = preg_replace ( '!(</?' . $allblocks . '[^>]*>)\s*<br />!' , " $ 1 " , $pee );
2015-03-20 15:47:27 -04:00
// If a <br /> tag is before a subset of opening or closing block tags, remove it.
2006-09-06 20:33:05 -04:00
$pee = preg_replace ( '!<br />(\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)!' , '$1' , $pee );
2006-11-30 18:32:45 -05:00
$pee = preg_replace ( " | \n </p> $ | " , '</p>' , $pee );
2009-12-01 02:46:36 -05:00
2015-03-20 15:47:27 -04:00
// Replace placeholder <pre> tags with their original content.
2012-03-28 11:43:31 -04:00
if ( ! empty ( $pre_tags ) )
$pee = str_replace ( array_keys ( $pre_tags ), array_values ( $pre_tags ), $pee );
2009-12-01 02:46:36 -05:00
return $pee ;
}
2010-10-28 03:38:00 -04:00
/**
* Newline preservation help function for wpautop
2010-11-17 13:47:34 -05:00
*
2010-10-28 03:38:00 -04:00
* @ since 3.1 . 0
* @ access private
2013-02-01 13:07:08 -05:00
*
2010-10-28 03:38:00 -04:00
* @ param array $matches preg_replace_callback matches array
2012-07-09 01:03:53 -04:00
* @ return string
2010-10-28 03:38:00 -04:00
*/
2010-11-11 17:50:36 -05:00
function _autop_newline_preservation_helper ( $matches ) {
2010-10-28 03:38:00 -04:00
return str_replace ( " \n " , " <WPPreserveNewline /> " , $matches [ 0 ]);
}
2009-12-01 02:46:36 -05:00
/**
* Don ' t auto - p wrap shortcodes that stand alone
*
2014-11-24 00:30:25 -05:00
* Ensures that shortcodes are not wrapped in `<p>...</p>` .
2009-12-01 02:46:36 -05:00
*
* @ since 2.9 . 0
*
* @ param string $pee The content .
* @ return string The filtered content .
*/
2011-10-12 12:50:30 -04:00
function shortcode_unautop ( $pee ) {
2009-12-01 02:46:36 -05:00
global $shortcode_tags ;
2011-10-12 12:50:30 -04:00
if ( empty ( $shortcode_tags ) || ! is_array ( $shortcode_tags ) ) {
return $pee ;
2009-12-01 02:46:36 -05:00
}
2007-02-20 00:41:39 -05:00
2011-10-12 12:50:30 -04:00
$tagregexp = join ( '|' , array_map ( 'preg_quote' , array_keys ( $shortcode_tags ) ) );
2014-06-09 21:55:15 -04:00
$spaces = wp_spaces_regexp ();
2011-10-12 12:50:30 -04:00
$pattern =
'/'
. '<p>' // Opening paragraph
2014-06-09 21:55:15 -04:00
. '(?:' . $spaces . ')*+' // Optional leading whitespace
2011-10-12 12:50:30 -04:00
. '(' // 1: The shortcode
. '\\[' // Opening bracket
. " ( $tagregexp ) " // 2: Shortcode name
2012-11-06 09:47:33 -05:00
. '(?![\\w-])' // Not followed by word character or hyphen
2011-10-12 12:50:30 -04:00
// 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
. ')?'
. ')'
. ')'
2014-06-09 21:55:15 -04:00
. '(?:' . $spaces . ')*+' // optional trailing whitespace
2011-10-12 12:50:30 -04:00
. '<\\/p>' // closing paragraph
. '/s' ;
return preg_replace ( $pattern , '$1' , $pee );
2004-02-09 01:57:02 -05:00
}
2008-08-17 07:29:43 -04:00
/**
* Checks to see if a string is utf8 encoded .
*
2009-05-24 19:47:49 -04:00
* NOTE : This function checks for 5 - Byte sequences , UTF8
2009-05-20 17:13:14 -04:00
* has Bytes Sequences with a maximum length of 4.
2008-08-31 16:58:19 -04:00
*
2009-05-20 17:13:14 -04:00
* @ author bmorel at ssi dot fr ( modified )
2008-08-17 07:29:43 -04:00
* @ since 1.2 . 1
*
2009-05-20 17:13:14 -04:00
* @ param string $str The string to be checked
* @ return bool True if $str fits a UTF - 8 model , false otherwise .
2008-08-17 07:29:43 -04:00
*/
2009-06-04 01:32:58 -04:00
function seems_utf8 ( $str ) {
2014-06-23 18:21:15 -04:00
mbstring_binary_safe_encoding ();
$length = strlen ( $str );
reset_mbstring_encoding ();
2007-11-05 12:13:43 -05:00
for ( $i = 0 ; $i < $length ; $i ++ ) {
2009-05-24 19:47:49 -04:00
$c = ord ( $str [ $i ]);
2015-01-08 00:52:24 -05:00
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 ?
2009-05-20 17:13:14 -04:00
if (( ++ $i == $length ) || (( ord ( $str [ $i ]) & 0xC0 ) != 0x80 ))
return false ;
2004-05-22 10:34:09 -04:00
}
}
return true ;
}
2008-08-17 07:29:43 -04:00
/**
2008-08-27 02:49:21 -04:00
* Converts a number of special characters into their HTML entities .
2008-08-17 07:29:43 -04:00
*
2009-01-04 18:37:47 -05:00
* Specifically deals with : & , < , > , " , and '.
2008-08-17 07:29:43 -04:00
*
2009-01-04 17:25:50 -05:00
* $quote_style can be set to ENT_COMPAT to encode " to
* & quot ;, or ENT_QUOTES to do both . Default is ENT_NOQUOTES where no quotes are encoded .
2008-08-17 07:29:43 -04:00
*
* @ since 1.2 . 2
2013-02-01 13:07:08 -05:00
* @ access private
2008-08-17 07:29:43 -04:00
*
2009-01-04 17:25:50 -05:00
* @ param string $string The text which is to be encoded .
2014-11-30 20:34:24 -05:00
* @ 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 .
2009-01-04 17:25:50 -05:00
* @ param string $charset Optional . The character encoding of the string . Default is false .
2010-02-24 15:13:23 -05:00
* @ param boolean $double_encode Optional . Whether to encode existing html entities . Default is false .
2008-08-27 02:49:21 -04:00
* @ return string The encoded text with HTML entities .
2008-08-17 07:29:43 -04:00
*/
2009-05-18 11:11:07 -04:00
function _wp_specialchars ( $string , $quote_style = ENT_NOQUOTES , $charset = false , $double_encode = false ) {
2009-01-04 18:37:47 -05:00
$string = ( string ) $string ;
2011-07-29 16:43:45 -04:00
if ( 0 === strlen ( $string ) )
2009-01-04 17:25:50 -05:00
return '' ;
2009-01-13 10:18:37 -05:00
// Don't bother if there are no specialchars - saves some processing
2011-07-29 16:43:45 -04:00
if ( ! preg_match ( '/[&<>"\']/' , $string ) )
2009-01-13 10:18:37 -05:00
return $string ;
2009-01-18 23:40:12 -05:00
// Account for the previous behaviour of the function when the $quote_style is not an accepted value
2011-07-29 16:43:45 -04:00
if ( empty ( $quote_style ) )
2009-01-18 23:40:12 -05:00
$quote_style = ENT_NOQUOTES ;
2011-07-29 16:43:45 -04:00
elseif ( ! in_array ( $quote_style , array ( 0 , 2 , 3 , 'single' , 'double' ), true ) )
2009-01-18 23:40:12 -05:00
$quote_style = ENT_QUOTES ;
2009-01-13 10:18:37 -05:00
// Store the site charset as a static to avoid multiple calls to wp_load_alloptions()
2011-07-29 16:43:45 -04:00
if ( ! $charset ) {
2009-01-13 10:18:37 -05:00
static $_charset ;
2011-07-29 16:43:45 -04:00
if ( ! isset ( $_charset ) ) {
2009-01-13 10:18:37 -05:00
$alloptions = wp_load_alloptions ();
$_charset = isset ( $alloptions [ 'blog_charset' ] ) ? $alloptions [ 'blog_charset' ] : '' ;
}
$charset = $_charset ;
2009-01-04 17:25:50 -05:00
}
2011-07-29 16:43:45 -04:00
if ( in_array ( $charset , array ( 'utf8' , 'utf-8' , 'UTF8' ) ) )
2009-01-04 17:25:50 -05:00
$charset = 'UTF-8' ;
2009-01-18 23:40:12 -05:00
$_quote_style = $quote_style ;
if ( $quote_style === 'double' ) {
$quote_style = ENT_COMPAT ;
$_quote_style = ENT_COMPAT ;
} elseif ( $quote_style === 'single' ) {
$quote_style = ENT_NOQUOTES ;
2009-01-04 17:25:50 -05:00
}
2009-05-24 19:47:49 -04:00
2009-01-04 18:37:47 -05:00
// Handle double encoding ourselves
2011-07-29 16:43:45 -04:00
if ( $double_encode ) {
$string = @ htmlspecialchars ( $string , $quote_style , $charset );
} else {
// Decode & into &
2009-01-04 18:37:47 -05:00
$string = wp_specialchars_decode ( $string , $_quote_style );
2010-02-24 00:37:20 -05:00
2011-07-29 16:43:45 -04:00
// Guarantee every &entity; is valid or re-encode the &
$string = wp_kses_normalize_entities ( $string );
2010-02-24 00:37:20 -05:00
2011-07-29 16:43:45 -04:00
// Now re-encode everything except &entity;
$string = preg_split ( '/(&#?x?[0-9a-z]+;)/i' , $string , - 1 , PREG_SPLIT_DELIM_CAPTURE );
2009-01-04 18:37:47 -05:00
2015-02-26 00:48:24 -05:00
for ( $i = 0 , $c = count ( $string ); $i < $c ; $i += 2 ) {
2011-07-29 16:43:45 -04:00
$string [ $i ] = @ htmlspecialchars ( $string [ $i ], $quote_style , $charset );
2015-02-26 00:48:24 -05:00
}
2011-07-29 16:43:45 -04:00
$string = implode ( '' , $string );
2009-01-04 17:25:50 -05:00
}
// Backwards compatibility
2011-07-29 16:43:45 -04:00
if ( 'single' === $_quote_style )
2009-01-04 17:25:50 -05:00
$string = str_replace ( " ' " , ''' , $string );
return $string ;
}
/**
2009-01-04 18:37:47 -05:00
* Converts a number of HTML entities into their special characters .
2009-01-04 17:25:50 -05:00
*
2009-01-04 18:37:47 -05:00
* 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.
2009-01-04 17:25:50 -05:00
*
2013-02-01 13:07:08 -05:00
* @ since 2.8 . 0
2009-01-04 17:25:50 -05:00
*
2009-01-04 18:37:47 -05:00
* @ param string $string The text which is to be decoded .
2009-05-18 11:11:07 -04:00
* @ 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 .
2009-01-04 18:37:47 -05:00
* @ return string The decoded text without HTML entities .
2009-01-04 17:25:50 -05:00
*/
2009-05-06 00:56:32 -04:00
function wp_specialchars_decode ( $string , $quote_style = ENT_NOQUOTES ) {
2009-01-04 18:37:47 -05:00
$string = ( string ) $string ;
2009-01-04 17:25:50 -05:00
if ( 0 === strlen ( $string ) ) {
return '' ;
}
2009-01-13 10:18:37 -05:00
// Don't bother if there are no entities - saves a lot of processing
if ( strpos ( $string , '&' ) === false ) {
return $string ;
}
2009-05-18 11:11:07 -04:00
// Match the previous behaviour of _wp_specialchars() when the $quote_style is not an accepted value
2009-01-18 23:40:12 -05:00
if ( empty ( $quote_style ) ) {
$quote_style = ENT_NOQUOTES ;
} elseif ( ! in_array ( $quote_style , array ( 0 , 2 , 3 , 'single' , 'double' ), true ) ) {
$quote_style = ENT_QUOTES ;
}
2009-01-04 18:37:47 -05:00
// 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' => '&' );
2009-01-04 17:25:50 -05:00
2009-01-18 23:40:12 -05:00
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 ;
2009-01-04 17:25:50 -05:00
}
2009-01-04 18:37:47 -05:00
// 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 );
2009-01-04 17:25:50 -05:00
}
/**
* Checks for invalid UTF8 in a string .
*
2013-02-01 13:07:08 -05:00
* @ since 2.8 . 0
2009-01-04 17:25:50 -05:00
*
* @ 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 .
*/
2009-05-06 00:56:32 -04:00
function wp_check_invalid_utf8 ( $string , $strip = false ) {
2009-01-04 18:37:47 -05:00
$string = ( string ) $string ;
2009-01-04 17:25:50 -05:00
if ( 0 === strlen ( $string ) ) {
return '' ;
}
2009-01-13 10:18:37 -05:00
// 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 ) {
2009-01-04 17:25:50 -05:00
return $string ;
}
// preg_match fails when it encounters invalid UTF8 in $string
2009-01-13 10:18:37 -05:00
if ( 1 === @ preg_match ( '/^./us' , $string ) ) {
2009-01-04 17:25:50 -05:00
return $string ;
}
2009-01-13 10:18:37 -05:00
// Attempt to strip the bad chars if requested (not recommended)
2009-01-04 17:25:50 -05:00
if ( $strip && function_exists ( 'iconv' ) ) {
return iconv ( 'utf-8' , 'utf-8' , $string );
2004-12-12 15:41:19 -05:00
}
2009-01-13 10:18:37 -05:00
return '' ;
2004-12-12 15:41:19 -05:00
}
2008-08-17 07:29:43 -04:00
/**
2008-08-31 16:58:19 -04:00
* Encode the Unicode values to be used in the URI .
2008-08-17 07:29:43 -04:00
*
* @ since 1.5 . 0
*
2008-08-31 16:58:19 -04:00
* @ param string $utf8_string
* @ param int $length Max length of the string
* @ return string String with Unicode encoded for URI .
2008-08-17 07:29:43 -04:00
*/
2006-11-30 15:26:42 -05:00
function utf8_uri_encode ( $utf8_string , $length = 0 ) {
2006-11-19 02:56:05 -05:00
$unicode = '' ;
$values = array ();
$num_octets = 1 ;
2007-11-05 12:13:43 -05:00
$unicode_length = 0 ;
2006-11-19 02:56:05 -05:00
2014-06-23 18:21:15 -04:00
mbstring_binary_safe_encoding ();
$string_length = strlen ( $utf8_string );
reset_mbstring_encoding ();
2007-11-05 12:13:43 -05:00
for ( $i = 0 ; $i < $string_length ; $i ++ ) {
2006-11-19 02:56:05 -05:00
$value = ord ( $utf8_string [ $i ] );
if ( $value < 128 ) {
2007-11-05 12:13:43 -05:00
if ( $length && ( $unicode_length >= $length ) )
2007-09-03 19:32:58 -04:00
break ;
2006-11-19 02:56:05 -05:00
$unicode .= chr ( $value );
2007-11-05 12:13:43 -05:00
$unicode_length ++ ;
2006-11-19 02:56:05 -05:00
} else {
2015-03-11 18:55:28 -04:00
if ( count ( $values ) == 0 ) {
if ( $value < 224 ) {
$num_octets = 2 ;
} elseif ( $value < 240 ) {
$num_octets = 3 ;
} else {
$num_octets = 4 ;
}
}
2006-11-19 02:56:05 -05:00
$values [] = $value ;
2007-11-05 12:13:43 -05:00
if ( $length && ( $unicode_length + ( $num_octets * 3 ) ) > $length )
2006-11-30 15:26:42 -05:00
break ;
2006-11-19 02:56:05 -05:00
if ( count ( $values ) == $num_octets ) {
2015-03-11 18:55:28 -04:00
for ( $j = 0 ; $j < $num_octets ; $j ++ ) {
$unicode .= '%' . dechex ( $values [ $j ] );
2006-11-30 15:26:42 -05:00
}
2015-03-11 18:55:28 -04:00
$unicode_length += $num_octets * 3 ;
2006-11-30 15:26:42 -05:00
$values = array ();
$num_octets = 1 ;
2006-11-19 02:56:05 -05:00
}
}
}
2004-09-10 04:36:54 -04:00
2006-11-19 02:56:05 -05:00
return $unicode ;
2004-09-10 04:36:54 -04:00
}
2008-08-17 07:29:43 -04:00
/**
2008-08-31 16:58:19 -04:00
* Converts all accent characters to ASCII characters .
*
* If there are no accent characters , then the string given is just returned .
2008-08-17 07:29:43 -04:00
*
* @ since 1.2 . 1
*
2008-08-31 16:58:19 -04:00
* @ param string $string Text that might have accent characters
2008-08-27 02:49:21 -04:00
* @ return string Filtered string with replaced " nice " characters .
2008-08-17 07:29:43 -04:00
*/
2004-05-22 10:34:09 -04:00
function remove_accents ( $string ) {
2006-07-26 18:55:36 -04:00
if ( ! preg_match ( '/[\x80-\xff]/' , $string ) )
return $string ;
2004-05-22 10:34:09 -04:00
if ( seems_utf8 ( $string )) {
2005-03-28 20:38:29 -05:00
$chars = array (
// Decompositions for Latin-1 Supplement
2011-11-02 19:08:05 -04:00
chr ( 194 ) . chr ( 170 ) => 'a' , chr ( 194 ) . chr ( 186 ) => 'o' ,
2005-03-28 20:38:29 -05:00
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' ,
2010-10-23 09:00:21 -04:00
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' ,
2005-03-28 20:38:29 -05:00
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' ,
2010-10-23 09:00:21 -04:00
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' ,
2005-03-28 20:38:29 -05:00
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' ,
2010-10-23 09:00:21 -04:00
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' ,
2011-06-05 22:22:50 -04:00
chr ( 195 ) . chr ( 182 ) => 'o' , chr ( 195 ) . chr ( 184 ) => 'o' ,
2010-10-23 09:00:21 -04:00
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' ,
2011-11-02 19:08:05 -04:00
chr ( 195 ) . chr ( 191 ) => 'y' , chr ( 195 ) . chr ( 152 ) => 'O' ,
2005-03-28 20:38:29 -05:00
// Decompositions for Latin Extended-A
2005-03-28 22:12:24 -05:00
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' ,
2005-11-16 01:37:06 -05:00
chr ( 196 ) . chr ( 134 ) => 'C' , chr ( 196 ) . chr ( 135 ) => 'c' ,
2005-03-28 22:12:24 -05:00
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' ,
2005-11-16 01:37:06 -05:00
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' ,
2005-03-28 22:12:24 -05:00
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' ,
2005-03-28 20:38:29 -05:00
chr ( 197 ) . chr ( 160 ) => 'S' , chr ( 197 ) . chr ( 161 ) => 's' ,
2005-03-28 22:12:24 -05:00
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' ,
2010-10-23 11:36:16 -04:00
// 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' ,
2005-03-28 20:38:29 -05:00
// Euro Sign
2006-10-04 03:51:11 -04:00
chr ( 226 ) . chr ( 130 ) . chr ( 172 ) => 'E' ,
// GBP (Pound) Sign
2012-05-02 12:55:16 -04:00
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' ,
2012-09-15 16:01:08 -04:00
// 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' ,
2012-05-02 12:55:16 -04:00
);
2006-02-12 02:53:23 -05:00
2013-01-30 20:55:09 -05:00
// 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' ;
2013-12-03 15:39:09 -05:00
} 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' ;
2013-01-30 20:55:09 -05:00
}
2004-09-10 04:36:54 -04:00
$string = strtr ( $string , $chars );
} else {
2014-12-20 17:47:22 -05:00
$chars = array ();
2004-09-10 04:36:54 -04:00
// 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' ]);
2014-12-20 17:47:22 -05:00
$double_chars = array ();
2004-09-10 04:36:54 -04:00
$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 );
2004-05-22 10:34:09 -04:00
}
2004-09-10 04:36:54 -04:00
2004-05-22 10:34:09 -04:00
return $string ;
}
2008-08-17 07:29:43 -04:00
/**
2013-02-01 13:07:08 -05:00
* Sanitizes a filename , replacing whitespace with dashes .
2008-08-17 07:29:43 -04:00
*
2009-05-24 19:47:49 -04:00
* 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
2013-02-01 13:07:08 -05:00
* dashes with a single dash . Trims period , dash and underscore from beginning
2009-05-04 16:20:48 -04:00
* and end of filename .
2008-08-17 07:29:43 -04:00
*
* @ since 2.1 . 0
*
2009-05-04 16:20:48 -04:00
* @ param string $filename The filename to be sanitized
* @ return string The sanitized filename
2008-08-17 07:29:43 -04:00
*/
2009-05-04 16:20:48 -04:00
function sanitize_file_name ( $filename ) {
$filename_raw = $filename ;
2009-10-20 14:52:37 -04:00
$special_chars = array ( " ? " , " [ " , " ] " , " / " , " \\ " , " = " , " < " , " > " , " : " , " ; " , " , " , " ' " , " \" " , " & " , " $ " , " # " , " * " , " ( " , " ) " , " | " , " ~ " , " ` " , " ! " , " { " , " } " , chr ( 0 ));
2013-11-30 13:36:10 -05:00
/**
* 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 );
2014-03-19 03:16:15 -04:00
$filename = preg_replace ( " # \ x { 00a0}#siu " , ' ' , $filename );
2014-09-07 04:33:16 -04:00
$filename = str_replace ( $special_chars , '' , $filename );
2014-07-24 18:09:16 -04:00
$filename = str_replace ( array ( '%20' , '+' ), '-' , $filename );
2014-09-07 04:33:16 -04:00
$filename = preg_replace ( '/[\r\n\t -]+/' , '-' , $filename );
$filename = trim ( $filename , '.-_' );
2009-11-11 18:07:29 -05:00
// Split the filename into a base and extension[s]
$parts = explode ( '.' , $filename );
// Return if only one extension
2013-11-30 13:36:10 -05:00
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 );
}
2009-11-11 18:07:29 -05:00
// Process multiple extensions
$filename = array_shift ( $parts );
$extension = array_pop ( $parts );
$mimes = get_allowed_mime_types ();
2013-11-30 13:36:10 -05:00
/*
* 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 .
*/
2009-11-11 18:07:29 -05:00
foreach ( ( array ) $parts as $part ) {
$filename .= '.' . $part ;
2010-01-15 17:11:12 -05:00
2009-11-11 18:07:29 -05:00
if ( preg_match ( " /^[a-zA-Z] { 2,5} \ d? $ / " , $part ) ) {
$allowed = false ;
foreach ( $mimes as $ext_preg => $mime_match ) {
2011-05-22 19:17:09 -04:00
$ext_preg = '!^(' . $ext_preg . ')$!i' ;
2009-11-11 18:07:29 -05:00
if ( preg_match ( $ext_preg , $part ) ) {
$allowed = true ;
break ;
}
}
if ( ! $allowed )
$filename .= '_' ;
}
}
$filename .= '.' . $extension ;
2013-11-30 13:36:10 -05:00
/** This filter is documented in wp-includes/formatting.php */
2009-05-04 16:20:48 -04:00
return apply_filters ( 'sanitize_file_name' , $filename , $filename_raw );
2007-01-09 17:53:14 -05:00
}
2008-08-17 07:29:43 -04:00
/**
2013-02-01 13:07:08 -05:00
* Sanitizes a username , stripping out unsafe characters .
2008-08-17 07:29:43 -04:00
*
2010-10-24 16:33:54 -04:00
* Removes tags , octets , entities , and if strict is enabled , will only keep
2010-11-17 13:47:34 -05:00
* alphanumeric , _ , space , . , - , @. After sanitizing , it passes the username ,
2010-10-24 16:33:54 -04:00
* raw username ( the username in the parameter ), and the value of $strict as
* parameters for the 'sanitize_user' filter .
2008-08-17 07:29:43 -04:00
*
* @ since 2.0 . 0
*
2008-08-27 02:49:21 -04:00
* @ 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 .
2008-08-17 07:29:43 -04:00
*/
2006-01-24 22:09:16 -05:00
function sanitize_user ( $username , $strict = false ) {
2006-01-18 00:37:26 -05:00
$raw_username = $username ;
2010-05-03 19:46:42 -04:00
$username = wp_strip_all_tags ( $username );
$username = remove_accents ( $username );
2006-01-18 00:37:26 -05:00
// Kill octets
2010-05-03 19:46:42 -04:00
$username = preg_replace ( '|%([a-fA-F0-9][a-fA-F0-9])|' , '' , $username );
$username = preg_replace ( '/&.+?;/' , '' , $username ); // Kill entities
2006-01-24 22:09:16 -05:00
// If strict, reduce to ASCII for max portability.
if ( $strict )
2010-05-03 19:46:42 -04:00
$username = preg_replace ( '|[^a-z0-9 _.\-@]|i' , '' , $username );
2006-01-24 22:09:16 -05:00
2010-10-24 16:33:54 -04:00
$username = trim ( $username );
2008-08-21 18:58:29 -04:00
// Consolidate contiguous whitespace
2010-05-03 19:46:42 -04:00
$username = preg_replace ( '|\s+|' , ' ' , $username );
2008-08-21 18:58:29 -04:00
2013-11-30 13:36:10 -05:00
/**
* Filter a sanitized username string .
*
2013-11-30 14:05:10 -05:00
* @ since 2.0 . 1
2013-11-30 13:36:10 -05:00
*
* @ 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 .
*/
2010-05-03 19:46:42 -04:00
return apply_filters ( 'sanitize_user' , $username , $raw_username , $strict );
2005-06-12 19:14:52 -04:00
}
2010-03-16 15:19:32 -04:00
/**
2013-02-01 13:07:08 -05:00
* Sanitizes a string key .
2010-03-16 15:19:32 -04:00
*
2010-10-24 16:33:54 -04:00
* Keys are used as internal identifiers . Lowercase alphanumeric characters , dashes and underscores are allowed .
2010-03-16 15:19:32 -04:00
*
* @ since 3.0 . 0
2010-03-17 12:27:25 -04:00
*
2010-03-16 15:19:32 -04:00
* @ param string $key String key
* @ return string Sanitized key
*/
function sanitize_key ( $key ) {
$raw_key = $key ;
2010-10-24 16:33:54 -04:00
$key = strtolower ( $key );
$key = preg_replace ( '/[^a-z0-9_\-]/' , '' , $key );
2013-11-30 13:36:10 -05:00
/**
* Filter a sanitized key string .
*
* @ since 3.0 . 0
*
* @ param string $key Sanitized key .
* @ param string $raw_key The key prior to sanitization .
*/
2010-10-24 16:33:54 -04:00
return apply_filters ( 'sanitize_key' , $key , $raw_key );
2010-03-16 15:19:32 -04:00
}
2008-08-17 07:29:43 -04:00
/**
2013-02-01 13:07:08 -05:00
* Sanitizes a title , or returns a fallback title .
2008-08-17 07:29:43 -04:00
*
2008-08-27 02:49:21 -04:00
* 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 .
2008-08-17 07:29:43 -04:00
*
* @ since 1.0 . 0
*
2008-08-27 02:49:21 -04:00
* @ param string $title The string to be sanitized .
* @ param string $fallback_title Optional . A title to use if $title is empty .
2010-10-23 08:55:55 -04:00
* @ param string $context Optional . The operation for which the string is sanitized
2008-08-27 02:49:21 -04:00
* @ return string The sanitized string .
2008-08-17 07:29:43 -04:00
*/
2013-02-01 13:07:08 -05:00
function sanitize_title ( $title , $fallback_title = '' , $context = 'save' ) {
2009-03-17 13:42:54 -04:00
$raw_title = $title ;
2010-10-23 08:55:55 -04:00
if ( 'save' == $context )
$title = remove_accents ( $title );
2013-11-30 13:36:10 -05:00
/**
* Filter a sanitized title string .
*
2013-11-30 14:05:10 -05:00
* @ since 1.2 . 0
2013-11-30 13:36:10 -05:00
*
* @ 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 );
2004-08-05 21:28:51 -04:00
2007-12-19 12:45:50 -05:00
if ( '' === $title || false === $title )
2005-01-02 04:08:55 -05:00
$title = $fallback_title ;
2004-05-21 04:37:55 -04:00
2005-01-02 04:08:55 -05:00
return $title ;
2004-02-09 01:57:02 -05:00
}
2013-02-01 13:07:08 -05:00
/**
* Sanitizes a title with the 'query' context .
*
* Used for querying the database for a value from URL .
*
* @ since 3.1 . 0
*
* @ param string $title The string to be sanitized .
* @ return string The sanitized string .
*/
function sanitize_title_for_query ( $title ) {
return sanitize_title ( $title , '' , 'query' );
2010-10-23 08:55:55 -04:00
}
2008-08-17 07:29:43 -04:00
/**
2013-02-01 13:07:08 -05:00
* Sanitizes a title , replacing whitespace and a few other characters with dashes .
2008-08-17 07:29:43 -04:00
*
2008-08-27 02:49:21 -04:00
* Limits the output to alphanumeric characters , underscore ( _ ) and dash ( - ) .
2008-08-30 17:28:11 -04:00
* Whitespace becomes a dash .
2008-08-17 07:29:43 -04:00
*
* @ since 1.2 . 0
*
2008-08-27 02:49:21 -04:00
* @ param string $title The title to be sanitized .
2011-09-18 15:53:59 -04:00
* @ param string $raw_title Optional . Not used .
* @ param string $context Optional . The operation for which the string is sanitized .
2008-08-27 02:49:21 -04:00
* @ return string The sanitized title .
2008-08-17 07:29:43 -04:00
*/
2013-02-01 13:07:08 -05:00
function sanitize_title_with_dashes ( $title , $raw_title = '' , $context = 'display' ) {
2004-09-15 21:08:50 -04:00
$title = strip_tags ( $title );
2005-02-01 03:31:13 -05:00
// 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 );
2005-01-02 04:08:55 -05:00
if ( seems_utf8 ( $title )) {
if ( function_exists ( 'mb_strtolower' )) {
$title = mb_strtolower ( $title , 'UTF-8' );
2004-09-10 04:36:54 -04:00
}
2006-11-30 15:26:42 -05:00
$title = utf8_uri_encode ( $title , 200 );
2005-01-02 04:08:55 -05:00
}
2004-09-10 04:36:54 -04:00
2005-01-02 04:08:55 -05:00
$title = strtolower ( $title );
$title = preg_replace ( '/&.+?;/' , '' , $title ); // kill entities
2009-04-16 23:28:55 -04:00
$title = str_replace ( '.' , '-' , $title );
2011-09-18 15:53:59 -04:00
if ( 'save' == $context ) {
2012-05-02 12:37:42 -04:00
// Convert nbsp, ndash and mdash to hyphens
2011-09-18 15:53:59 -04:00
$title = str_replace ( array ( '%c2%a0' , '%e2%80%93' , '%e2%80%94' ), '-' , $title );
2012-05-02 12:37:42 -04:00
// 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' ,
2012-12-13 04:59:28 -05:00
// acute accents
'%c2%b4' , '%cb%8a' , '%cc%81' , '%cd%81' ,
// grave accent, macron, caron
'%cc%80' , '%cc%84' , '%cc%8c' ,
2012-05-02 12:37:42 -04:00
), '' , $title );
// Convert times to x
$title = str_replace ( '%c3%97' , 'x' , $title );
2011-09-18 15:53:59 -04:00
}
2005-01-02 04:08:55 -05:00
$title = preg_replace ( '/[^%a-z0-9 _-]/' , '' , $title );
$title = preg_replace ( '/\s+/' , '-' , $title );
$title = preg_replace ( '|-+|' , '-' , $title );
$title = trim ( $title , '-' );
2004-05-16 18:14:14 -04:00
2005-01-02 04:08:55 -05:00
return $title ;
2004-05-16 18:07:26 -04:00
}
2008-08-17 07:29:43 -04:00
/**
2008-08-27 02:49:21 -04:00
* Ensures a string is a valid SQL order by clause .
2008-08-17 07:29:43 -04:00
*
2008-08-27 02:49:21 -04:00
* Accepts one or more columns , with or without ASC / DESC , and also accepts
* RAND () .
2008-08-17 07:29:43 -04:00
*
* @ since 2.5 . 1
*
2008-08-27 02:49:21 -04:00
* @ param string $orderby Order by string to be checked .
2014-11-30 20:34:24 -05:00
* @ return false | string Returns the order by clause if it is a match , false otherwise .
2008-08-17 07:29:43 -04:00
*/
2008-04-02 23:05:49 -04:00
function sanitize_sql_orderby ( $orderby ){
preg_match ( '/^\s*([a-z0-9_]+(\s+(ASC|DESC))?(\s*,\s*|\s*$))+|^\s*RAND\(\s*\)\s*$/i' , $orderby , $obmatches );
if ( ! $obmatches )
return false ;
return $orderby ;
}
2009-05-22 13:44:26 -04:00
/**
2013-02-01 13:07:08 -05:00
* Sanitizes an HTML classname to ensure it only contains valid characters .
2009-05-24 19:47:49 -04:00
*
2011-04-06 17:28:52 -04:00
* Strips the string down to A - Z , a - z , 0 - 9 , _ , -. If this results in an empty
2009-05-22 13:44:26 -04:00
* string then it will return the alternative value supplied .
2009-05-24 19:47:49 -04:00
*
2009-05-22 17:31:42 -04:00
* @ todo Expand to support the full range of CDATA that a class attribute can contain .
2009-05-24 19:47:49 -04:00
*
2009-05-22 17:31:42 -04:00
* @ since 2.8 . 0
2009-05-24 19:47:49 -04:00
*
2009-05-22 17:31:42 -04:00
* @ param string $class The classname to be sanitized
2014-07-03 12:58:16 -04:00
* @ param string $fallback Optional . The value to return if the sanitization ends up as an empty string .
2010-02-27 15:06:35 -05:00
* Defaults to an empty string .
2009-05-22 17:31:42 -04:00
* @ return string The sanitized value
2009-05-22 13:44:26 -04:00
*/
2010-02-27 15:06:35 -05:00
function sanitize_html_class ( $class , $fallback = '' ) {
2009-05-22 13:44:26 -04:00
//Strip out any % encoded octets
2011-04-06 17:28:52 -04:00
$sanitized = preg_replace ( '|%[a-fA-F0-9][a-fA-F0-9]|' , '' , $class );
2009-05-24 19:47:49 -04:00
2011-04-06 17:28:52 -04:00
//Limit to A-Z,a-z,0-9,_,-
$sanitized = preg_replace ( '/[^A-Za-z0-9_-]/' , '' , $sanitized );
2009-05-24 19:47:49 -04:00
2010-02-27 15:06:35 -05:00
if ( '' == $sanitized )
2009-05-22 17:31:42 -04:00
$sanitized = $fallback ;
2009-05-24 19:47:49 -04:00
2013-11-30 13:36:10 -05:00
/**
* 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 .
*/
2010-02-27 15:06:35 -05:00
return apply_filters ( 'sanitize_html_class' , $sanitized , $class , $fallback );
2009-05-22 13:44:26 -04:00
}
2008-08-17 07:29:43 -04:00
/**
2008-08-27 02:49:21 -04:00
* Converts a number of characters from a string .
2008-08-17 07:29:43 -04:00
*
2014-11-24 00:30:25 -05:00
* Metadata tags `<title>` and `<category>` are removed , `<br>` and `<hr>` are
2008-08-27 02:49:21 -04:00
* converted into correct XHTML and Unicode characters are converted to the
* valid range .
2008-08-17 07:29:43 -04:00
*
* @ since 0.71
*
2008-08-27 02:49:21 -04:00
* @ param string $content String of characters to be converted .
* @ param string $deprecated Not used .
2008-08-17 07:29:43 -04:00
* @ return string Converted string .
*/
2007-12-06 14:49:33 -05:00
function convert_chars ( $content , $deprecated = '' ) {
2009-12-30 11:23:39 -05:00
if ( ! empty ( $deprecated ) )
2010-01-09 05:03:55 -05:00
_deprecated_argument ( __FUNCTION__ , '0.71' );
2009-12-30 11:23:39 -05:00
2004-12-22 19:08:43 -05:00
// Translation of invalid Unicode references range to valid range
$wp_htmltranswinuni = array (
'€' => '€' , // the Euro sign
'' => '' ,
'‚' => '‚' , // these are Windows CP1252 specific characters
'ƒ' => 'ƒ' , // they would look weird on non-Windows browsers
'„' => '„' ,
'…' => '…' ,
'†' => '†' ,
'‡' => '‡' ,
'ˆ' => 'ˆ' ,
'‰' => '‰' ,
'Š' => 'Š' ,
'‹' => '‹' ,
'Œ' => 'Œ' ,
'' => '' ,
2012-04-30 17:20:50 -04:00
'Ž' => 'Ž' ,
2004-12-22 19:08:43 -05:00
'' => '' ,
'' => '' ,
'‘' => '‘' ,
'’' => '’' ,
'“' => '“' ,
'”' => '”' ,
'•' => '•' ,
'–' => '–' ,
'—' => '—' ,
'˜' => '˜' ,
'™' => '™' ,
'š' => 'š' ,
'›' => '›' ,
'œ' => 'œ' ,
'' => '' ,
2012-04-30 17:20:50 -04:00
'ž' => 'ž' ,
2004-12-22 19:08:43 -05:00
'Ÿ' => 'Ÿ'
);
2004-02-09 01:57:02 -05:00
2004-04-22 03:41:57 -04:00
// Remove metadata tags
2004-02-09 01:57:02 -05:00
$content = preg_replace ( '/<title>(.+?)<\/title>/' , '' , $content );
$content = preg_replace ( '/<category>(.+?)<\/category>/' , '' , $content );
2004-04-22 03:41:57 -04:00
// Converts lone & characters into & (a.k.a. &)
2005-11-12 21:48:35 -05:00
$content = preg_replace ( '/&([^#])(?![a-z1-4]{1,8};)/i' , '&$1' , $content );
2004-04-22 03:41:57 -04:00
// Fix Word pasting
2004-04-21 20:44:14 -04:00
$content = strtr ( $content , $wp_htmltranswinuni );
2004-02-09 01:57:02 -05:00
2004-04-22 03:41:57 -04:00
// Just a little XHTML help
$content = str_replace ( '<br>' , '<br />' , $content );
$content = str_replace ( '<hr>' , '<hr />' , $content );
2004-02-09 01:57:02 -05:00
return $content ;
}
2008-08-17 07:29:43 -04:00
/**
2013-02-01 17:20:06 -05:00
* Balances tags if forced to , or if the 'use_balanceTags' option is set to true .
2008-08-17 07:29:43 -04:00
*
* @ since 0.71
*
* @ param string $text Text to be balanced
2011-12-16 15:57:05 -05:00
* @ param bool $force If true , forces balancing , ignoring the value of the option . Default false .
2008-08-17 07:29:43 -04:00
* @ return string Balanced text
*/
2007-07-16 15:23:41 -04:00
function balanceTags ( $text , $force = false ) {
2013-11-08 17:22:11 -05:00
if ( $force || get_option ( 'use_balanceTags' ) == 1 ) {
2013-12-03 12:08:10 -05:00
return force_balance_tags ( $text );
} else {
return $text ;
2013-11-08 17:22:11 -05:00
}
2007-07-16 15:23:41 -04:00
}
2008-08-17 07:29:43 -04:00
/**
* Balances tags of string using a modified stack .
*
* @ since 2.0 . 4
*
* @ author Leonard Lin < leonard @ acm . org >
2010-08-26 11:43:32 -04:00
* @ license GPL
2008-08-30 17:28:11 -04:00
* @ copyright November 4 , 2001
2008-08-17 07:29:43 -04:00
* @ version 1.1
* @ todo Make better - change loop condition to $text in 1.2
* @ internal Modified by Scott Reilly ( coffee2code ) 02 Aug 2004
* 1.1 Fixed handling of append / stack pop order of end text
* Added Cleaning Hooks
* 1.0 First Version
*
2008-08-27 02:49:21 -04:00
* @ param string $text Text to be balanced .
* @ return string Balanced text .
2008-08-17 07:29:43 -04:00
*/
2007-07-16 15:23:41 -04:00
function force_balance_tags ( $text ) {
2010-04-01 09:18:34 -04:00
$tagstack = array ();
$stacksize = 0 ;
$tagqueue = '' ;
$newtext = '' ;
2012-09-13 12:39:06 -04:00
// Known single-entity/self-closing tags
$single_tags = array ( 'area' , 'base' , 'basefont' , 'br' , 'col' , 'command' , 'embed' , 'frame' , 'hr' , 'img' , 'input' , 'isindex' , 'link' , 'meta' , 'param' , 'source' );
// Tags that can be immediately nested within themselves
$nestable_tags = array ( 'blockquote' , 'div' , 'object' , 'q' , 'span' );
2010-04-01 09:18:34 -04:00
// WP bug fix for comments - in case you REALLY meant to type '< !--'
2004-02-09 01:57:02 -05:00
$text = str_replace ( '< !--' , '< !--' , $text );
2010-04-01 09:18:34 -04:00
// WP bug fix for LOVE <3 (and other situations with '<' before a number)
2004-02-09 01:57:02 -05:00
$text = preg_replace ( '#<([0-9]{1})#' , '<$1' , $text );
2010-04-01 09:18:34 -04:00
while ( preg_match ( " /<( \ /?[ \ w:]*) \ s*([^>]*)>/ " , $text , $regex ) ) {
2005-01-06 05:24:11 -05:00
$newtext .= $tagqueue ;
2004-02-09 01:57:02 -05:00
2010-04-01 09:18:34 -04:00
$i = strpos ( $text , $regex [ 0 ]);
2005-01-06 05:24:11 -05:00
$l = strlen ( $regex [ 0 ]);
2004-02-09 01:57:02 -05:00
// clear the shifter
$tagqueue = '' ;
// Pop or Push
2009-02-07 23:16:58 -05:00
if ( isset ( $regex [ 1 ][ 0 ]) && '/' == $regex [ 1 ][ 0 ] ) { // End Tag
2004-02-09 01:57:02 -05:00
$tag = strtolower ( substr ( $regex [ 1 ], 1 ));
// if too many closing tags
2010-04-01 09:18:34 -04:00
if ( $stacksize <= 0 ) {
2004-02-09 01:57:02 -05:00
$tag = '' ;
2010-04-01 09:18:34 -04:00
// or close to be safe $tag = '/' . $tag;
2004-02-09 01:57:02 -05:00
}
// if stacktop value = tag close value then pop
2015-01-08 02:05:25 -05:00
elseif ( $tagstack [ $stacksize - 1 ] == $tag ) { // found closing tag
2004-02-09 01:57:02 -05:00
$tag = '</' . $tag . '>' ; // Close Tag
// Pop
2010-04-01 09:18:34 -04:00
array_pop ( $tagstack );
2004-02-09 01:57:02 -05:00
$stacksize -- ;
} else { // closing tag not at top, search for it
2010-04-01 09:18:34 -04:00
for ( $j = $stacksize - 1 ; $j >= 0 ; $j -- ) {
if ( $tagstack [ $j ] == $tag ) {
2004-02-09 01:57:02 -05:00
// add tag to tagqueue
2010-04-01 09:18:34 -04:00
for ( $k = $stacksize - 1 ; $k >= $j ; $k -- ) {
$tagqueue .= '</' . array_pop ( $tagstack ) . '>' ;
2004-02-09 01:57:02 -05:00
$stacksize -- ;
}
break ;
}
}
$tag = '' ;
}
} else { // Begin Tag
$tag = strtolower ( $regex [ 1 ]);
// Tag Cleaning
2012-09-13 12:39:06 -04:00
// If it's an empty tag "< >", do nothing
if ( '' == $tag ) {
2010-04-01 09:18:34 -04:00
// do nothing
2005-01-06 05:24:11 -05:00
}
2012-09-13 12:39:06 -04:00
// ElseIf it presents itself as a self-closing tag...
elseif ( substr ( $regex [ 2 ], - 1 ) == '/' ) {
// ...but it isn't a known single-entity self-closing tag, then don't let it be treated as such and
// immediately close it with a closing tag (the tag will encapsulate no text as a result)
if ( ! in_array ( $tag , $single_tags ) )
$regex [ 2 ] = trim ( substr ( $regex [ 2 ], 0 , - 1 ) ) . " ></ $tag " ;
}
2005-01-06 05:24:11 -05:00
// ElseIf it's a known single-entity tag but it doesn't close itself, do so
2007-05-31 22:33:03 -04:00
elseif ( in_array ( $tag , $single_tags ) ) {
2005-01-06 05:24:11 -05:00
$regex [ 2 ] .= '/' ;
2012-09-13 12:39:06 -04:00
}
// Else it's not a single-entity tag
else {
2005-01-06 05:24:11 -05:00
// If the top of the stack is the same as the tag we want to push, close previous tag
2010-04-01 09:18:34 -04:00
if ( $stacksize > 0 && ! in_array ( $tag , $nestable_tags ) && $tagstack [ $stacksize - 1 ] == $tag ) {
2012-09-13 12:39:06 -04:00
$tagqueue = '</' . array_pop ( $tagstack ) . '>' ;
2005-01-06 05:24:11 -05:00
$stacksize -- ;
}
2012-09-13 12:39:06 -04:00
$stacksize = array_push ( $tagstack , $tag );
2004-02-09 01:57:02 -05:00
}
// Attributes
$attributes = $regex [ 2 ];
2012-09-13 12:39:06 -04:00
if ( ! empty ( $attributes ) && $attributes [ 0 ] != '>' )
$attributes = ' ' . $attributes ;
2010-04-01 09:18:34 -04:00
$tag = '<' . $tag . $attributes . '>' ;
2005-01-06 05:24:11 -05:00
//If already queuing a close tag, then put this tag on, too
2010-04-01 09:18:34 -04:00
if ( ! empty ( $tagqueue ) ) {
2005-01-06 05:24:11 -05:00
$tagqueue .= $tag ;
$tag = '' ;
}
2004-02-09 01:57:02 -05:00
}
2010-04-01 09:18:34 -04:00
$newtext .= substr ( $text , 0 , $i ) . $tag ;
$text = substr ( $text , $i + $l );
2006-11-19 02:56:05 -05:00
}
2004-02-09 01:57:02 -05:00
// Clear Tag Queue
2005-01-06 05:24:11 -05:00
$newtext .= $tagqueue ;
2004-02-09 01:57:02 -05:00
// Add Remaining text
$newtext .= $text ;
// Empty Stack
2010-04-01 09:18:34 -04:00
while ( $x = array_pop ( $tagstack ) )
2005-01-06 05:24:11 -05:00
$newtext .= '</' . $x . '>' ; // Add remaining tags to close
2004-02-09 01:57:02 -05:00
2004-04-22 03:41:57 -04:00
// WP fix for the bug with HTML comments
2004-02-09 01:57:02 -05:00
$newtext = str_replace ( " < !-- " , " <!-- " , $newtext );
$newtext = str_replace ( " < !-- " , " < !-- " , $newtext );
return $newtext ;
}
2008-08-17 07:29:43 -04:00
/**
2008-08-27 02:49:21 -04:00
* Acts on text which is about to be edited .
2008-08-17 07:29:43 -04:00
*
2012-02-23 20:58:18 -05:00
* The $content is run through esc_textarea (), which uses htmlspecialchars ()
* to convert special characters to HTML entities . If $richedit is set to true ,
* it is simply a holder for the 'format_to_edit' filter .
2008-08-17 07:29:43 -04:00
*
* @ since 0.71
*
2008-08-27 02:49:21 -04:00
* @ param string $content The text about to be edited .
2012-02-23 20:58:18 -05:00
* @ param bool $richedit Whether the $content should not pass through htmlspecialchars () . Default false ( meaning it will be passed ) .
2008-08-27 02:49:21 -04:00
* @ return string The text after the filter ( and possibly htmlspecialchars ()) has been run .
2008-08-17 07:29:43 -04:00
*/
2010-12-25 13:10:59 -05:00
function format_to_edit ( $content , $richedit = false ) {
2013-11-30 13:36:10 -05:00
/**
* Filter the text to be formatted for editing .
*
2013-11-30 14:05:10 -05:00
* @ since 1.2 . 0
2013-11-30 13:36:10 -05:00
*
* @ param string $content The text , prior to formatting for editing .
*/
2010-12-25 13:10:59 -05:00
$content = apply_filters ( 'format_to_edit' , $content );
if ( ! $richedit )
$content = esc_textarea ( $content );
2004-02-09 01:57:02 -05:00
return $content ;
}
2004-03-28 22:54:57 -05:00
2008-08-17 07:29:43 -04:00
/**
2008-08-27 02:49:21 -04:00
* Add leading zeros when necessary .
2008-08-17 07:29:43 -04:00
*
2008-08-30 17:28:11 -04:00
* If you set the threshold to '4' and the number is '10' , then you will get
2011-10-04 12:02:33 -04:00
* back '0010' . If you set the threshold to '4' and the number is '5000' , then you
2008-08-30 17:28:11 -04:00
* will get back '5000' .
2008-08-17 07:29:43 -04:00
*
2008-08-31 16:58:19 -04:00
* Uses sprintf to append the amount of zeros based on the $threshold parameter
* and the size of the number . If the number is large enough , then no zeros will
* be appended .
*
2008-08-17 07:29:43 -04:00
* @ since 0.71
*
2008-08-31 16:58:19 -04:00
* @ param mixed $number Number to append zeros to if not greater than threshold .
* @ param int $threshold Digit places number needs to be to not have zeros added .
* @ return string Adds leading zeros to number if needed .
2008-08-17 07:29:43 -04:00
*/
2008-08-30 17:28:11 -04:00
function zeroise ( $number , $threshold ) {
2004-12-30 12:34:27 -05:00
return sprintf ( '%0' . $threshold . 's' , $number );
2006-06-07 23:17:01 -04:00
}
2004-02-09 01:57:02 -05:00
2008-08-17 07:29:43 -04:00
/**
* Adds backslashes before letters and before a number at the start of a string .
*
* @ since 0.71
*
* @ param string $string Value to which backslashes will be added .
* @ return string String with backslashes inserted .
*/
2004-02-09 01:57:02 -05:00
function backslashit ( $string ) {
2013-04-22 16:01:57 -04:00
if ( isset ( $string [ 0 ] ) && $string [ 0 ] >= '0' && $string [ 0 ] <= '9' )
$string = '\\\\' . $string ;
return addcslashes ( $string , 'A..Za..z' );
2004-02-09 01:57:02 -05:00
}
2008-08-17 07:29:43 -04:00
/**
2008-08-27 02:49:21 -04:00
* Appends a trailing slash .
2008-08-17 07:29:43 -04:00
*
2014-03-01 16:45:15 -05:00
* Will remove trailing forward and backslashes if it exists already before adding
* a trailing forward slash . This prevents double slashing a string or path .
2008-08-17 07:29:43 -04:00
*
2008-08-27 02:49:21 -04:00
* The primary use of this is for paths and thus should be used for paths . It is
* not restricted to paths and offers no specific path support .
2008-08-17 07:29:43 -04:00
*
* @ since 1.2 . 0
*
2008-08-27 02:49:21 -04:00
* @ param string $string What to add the trailing slash to .
* @ return string String with trailing slash added .
2008-08-17 07:29:43 -04:00
*/
2014-03-01 16:45:15 -05:00
function trailingslashit ( $string ) {
return untrailingslashit ( $string ) . '/' ;
2004-02-09 01:57:02 -05:00
}
2008-08-17 07:29:43 -04:00
/**
2014-03-01 16:45:15 -05:00
* Removes trailing forward slashes and backslashes if they exist .
2008-08-17 07:29:43 -04:00
*
2008-08-27 02:49:21 -04:00
* The primary use of this is for paths and thus should be used for paths . It is
* not restricted to paths and offers no specific path support .
2008-08-17 07:29:43 -04:00
*
* @ since 2.2 . 0
*
2014-03-01 16:45:15 -05:00
* @ param string $string What to remove the trailing slashes from .
* @ return string String without the trailing slashes .
2008-08-17 07:29:43 -04:00
*/
2014-03-01 16:45:15 -05:00
function untrailingslashit ( $string ) {
return rtrim ( $string , '/\\' );
2007-03-10 01:25:33 -05:00
}
2008-08-17 07:29:43 -04:00
/**
2008-08-27 02:49:21 -04:00
* Adds slashes to escape strings .
2008-08-17 07:29:43 -04:00
*
2008-08-30 17:28:11 -04:00
* Slashes will first be removed if magic_quotes_gpc is set , see { @ link
* http :// www . php . net / magic_quotes } for more details .
2008-08-17 07:29:43 -04:00
*
* @ since 0.71
*
2008-08-27 02:49:21 -04:00
* @ param string $gpc The string returned from HTTP request data .
2008-12-09 13:03:31 -05:00
* @ return string Returns a string escaped with slashes .
2008-08-17 07:29:43 -04:00
*/
2004-02-09 01:57:02 -05:00
function addslashes_gpc ( $gpc ) {
2010-02-19 19:50:29 -05:00
if ( get_magic_quotes_gpc () )
2005-07-05 16:47:22 -04:00
$gpc = stripslashes ( $gpc );
2013-03-03 11:30:38 -05:00
return wp_slash ( $gpc );
2004-02-09 01:57:02 -05:00
}
2008-08-17 07:29:43 -04:00
/**
2008-08-27 02:49:21 -04:00
* Navigates through an array and removes slashes from the values .
2008-08-17 07:29:43 -04:00
*
2008-08-30 17:28:11 -04:00
* 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 .
2008-08-17 07:29:43 -04:00
*
* @ since 2.0 . 0
*
2012-07-20 11:14:26 -04:00
* @ param mixed $value The value to be stripped .
* @ return mixed Stripped value .
2008-08-17 07:29:43 -04:00
*/
2007-04-12 18:00:22 -04:00
function stripslashes_deep ( $value ) {
2010-05-20 17:16:44 -04:00
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 );
}
2012-07-20 11:14:26 -04:00
} elseif ( is_string ( $value ) ) {
2010-05-20 17:16:44 -04:00
$value = stripslashes ( $value );
}
2008-08-30 17:28:11 -04:00
return $value ;
2007-04-12 18:00:22 -04:00
}
2008-08-17 07:29:43 -04:00
/**
2008-08-27 02:49:21 -04:00
* Navigates through an array and encodes the values to be used in a URL .
2008-08-17 07:29:43 -04:00
*
*
* @ since 2.2 . 0
*
2008-08-27 02:49:21 -04:00
* @ param array | string $value The array or string to be encoded .
* @ return array | string $value The encoded array ( or string from the callback ) .
2008-08-17 07:29:43 -04:00
*/
2007-04-12 18:00:22 -04:00
function urlencode_deep ( $value ) {
2008-08-30 17:28:11 -04:00
$value = is_array ( $value ) ? array_map ( 'urlencode_deep' , $value ) : urlencode ( $value );
return $value ;
2005-07-05 21:12:38 -04:00
}
2012-04-27 11:40:00 -04:00
/**
* Navigates through an array 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 ) .
*/
function rawurlencode_deep ( $value ) {
return is_array ( $value ) ? array_map ( 'rawurlencode_deep' , $value ) : rawurlencode ( $value );
}
2008-08-17 07:29:43 -04:00
/**
2008-08-31 16:58:19 -04:00
* Converts email addresses characters to HTML entities to block spam bots .
2008-08-17 07:29:43 -04:00
*
* @ since 0.71
*
2013-08-20 02:08:09 -04:00
* @ param string $email_address Email address .
2013-08-27 21:47:09 -04:00
* @ param int $hex_encoding Optional . Set to 1 to enable hex encoding .
2008-08-31 16:58:19 -04:00
* @ return string Converted email address .
2008-08-17 07:29:43 -04:00
*/
2013-08-27 21:47:09 -04:00
function antispambot ( $email_address , $hex_encoding = 0 ) {
2013-08-20 02:08:09 -04:00
$email_no_spam_address = '' ;
2015-03-08 19:01:26 -04:00
for ( $i = 0 , $len = strlen ( $email_address ); $i < $len ; $i ++ ) {
2013-08-27 21:47:09 -04:00
$j = rand ( 0 , 1 + $hex_encoding );
2013-08-20 02:08:09 -04:00
if ( $j == 0 ) {
2013-08-27 21:47:09 -04:00
$email_no_spam_address .= '&#' . ord ( $email_address [ $i ] ) . ';' ;
2013-08-20 02:08:09 -04:00
} elseif ( $j == 1 ) {
2013-08-27 21:47:09 -04:00
$email_no_spam_address .= $email_address [ $i ];
2013-08-20 02:08:09 -04:00
} elseif ( $j == 2 ) {
2013-08-27 21:47:09 -04:00
$email_no_spam_address .= '%' . zeroise ( dechex ( ord ( $email_address [ $i ] ) ), 2 );
2004-02-09 01:57:02 -05:00
}
}
2013-08-20 02:08:09 -04:00
$email_no_spam_address = str_replace ( '@' , '@' , $email_no_spam_address );
return $email_no_spam_address ;
2004-02-09 01:57:02 -05:00
}
2008-08-17 07:29:43 -04:00
/**
2008-08-30 17:28:11 -04:00
* Callback to convert URI match to HTML A element .
2008-08-17 07:29:43 -04:00
*
2008-08-30 17:28:11 -04:00
* This function was backported from 2.5 . 0 to 2.3 . 2. Regex callback for { @ link
* make_clickable ()} .
2008-08-17 07:29:43 -04:00
*
2008-08-30 17:28:11 -04:00
* @ since 2.3 . 2
2008-08-17 07:29:43 -04:00
* @ access private
*
2008-08-30 17:28:11 -04:00
* @ param array $matches Single Regex Match .
* @ return string HTML A element with URI address .
2008-08-17 07:29:43 -04:00
*/
2007-12-20 22:14:22 -05:00
function _make_url_clickable_cb ( $matches ) {
$url = $matches [ 2 ];
2011-01-05 23:11:14 -05:00
2012-02-10 08:42:15 -05:00
if ( ')' == $matches [ 3 ] && strpos ( $url , '(' ) ) {
// If the trailing character is a closing parethesis, and the URL has an opening parenthesis in it, add the closing parenthesis to the URL.
// Then we can let the parenthesis balancer do its thing below.
$url .= $matches [ 3 ];
$suffix = '' ;
} else {
$suffix = $matches [ 3 ];
}
// Include parentheses in the URL only if paired
2010-12-15 08:43:30 -05:00
while ( substr_count ( $url , '(' ) < substr_count ( $url , ')' ) ) {
2011-01-05 23:11:14 -05:00
$suffix = strrchr ( $url , ')' ) . $suffix ;
$url = substr ( $url , 0 , strrpos ( $url , ')' ) );
2010-12-15 08:43:30 -05:00
}
2009-08-19 19:56:10 -04:00
2009-05-18 12:00:33 -04:00
$url = esc_url ( $url );
2007-12-20 22:14:22 -05:00
if ( empty ( $url ) )
return $matches [ 0 ];
2009-08-19 19:56:10 -04:00
2010-12-15 08:43:30 -05:00
return $matches [ 1 ] . " <a href= \" $url\ " rel = \ " nofollow \" > $url </a> " . $suffix ;
2007-12-20 22:14:22 -05:00
}
2008-08-17 07:29:43 -04:00
/**
2008-08-30 17:28:11 -04:00
* Callback to convert URL match to HTML A element .
2008-08-17 07:29:43 -04:00
*
2008-08-30 17:28:11 -04:00
* This function was backported from 2.5 . 0 to 2.3 . 2. Regex callback for { @ link
* make_clickable ()} .
2008-08-17 07:29:43 -04:00
*
2008-08-30 17:28:11 -04:00
* @ since 2.3 . 2
2008-08-17 07:29:43 -04:00
* @ access private
*
2008-08-30 17:28:11 -04:00
* @ param array $matches Single Regex Match .
* @ return string HTML A element with URL address .
2008-08-17 07:29:43 -04:00
*/
2007-12-20 22:14:22 -05:00
function _make_web_ftp_clickable_cb ( $matches ) {
2008-03-21 12:29:59 -04:00
$ret = '' ;
2007-12-20 22:14:22 -05:00
$dest = $matches [ 2 ];
$dest = 'http://' . $dest ;
2009-05-18 12:00:33 -04:00
$dest = esc_url ( $dest );
2007-12-20 22:14:22 -05:00
if ( empty ( $dest ) )
return $matches [ 0 ];
2009-08-19 19:56:10 -04:00
// removed trailing [.,;:)] from URL
if ( in_array ( substr ( $dest , - 1 ), array ( '.' , ',' , ';' , ':' , ')' ) ) === true ) {
2008-03-21 12:29:59 -04:00
$ret = substr ( $dest , - 1 );
$dest = substr ( $dest , 0 , strlen ( $dest ) - 1 );
}
2009-08-19 19:56:10 -04:00
return $matches [ 1 ] . " <a href= \" $dest\ " rel = \ " nofollow \" > $dest </a> $ret " ;
2007-12-20 22:14:22 -05:00
}
2008-08-17 07:29:43 -04:00
/**
2008-08-30 17:28:11 -04:00
* Callback to convert email address match to HTML A element .
2008-08-17 07:29:43 -04:00
*
2008-08-30 17:28:11 -04:00
* This function was backported from 2.5 . 0 to 2.3 . 2. Regex callback for { @ link
* make_clickable ()} .
2008-08-17 07:29:43 -04:00
*
2008-08-30 17:28:11 -04:00
* @ since 2.3 . 2
2008-08-17 07:29:43 -04:00
* @ access private
*
2008-08-30 17:28:11 -04:00
* @ param array $matches Single Regex Match .
* @ return string HTML A element with email address .
2008-08-17 07:29:43 -04:00
*/
2007-12-20 22:14:22 -05:00
function _make_email_clickable_cb ( $matches ) {
$email = $matches [ 2 ] . '@' . $matches [ 3 ];
return $matches [ 1 ] . " <a href= \" mailto: $email\ " > $email </ a > " ;
}
2008-08-17 07:29:43 -04:00
/**
2008-08-30 17:28:11 -04:00
* Convert plaintext URI to HTML links .
2008-08-17 07:29:43 -04:00
*
2008-08-30 17:28:11 -04:00
* Converts URI , www and ftp , and email addresses . Finishes by fixing links
* within links .
2008-08-17 07:29:43 -04:00
*
* @ since 0.71
*
2012-04-11 17:14:13 -04:00
* @ param string $text Content to convert URIs .
2008-08-30 17:28:11 -04:00
* @ return string Content with converted URIs .
2008-08-17 07:29:43 -04:00
*/
2012-04-11 17:14:13 -04:00
function make_clickable ( $text ) {
$r = '' ;
$textarr = preg_split ( '/(<[^<>]+>)/' , $text , - 1 , PREG_SPLIT_DELIM_CAPTURE ); // split out HTML tags
2013-11-08 17:38:10 -05:00
$nested_code_pre = 0 ; // Keep track of how many levels link is nested inside <pre> or <code>
2012-04-11 17:14:13 -04:00
foreach ( $textarr as $piece ) {
2013-11-08 17:38:10 -05:00
2013-11-11 16:54:10 -05:00
if ( preg_match ( '|^<code[\s>]|i' , $piece ) || preg_match ( '|^<pre[\s>]|i' , $piece ) )
2013-11-08 17:38:10 -05:00
$nested_code_pre ++ ;
2013-11-11 16:54:10 -05:00
elseif ( ( '</code>' === strtolower ( $piece ) || '</pre>' === strtolower ( $piece ) ) && $nested_code_pre )
2013-11-08 17:38:10 -05:00
$nested_code_pre -- ;
if ( $nested_code_pre || empty ( $piece ) || ( $piece [ 0 ] === '<' && ! preg_match ( '|^<\s*[\w]{1,20}+://|' , $piece ) ) ) {
2012-04-11 17:14:13 -04:00
$r .= $piece ;
continue ;
}
// Long strings might contain expensive edge cases ...
if ( 10000 < strlen ( $piece ) ) {
// ... break it up
foreach ( _split_str_by_whitespace ( $piece , 2100 ) as $chunk ) { // 2100: Extra room for scheme and leading and trailing paretheses
if ( 2101 < strlen ( $chunk ) ) {
$r .= $chunk ; // Too big, no whitespace: bail.
} else {
$r .= make_clickable ( $chunk );
}
2012-02-10 08:42:15 -05:00
}
2012-04-11 17:14:13 -04:00
} else {
$ret = " $piece " ; // Pad with whitespace to simplify the regexes
$url_clickable = ' ~
([ \\s ( <. ,; :! ? ]) # 1: Leading whitespace, or punctuation
( # 2: URL
[ \\w ]{ 1 , 20 } +:// # Scheme and hier-part prefix
( ? = \S { 1 , 2000 } \s ) # Limit to URLs less than about 2000 characters long
[ \\w\\x80 - \\xff #%\\~/@\\[\\]*(+=&$-]*+ # Non-punctuation URL character
( ? : # Unroll the Loop: Only allow puctuation URL character if followed by a non-punctuation URL character
[ \ ' . ,; :! ? )] # Punctuation URL character
[ \\w\\x80 - \\xff #%\\~/@\\[\\]*(+=&$-]++ # Non-punctuation URL character
) *
)
( \ ) ? ) # 3: Trailing closing parenthesis (for parethesis balancing post processing)
~ xS ' ; // The regex is a non-anchored pattern and does not have a single fixed starting character.
// Tell PCRE to spend more time optimizing since, when used on a page load, it will probably be used several times.
$ret = preg_replace_callback ( $url_clickable , '_make_url_clickable_cb' , $ret );
$ret = preg_replace_callback ( '#([\s>])((www|ftp)\.[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]+)#is' , '_make_web_ftp_clickable_cb' , $ret );
$ret = preg_replace_callback ( '#([\s>])([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})#i' , '_make_email_clickable_cb' , $ret );
$ret = substr ( $ret , 1 , - 1 ); // Remove our whitespace padding.
$r .= $ret ;
2012-02-10 08:42:15 -05:00
}
}
// Cleanup of accidental links within links
2014-01-17 04:32:10 -05:00
$r = preg_replace ( '#(<a([ \r\n\t]+[^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i' , " $ 1 $ 3</a> " , $r );
2012-04-11 17:14:13 -04:00
return $r ;
2012-02-10 08:42:15 -05:00
}
/**
* Breaks a string into chunks by splitting at whitespace characters .
* The length of each returned chunk is as close to the specified length goal as possible ,
* with the caveat that each chunk includes its trailing delimiter .
* Chunks longer than the goal are guaranteed to not have any inner whitespace .
*
* Joining the returned chunks with empty delimiters reconstructs the input string losslessly .
*
* Input string must have no null characters ( or eventual transformations on output chunks must not care about null characters )
*
2014-11-24 00:30:25 -05:00
* _split_str_by_whitespace ( " 1234 67890 1234 67890a cd 1234 890 123456789 1234567890a 45678 1 3 5 7 90 " , 10 ) ==
* array (
* 0 => '1234 67890 ' , // 11 characters: Perfect split
* 1 => '1234 ' , // 5 characters: '1234 67890a' was too long
* 2 => '67890a cd ' , // 10 characters: '67890a cd 1234' was too long
* 3 => '1234 890 ' , // 11 characters: Perfect split
* 4 => '123456789 ' , // 10 characters: '123456789 1234567890a' was too long
* 5 => '1234567890a ' , // 12 characters: Too long, but no inner whitespace on which to split
* 6 => ' 45678 ' , // 11 characters: Perfect split
2014-11-25 22:52:22 -05:00
* 7 => '1 3 5 7 90 ' , // 11 characters: End of $string
2014-11-24 00:30:25 -05:00
* );
2012-02-10 08:42:15 -05:00
*
2012-02-10 08:57:21 -05:00
* @ since 3.4 . 0
* @ access private
*
2012-07-09 01:03:53 -04:00
* @ param string $string The string to split .
* @ param int $goal The desired chunk length .
2012-02-10 08:42:15 -05:00
* @ return array Numeric array of chunks .
*/
function _split_str_by_whitespace ( $string , $goal ) {
$chunks = array ();
$string_nullspace = strtr ( $string , " \r \n \t \ v \ f " , " \000 \000 \000 \000 \000 \000 " );
while ( $goal < strlen ( $string_nullspace ) ) {
$pos = strrpos ( substr ( $string_nullspace , 0 , $goal + 1 ), " \000 " );
if ( false === $pos ) {
$pos = strpos ( $string_nullspace , " \000 " , $goal + 1 );
if ( false === $pos ) {
break ;
}
}
$chunks [] = substr ( $string , 0 , $pos + 1 );
$string = substr ( $string , $pos + 1 );
$string_nullspace = substr ( $string_nullspace , $pos + 1 );
}
if ( $string ) {
$chunks [] = $string ;
}
return $chunks ;
2004-02-09 01:57:02 -05:00
}
2008-08-17 07:29:43 -04:00
/**
2008-08-31 16:58:19 -04:00
* Adds rel nofollow string to all HTML A elements in content .
2008-08-17 07:29:43 -04:00
*
* @ since 1.5 . 0
*
2008-08-31 16:58:19 -04:00
* @ param string $text Content that may contain HTML A elements .
* @ return string Converted content .
2008-08-17 07:29:43 -04:00
*/
2005-01-21 13:24:14 -05:00
function wp_rel_nofollow ( $text ) {
2013-03-01 11:28:40 -05:00
// This is a pre save filter, so text is already escaped.
$text = stripslashes ( $text );
2007-09-13 00:51:33 -04:00
$text = preg_replace_callback ( '|<a (.+?)>|i' , 'wp_rel_nofollow_callback' , $text );
2013-03-03 11:30:38 -05:00
$text = wp_slash ( $text );
2005-01-21 13:24:14 -05:00
return $text ;
}
2008-08-17 07:29:43 -04:00
/**
2013-02-15 13:59:56 -05:00
* Callback to add rel = nofollow string to HTML A element .
2008-08-17 07:29:43 -04:00
*
2008-08-31 16:58:19 -04:00
* Will remove already existing rel = " nofollow " and rel = 'nofollow' from the
* string to prevent from invalidating ( X ) HTML .
2008-08-17 07:29:43 -04:00
*
* @ since 2.3 . 0
*
2008-08-31 16:58:19 -04:00
* @ param array $matches Single Match
* @ return string HTML A Element with rel nofollow .
2008-08-17 07:29:43 -04:00
*/
2007-09-13 00:51:33 -04:00
function wp_rel_nofollow_callback ( $matches ) {
$text = $matches [ 1 ];
$text = str_replace ( array ( ' rel="nofollow"' , " rel='nofollow' " ), '' , $text );
return " <a $text rel= \" nofollow \" > " ;
}
2009-01-06 13:20:47 -05:00
/**
* Convert one smiley code to the icon graphic file equivalent .
*
2013-09-29 06:08:10 -04:00
* Callback handler for { @ link convert_smilies ()} .
2009-01-06 13:20:47 -05:00
* Looks up one smiley code in the $wpsmiliestrans global array and returns an
2014-11-24 00:30:25 -05:00
* `<img>` string for that smiley .
2009-01-06 13:20:47 -05:00
*
* @ global array $wpsmiliestrans
* @ since 2.8 . 0
*
2013-09-29 06:08:10 -04:00
* @ param array $matches Single match . Smiley code to convert to image .
2009-01-06 13:20:47 -05:00
* @ return string Image string for smiley .
*/
2013-09-29 06:08:10 -04:00
function translate_smiley ( $matches ) {
2009-01-06 13:20:47 -05:00
global $wpsmiliestrans ;
2013-09-29 06:08:10 -04:00
if ( count ( $matches ) == 0 )
2009-01-06 13:20:47 -05:00
return '' ;
2013-09-29 06:08:10 -04:00
$smiley = trim ( reset ( $matches ) );
$img = $wpsmiliestrans [ $smiley ];
2009-09-14 10:03:32 -04:00
2015-03-11 18:49:28 -04:00
$matches = array ();
$ext = preg_match ( '/\.([^.]+)$/' , $img , $matches ) ? strtolower ( $matches [ 1 ] ) : false ;
$image_exts = array ( 'jpg' , 'jpeg' , 'jpe' , 'gif' , 'png' );
// Don't convert smilies that aren't images - they're probably emoji.
if ( ! in_array ( $ext , $image_exts ) ) {
return $img ;
}
2013-11-30 13:36:10 -05:00
/**
* Filter the Smiley image URL before it ' s used in the image element .
*
* @ since 2.9 . 0
*
* @ param string $smiley_url URL for the smiley image .
* @ param string $img Filename for the smiley image .
* @ param string $site_url Site URL , as returned by site_url () .
2013-12-11 14:49:11 -05:00
*/
2013-09-29 06:08:10 -04:00
$src_url = apply_filters ( 'smilies_src' , includes_url ( " images/smilies/ $img " ), $img , site_url () );
2009-01-06 13:20:47 -05:00
2015-03-26 22:12:28 -04:00
return sprintf ( '<img src="%s" alt="%s" class="wp-smiley" style="height: 1em; max-height: 1em;" />' , esc_url ( $src_url ), esc_attr ( $smiley ) );
2009-01-06 13:20:47 -05:00
}
2008-08-17 07:29:43 -04:00
/**
2008-08-31 16:58:19 -04:00
* Convert text equivalent of smilies to images .
2008-08-17 07:29:43 -04:00
*
2009-01-06 13:20:47 -05:00
* Will only convert smilies if the option 'use_smilies' is true and the global
* used in the function isn ' t empty .
2008-08-17 07:29:43 -04:00
*
* @ since 0.71
2009-01-06 13:20:47 -05:00
* @ uses $wp_smiliessearch
2008-08-17 07:29:43 -04:00
*
2008-08-31 16:58:19 -04:00
* @ param string $text Content to convert smilies from text .
* @ return string Converted content with text smilies replaced with images .
2008-08-17 07:29:43 -04:00
*/
2013-11-14 21:46:10 -05:00
function convert_smilies ( $text ) {
2009-01-06 13:20:47 -05:00
global $wp_smiliessearch ;
2008-08-17 07:29:43 -04:00
$output = '' ;
2013-11-14 21:46:10 -05:00
if ( get_option ( 'use_smilies' ) && ! empty ( $wp_smiliessearch ) ) {
2004-02-09 01:57:02 -05:00
// HTML loop taken from texturize function, could possible be consolidated
2013-11-14 21:46:10 -05:00
$textarr = preg_split ( '/(<.*>)/U' , $text , - 1 , PREG_SPLIT_DELIM_CAPTURE ); // capture the tags as well as in between
$stop = count ( $textarr ); // loop stuff
// Ignore proessing of specific tags
$tags_to_ignore = 'code|pre|style|script|textarea' ;
$ignore_block_element = '' ;
for ( $i = 0 ; $i < $stop ; $i ++ ) {
2007-09-03 19:32:58 -04:00
$content = $textarr [ $i ];
2013-11-14 21:46:10 -05:00
// If we're in an ignore block, wait until we find its closing tag
if ( '' == $ignore_block_element && preg_match ( '/^<(' . $tags_to_ignore . ')>/' , $content , $matches ) ) {
$ignore_block_element = $matches [ 1 ];
}
// If it's not a tag and not in ignore block
if ( '' == $ignore_block_element && strlen ( $content ) > 0 && '<' != $content [ 0 ] ) {
$content = preg_replace_callback ( $wp_smiliessearch , 'translate_smiley' , $content );
}
// did we exit ignore block
if ( '' != $ignore_block_element && '</' . $ignore_block_element . '>' == $content ) {
$ignore_block_element = '' ;
2007-09-03 19:32:58 -04:00
}
2013-11-14 21:46:10 -05:00
2007-09-03 19:32:58 -04:00
$output .= $content ;
2006-10-12 06:14:14 -04:00
}
2004-02-09 01:57:02 -05:00
} else {
// return default text.
$output = $text ;
}
return $output ;
}
2008-08-17 07:29:43 -04:00
/**
2009-03-11 11:26:34 -04:00
* Verifies that an email is valid .
*
* Does not grok i18n domains . Not RFC compliant .
2008-08-17 07:29:43 -04:00
*
* @ since 0.71
*
2009-03-11 11:26:34 -04:00
* @ param string $email Email address to verify .
2010-09-07 07:21:11 -04:00
* @ param boolean $deprecated Deprecated .
2009-03-11 11:26:34 -04:00
* @ return string | bool Either false or the valid email address .
2008-08-17 07:29:43 -04:00
*/
2010-05-03 14:54:37 -04:00
function is_email ( $email , $deprecated = false ) {
if ( ! empty ( $deprecated ) )
_deprecated_argument ( __FUNCTION__ , '3.0' );
2009-03-11 11:26:34 -04:00
// Test for the minimum length the email can be
if ( strlen ( $email ) < 3 ) {
2013-11-30 13:36:10 -05:00
/**
* Filter whether an email address is valid .
*
* This filter is evaluated under several different contexts , such as 'email_too_short' ,
* 'email_no_at' , 'local_invalid_chars' , 'domain_period_sequence' , 'domain_period_limits' ,
* 'domain_no_periods' , 'sub_hyphen_limits' , 'sub_invalid_chars' , or no specific context .
*
* @ since 2.8 . 0
*
* @ 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 .
*/
2009-03-11 11:26:34 -04:00
return apply_filters ( 'is_email' , false , $email , 'email_too_short' );
}
// Test for an @ character after the first position
if ( strpos ( $email , '@' , 1 ) === false ) {
2013-11-30 13:36:10 -05:00
/** This filter is documented in wp-includes/formatting.php */
2009-03-11 11:26:34 -04:00
return apply_filters ( 'is_email' , false , $email , 'email_no_at' );
}
// Split out the local and domain parts
list ( $local , $domain ) = explode ( '@' , $email , 2 );
// LOCAL PART
// Test for invalid characters
if ( ! preg_match ( '/^[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.-]+$/' , $local ) ) {
2013-11-30 13:36:10 -05:00
/** This filter is documented in wp-includes/formatting.php */
2009-03-11 11:26:34 -04:00
return apply_filters ( 'is_email' , false , $email , 'local_invalid_chars' );
}
// DOMAIN PART
// Test for sequences of periods
if ( preg_match ( '/\.{2,}/' , $domain ) ) {
2013-11-30 13:36:10 -05:00
/** This filter is documented in wp-includes/formatting.php */
2009-03-11 11:26:34 -04:00
return apply_filters ( 'is_email' , false , $email , 'domain_period_sequence' );
}
// Test for leading and trailing periods and whitespace
if ( trim ( $domain , " \t \n \r \0 \x0B . " ) !== $domain ) {
2013-11-30 13:36:10 -05:00
/** This filter is documented in wp-includes/formatting.php */
2009-03-11 11:26:34 -04:00
return apply_filters ( 'is_email' , false , $email , 'domain_period_limits' );
}
// Split the domain into subs
$subs = explode ( '.' , $domain );
// Assume the domain will have at least two subs
if ( 2 > count ( $subs ) ) {
2013-11-30 13:36:10 -05:00
/** This filter is documented in wp-includes/formatting.php */
2009-03-11 11:26:34 -04:00
return apply_filters ( 'is_email' , false , $email , 'domain_no_periods' );
}
// Loop through each sub
foreach ( $subs as $sub ) {
// Test for leading and trailing hyphens and whitespace
if ( trim ( $sub , " \t \n \r \0 \x0B - " ) !== $sub ) {
2013-11-30 13:36:10 -05:00
/** This filter is documented in wp-includes/formatting.php */
2009-03-11 11:26:34 -04:00
return apply_filters ( 'is_email' , false , $email , 'sub_hyphen_limits' );
}
// Test for invalid characters
if ( ! preg_match ( '/^[a-z0-9-]+$/i' , $sub ) ) {
2013-11-30 13:36:10 -05:00
/** This filter is documented in wp-includes/formatting.php */
2009-03-11 11:26:34 -04:00
return apply_filters ( 'is_email' , false , $email , 'sub_invalid_chars' );
2004-02-09 01:57:02 -05:00
}
}
2009-03-11 11:26:34 -04:00
// Congratulations your email made it!
2013-11-30 13:36:10 -05:00
/** This filter is documented in wp-includes/formatting.php */
2009-03-11 11:26:34 -04:00
return apply_filters ( 'is_email' , $email , $email , null );
2004-02-09 01:57:02 -05:00
}
2008-08-17 07:29:43 -04:00
/**
2008-08-31 16:58:19 -04:00
* Convert to ASCII from email subjects .
2008-08-17 07:29:43 -04:00
*
* @ since 1.2 . 0
*
2008-08-31 16:58:19 -04:00
* @ param string $string Subject line
* @ return string Converted string to ASCII
2008-08-17 07:29:43 -04:00
*/
2004-02-21 19:31:25 -05:00
function wp_iso_descrambler ( $string ) {
2008-08-17 07:29:43 -04:00
/* this may only work with iso-8859-1, I'm afraid */
if ( ! preg_match ( '#\=\?(.+)\?Q\?(.+)\?\=#i' , $string , $matches )) {
return $string ;
} else {
$subject = str_replace ( '_' , ' ' , $matches [ 2 ]);
2010-11-11 17:50:36 -05:00
$subject = preg_replace_callback ( '#\=([0-9a-f]{2})#i' , '_wp_iso_convert' , $subject );
2008-08-17 07:29:43 -04:00
return $subject ;
}
2004-02-21 19:31:25 -05:00
}
2010-10-28 03:38:00 -04:00
/**
2012-07-09 01:03:53 -04:00
* Helper function to convert hex encoded chars to ASCII
2010-11-17 13:47:34 -05:00
*
2010-10-28 03:38:00 -04:00
* @ since 3.1 . 0
* @ access private
2013-02-01 13:07:08 -05:00
*
2012-07-09 01:03:53 -04:00
* @ param array $match The preg_replace_callback matches array
2014-11-30 20:34:24 -05:00
* @ return string Converted chars
2010-10-28 03:38:00 -04:00
*/
2010-11-17 13:47:34 -05:00
function _wp_iso_convert ( $match ) {
return chr ( hexdec ( strtolower ( $match [ 1 ] ) ) );
}
2010-10-28 03:38:00 -04:00
2008-08-17 07:29:43 -04:00
/**
2008-08-27 02:49:21 -04:00
* Returns a date in the GMT equivalent .
2008-08-17 07:29:43 -04:00
*
2013-03-05 11:14:14 -05:00
* Requires and returns a date in the Y - m - d H : i : s format . If there is a
* timezone_string available , the date is assumed to be in that timezone ,
* otherwise it simply subtracts the value of the 'gmt_offset' option . Return
* format can be overridden using the $format parameter .
2008-08-17 07:29:43 -04:00
*
* @ since 1.2 . 0
*
2008-08-27 02:49:21 -04:00
* @ param string $string The date to be converted .
2009-08-20 02:59:02 -04:00
* @ param string $format The format string for the returned date ( default is Y - m - d H : i : s )
2008-08-27 02:49:21 -04:00
* @ return string GMT version of the date provided .
2008-08-17 07:29:43 -04:00
*/
2013-03-05 11:14:14 -05:00
function get_gmt_from_date ( $string , $format = 'Y-m-d H:i:s' ) {
$tz = get_option ( 'timezone_string' );
2011-05-18 14:56:42 -04:00
if ( $tz ) {
2013-03-05 11:14:14 -05:00
$datetime = date_create ( $string , new DateTimeZone ( $tz ) );
2012-11-07 15:07:41 -05:00
if ( ! $datetime )
2013-03-05 11:14:14 -05:00
return gmdate ( $format , 0 );
$datetime -> setTimezone ( new DateTimeZone ( 'UTC' ) );
$string_gmt = $datetime -> format ( $format );
2011-05-18 14:56:42 -04:00
} else {
2013-03-05 11:14:14 -05:00
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 );
$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 );
2011-05-18 14:56:42 -04:00
}
2008-08-17 07:29:43 -04:00
return $string_gmt ;
2004-02-22 22:04:55 -05:00
}
2008-08-17 07:29:43 -04:00
/**
2008-08-27 02:49:21 -04:00
* Converts a GMT date into the correct format for the blog .
2008-08-17 07:29:43 -04:00
*
2013-03-05 11:14:14 -05:00
* Requires and returns a date in the Y - m - d H : i : s format . If there is a
* timezone_string available , the returned date is in that timezone , otherwise
* it simply adds the value of gmt_offset . Return format can be overridden
* using the $format parameter
2008-08-17 07:29:43 -04:00
*
* @ since 1.2 . 0
*
2008-08-27 02:49:21 -04:00
* @ param string $string The date to be converted .
2009-08-20 02:59:02 -04:00
* @ param string $format The format string for the returned date ( default is Y - m - d H : i : s )
2013-03-05 11:14:14 -05:00
* @ return string Formatted date relative to the timezone / GMT offset .
2008-08-17 07:29:43 -04:00
*/
2013-03-05 11:14:14 -05:00
function get_date_from_gmt ( $string , $format = 'Y-m-d H:i:s' ) {
$tz = get_option ( 'timezone_string' );
if ( $tz ) {
$datetime = date_create ( $string , new DateTimeZone ( 'UTC' ) );
if ( ! $datetime )
return date ( $format , 0 );
$datetime -> setTimezone ( new DateTimeZone ( $tz ) );
$string_localtime = $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 date ( $format , 0 );
$string_time = gmmktime ( $matches [ 4 ], $matches [ 5 ], $matches [ 6 ], $matches [ 2 ], $matches [ 3 ], $matches [ 1 ] );
$string_localtime = gmdate ( $format , $string_time + get_option ( 'gmt_offset' ) * HOUR_IN_SECONDS );
}
2008-08-17 07:29:43 -04:00
return $string_localtime ;
2004-02-22 23:37:11 -05:00
}
2008-08-17 07:29:43 -04:00
/**
2008-08-27 02:49:21 -04:00
* Computes an offset in seconds from an iso8601 timezone .
2008-08-17 07:29:43 -04:00
*
* @ since 1.5 . 0
*
2008-08-27 02:49:21 -04:00
* @ param string $timezone Either 'Z' for 0 offset or '±hhmm' .
2008-12-09 13:03:31 -05:00
* @ return int | float The offset in seconds .
2008-08-17 07:29:43 -04:00
*/
2004-05-31 13:02:09 -04:00
function iso8601_timezone_to_offset ( $timezone ) {
2008-08-17 07:29:43 -04:00
// $timezone is either 'Z' or '[+|-]hhmm'
if ( $timezone == 'Z' ) {
$offset = 0 ;
} else {
$sign = ( substr ( $timezone , 0 , 1 ) == '+' ) ? 1 : - 1 ;
$hours = intval ( substr ( $timezone , 1 , 2 ));
$minutes = intval ( substr ( $timezone , 3 , 4 )) / 60 ;
2012-09-25 01:26:19 -04:00
$offset = $sign * HOUR_IN_SECONDS * ( $hours + $minutes );
2008-08-17 07:29:43 -04:00
}
return $offset ;
2004-05-31 13:02:09 -04:00
}
2008-08-17 07:29:43 -04:00
/**
2008-08-27 02:49:21 -04:00
* Converts an iso8601 date to MySQL DateTime format used by post_date [ _gmt ] .
2008-08-17 07:29:43 -04:00
*
* @ since 1.5 . 0
*
2008-08-27 02:49:21 -04:00
* @ param string $date_string Date and time in ISO 8601 format { @ link http :// en . wikipedia . org / wiki / ISO_8601 } .
2008-08-30 17:28:11 -04:00
* @ param string $timezone Optional . If set to GMT returns the time minus gmt_offset . Default is 'user' .
2008-08-27 02:49:21 -04:00
* @ return string The date and time in MySQL DateTime format - Y - m - d H : i : s .
2008-08-17 07:29:43 -04:00
*/
2008-10-13 18:14:52 -04:00
function iso8601_to_datetime ( $date_string , $timezone = 'user' ) {
$timezone = strtolower ( $timezone );
if ( $timezone == 'gmt' ) {
2008-08-17 07:29:43 -04:00
preg_match ( '#([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(Z|[\+|\-][0-9]{2,4}){0,1}#' , $date_string , $date_bits );
if ( ! empty ( $date_bits [ 7 ])) { // we have a timezone, so let's compute an offset
$offset = iso8601_timezone_to_offset ( $date_bits [ 7 ]);
} else { // we don't have a timezone, so we assume user local timezone (not server's!)
2012-09-25 01:26:19 -04:00
$offset = HOUR_IN_SECONDS * get_option ( 'gmt_offset' );
2008-08-17 07:29:43 -04:00
}
$timestamp = gmmktime ( $date_bits [ 4 ], $date_bits [ 5 ], $date_bits [ 6 ], $date_bits [ 2 ], $date_bits [ 3 ], $date_bits [ 1 ]);
$timestamp -= $offset ;
return gmdate ( 'Y-m-d H:i:s' , $timestamp );
2015-01-08 02:05:25 -05:00
} elseif ( $timezone == 'user' ) {
2008-08-17 07:29:43 -04:00
return preg_replace ( '#([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(Z|[\+|\-][0-9]{2,4}){0,1}#' , '$1-$2-$3 $4:$5:$6' , $date_string );
}
2004-05-31 13:02:09 -04:00
}
2008-08-17 07:29:43 -04:00
/**
2008-08-27 02:49:21 -04:00
* Adds a element attributes to open links in new windows .
2008-08-17 07:29:43 -04:00
*
2008-08-27 02:49:21 -04:00
* 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 .
2008-08-17 07:29:43 -04:00
*
* @ since 0.71
*
2008-08-27 02:49:21 -04:00
* @ param string $text Content to replace links to open in a new window .
* @ return string Content that has filtered links .
2008-08-17 07:29:43 -04:00
*/
2004-06-10 06:01:45 -04:00
function popuplinks ( $text ) {
$text = preg_replace ( '/<a (.+?)>/i' , " <a $ 1 target='_blank' rel='external'> " , $text );
return $text ;
}
2008-08-17 07:29:43 -04:00
/**
2008-08-27 02:49:21 -04:00
* Strips out all characters that are not allowable in an email .
2008-08-17 07:29:43 -04:00
*
* @ since 1.5 . 0
*
2008-08-27 02:49:21 -04:00
* @ param string $email Email address to filter .
* @ return string Filtered email address .
2008-08-17 07:29:43 -04:00
*/
2009-03-11 11:26:34 -04:00
function sanitize_email ( $email ) {
// Test for the minimum length the email can be
if ( strlen ( $email ) < 3 ) {
2013-11-30 13:36:10 -05:00
/**
* Filter a sanitized email address .
*
* This filter is evaluated under several contexts , including 'email_too_short' ,
* 'email_no_at' , 'local_invalid_chars' , 'domain_period_sequence' , 'domain_period_limits' ,
* 'domain_no_periods' , 'domain_no_valid_subs' , or no context .
*
* @ since 2.8 . 0
*
* @ param string $email The sanitized email address .
* @ param string $email The email address , as provided to sanitize_email () .
* @ param string $message A message to pass to the user .
*/
2009-03-11 11:26:34 -04:00
return apply_filters ( 'sanitize_email' , '' , $email , 'email_too_short' );
}
// Test for an @ character after the first position
if ( strpos ( $email , '@' , 1 ) === false ) {
2013-11-30 13:36:10 -05:00
/** This filter is documented in wp-includes/formatting.php */
2009-03-11 11:26:34 -04:00
return apply_filters ( 'sanitize_email' , '' , $email , 'email_no_at' );
}
// Split out the local and domain parts
list ( $local , $domain ) = explode ( '@' , $email , 2 );
// LOCAL PART
// Test for invalid characters
2009-03-13 21:35:47 -04:00
$local = preg_replace ( '/[^a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.-]/' , '' , $local );
if ( '' === $local ) {
2013-11-30 13:36:10 -05:00
/** This filter is documented in wp-includes/formatting.php */
2009-03-11 11:26:34 -04:00
return apply_filters ( 'sanitize_email' , '' , $email , 'local_invalid_chars' );
}
// DOMAIN PART
// Test for sequences of periods
$domain = preg_replace ( '/\.{2,}/' , '' , $domain );
if ( '' === $domain ) {
2013-11-30 13:36:10 -05:00
/** This filter is documented in wp-includes/formatting.php */
2009-03-11 11:26:34 -04:00
return apply_filters ( 'sanitize_email' , '' , $email , 'domain_period_sequence' );
}
// Test for leading and trailing periods and whitespace
$domain = trim ( $domain , " \t \n \r \0 \x0B . " );
if ( '' === $domain ) {
2013-11-30 13:36:10 -05:00
/** This filter is documented in wp-includes/formatting.php */
2009-03-11 11:26:34 -04:00
return apply_filters ( 'sanitize_email' , '' , $email , 'domain_period_limits' );
}
// Split the domain into subs
$subs = explode ( '.' , $domain );
// Assume the domain will have at least two subs
if ( 2 > count ( $subs ) ) {
2013-11-30 13:36:10 -05:00
/** This filter is documented in wp-includes/formatting.php */
2009-03-11 11:26:34 -04:00
return apply_filters ( 'sanitize_email' , '' , $email , 'domain_no_periods' );
}
// Create an array that will contain valid subs
$new_subs = array ();
// Loop through each sub
foreach ( $subs as $sub ) {
// Test for leading and trailing hyphens
$sub = trim ( $sub , " \t \n \r \0 \x0B - " );
// Test for invalid characters
2010-11-05 11:29:50 -04:00
$sub = preg_replace ( '/[^a-z0-9-]+/i' , '' , $sub );
2009-03-11 11:26:34 -04:00
// If there's anything left, add it to the valid subs
if ( '' !== $sub ) {
$new_subs [] = $sub ;
}
}
// If there aren't 2 or more valid subs
if ( 2 > count ( $new_subs ) ) {
2013-11-30 13:36:10 -05:00
/** This filter is documented in wp-includes/formatting.php */
2009-03-11 11:26:34 -04:00
return apply_filters ( 'sanitize_email' , '' , $email , 'domain_no_valid_subs' );
}
// Join valid subs into the new domain
$domain = join ( '.' , $new_subs );
// Put the email back together
$email = $local . '@' . $domain ;
// Congratulations your email made it!
2013-11-30 13:36:10 -05:00
/** This filter is documented in wp-includes/formatting.php */
2009-03-11 11:26:34 -04:00
return apply_filters ( 'sanitize_email' , $email , $email , null );
2004-12-15 21:57:05 -05:00
}
2008-08-17 07:29:43 -04:00
/**
2008-08-27 02:49:21 -04:00
* Determines the difference between two timestamps .
2008-08-17 07:29:43 -04:00
*
2008-08-30 17:28:11 -04:00
* The difference is returned in a human readable format such as " 1 hour " ,
* " 5 mins " , " 2 days " .
2008-08-17 07:29:43 -04:00
*
* @ since 1.5 . 0
*
2008-08-27 02:49:21 -04:00
* @ param int $from Unix timestamp from which the difference begins .
* @ param int $to Optional . Unix timestamp to end the time difference . Default becomes time () if not set .
* @ return string Human readable time difference .
2008-08-17 07:29:43 -04:00
*/
2006-11-19 02:56:05 -05:00
function human_time_diff ( $from , $to = '' ) {
2014-06-04 20:39:14 -04:00
if ( empty ( $to ) ) {
2004-12-18 19:10:10 -05:00
$to = time ();
2014-06-04 20:39:14 -04:00
}
2013-07-08 09:00:34 -04:00
2012-09-25 01:26:19 -04:00
$diff = ( int ) abs ( $to - $from );
2013-07-08 09:00:34 -04:00
if ( $diff < HOUR_IN_SECONDS ) {
2012-09-25 01:26:19 -04:00
$mins = round ( $diff / MINUTE_IN_SECONDS );
2013-07-08 09:00:34 -04:00
if ( $mins <= 1 )
2006-12-21 18:06:18 -05:00
$mins = 1 ;
2010-01-21 16:37:43 -05:00
/* translators: min=minute */
2012-09-25 01:26:19 -04:00
$since = sprintf ( _n ( '%s min' , '%s mins' , $mins ), $mins );
2013-07-08 09:00:34 -04:00
} elseif ( $diff < DAY_IN_SECONDS && $diff >= HOUR_IN_SECONDS ) {
2012-09-25 01:26:19 -04:00
$hours = round ( $diff / HOUR_IN_SECONDS );
2013-07-08 09:00:34 -04:00
if ( $hours <= 1 )
2007-12-06 14:49:33 -05:00
$hours = 1 ;
2012-09-25 01:26:19 -04:00
$since = sprintf ( _n ( '%s hour' , '%s hours' , $hours ), $hours );
2013-07-08 09:00:34 -04:00
} elseif ( $diff < WEEK_IN_SECONDS && $diff >= DAY_IN_SECONDS ) {
2012-09-25 01:26:19 -04:00
$days = round ( $diff / DAY_IN_SECONDS );
2013-07-08 09:00:34 -04:00
if ( $days <= 1 )
2006-12-21 18:06:18 -05:00
$days = 1 ;
2012-09-25 01:26:19 -04:00
$since = sprintf ( _n ( '%s day' , '%s days' , $days ), $days );
2013-07-08 09:00:34 -04:00
} elseif ( $diff < 30 * DAY_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 ) );
if ( $months <= 1 )
$months = 1 ;
$since = sprintf ( _n ( '%s month' , '%s months' , $months ), $months );
} elseif ( $diff >= YEAR_IN_SECONDS ) {
$years = round ( $diff / YEAR_IN_SECONDS );
if ( $years <= 1 )
$years = 1 ;
$since = sprintf ( _n ( '%s year' , '%s years' , $years ), $years );
2004-12-18 19:10:10 -05:00
}
2013-07-08 09:00:34 -04:00
2014-06-04 20:39:14 -04:00
/**
* Filter the human readable difference between two timestamps .
*
* @ since 4.0 . 0
*
* @ param string $since The difference in human readable text .
* @ param int $diff The difference in seconds .
* @ param int $from Unix timestamp from which the difference begins .
* @ param int $to Unix timestamp to end the time difference .
*/
return apply_filters ( 'human_time_diff' , $since , $diff , $from , $to );
2004-12-18 19:10:10 -05:00
}
2008-08-17 07:29:43 -04:00
/**
2008-08-30 17:28:11 -04:00
* Generates an excerpt from the content , if needed .
2008-08-17 07:29:43 -04:00
*
2008-08-30 17:28:11 -04:00
* The excerpt word amount will be 55 words and if the amount is greater than
2013-05-08 17:27:31 -04:00
* that , then the string ' […]' will be appended to the excerpt . If the string
2008-08-30 17:28:11 -04:00
* is less than 55 words , then the content will be returned as is .
2008-08-17 07:29:43 -04:00
*
2009-09-09 12:34:44 -04:00
* The 55 word limit can be modified by plugins / themes using the excerpt_length filter
2013-05-08 17:27:31 -04:00
* The ' […]' string can be modified by plugins / themes using the excerpt_more filter
2009-09-09 12:34:44 -04:00
*
2008-08-17 07:29:43 -04:00
* @ since 1.5 . 0
*
2011-09-29 17:48:03 -04:00
* @ param string $text Optional . The excerpt . If set to empty , an excerpt is generated .
2008-08-27 02:49:21 -04:00
* @ return string The excerpt .
2008-08-17 07:29:43 -04:00
*/
2011-09-29 17:48:03 -04:00
function wp_trim_excerpt ( $text = '' ) {
2009-04-17 02:59:33 -04:00
$raw_excerpt = $text ;
2005-02-14 19:21:21 -05:00
if ( '' == $text ) {
2006-09-11 19:59:00 -04:00
$text = get_the_content ( '' );
2008-08-09 01:36:14 -04:00
$text = strip_shortcodes ( $text );
2013-11-30 13:36:10 -05:00
/** This filter is documented in wp-includes/post-template.php */
$text = apply_filters ( 'the_content' , $text );
2005-03-13 20:02:04 -05:00
$text = str_replace ( ']]>' , ']]>' , $text );
2013-11-30 13:36:10 -05:00
/**
* Filter the number of words in an excerpt .
*
* @ since 2.7 . 0
*
* @ param int $number The number of words . Default 55.
*/
$excerpt_length = apply_filters ( 'excerpt_length' , 55 );
/**
* Filter the string in the " more " link displayed after a trimmed excerpt .
*
* @ since 2.9 . 0
*
* @ param string $more_string The string shown within the more link .
*/
$excerpt_more = apply_filters ( 'excerpt_more' , ' ' . '[…]' );
2011-09-20 13:14:23 -04:00
$text = wp_trim_words ( $text , $excerpt_length , $excerpt_more );
2005-03-13 20:02:04 -05:00
}
2013-11-30 13:36:10 -05:00
/**
* Filter the trimmed excerpt string .
*
* @ since 2.8 . 0
*
* @ param string $text The trimmed text .
* @ param string $raw_excerpt The text prior to trimming .
*/
return apply_filters ( 'wp_trim_excerpt' , $text , $raw_excerpt );
2005-02-14 19:21:21 -05:00
}
2011-09-20 13:14:23 -04:00
/**
* Trims text to a certain number of words .
*
2012-05-23 17:04:35 -04:00
* This function is localized . For languages that count 'words' by the individual
* character ( such as East Asian languages ), the $num_words argument will apply
* to the number of individual characters .
*
2011-09-20 13:14:23 -04:00
* @ since 3.3 . 0
*
* @ param string $text Text to trim .
* @ param int $num_words Number of words . Default 55.
2013-05-08 20:22:02 -04:00
* @ param string $more Optional . What to append if $text needs to be trimmed . Default '…' .
2011-09-20 13:14:23 -04:00
* @ return string Trimmed text .
*/
function wp_trim_words ( $text , $num_words = 55 , $more = null ) {
if ( null === $more )
$more = __ ( '…' );
$original_text = $text ;
2011-09-21 16:39:21 -04:00
$text = wp_strip_all_tags ( $text );
2012-05-27 12:25:43 -04:00
/* translators : If your word count is based on single characters ( East Asian characters ),
enter 'characters' . Otherwise , enter 'words' . Do not translate into your own language . */
2012-05-23 17:04:35 -04:00
if ( 'characters' == _x ( 'words' , 'word count: words or characters?' ) && preg_match ( '/^utf\-?8$/i' , get_option ( 'blog_charset' ) ) ) {
$text = trim ( preg_replace ( " /[ \n \r \t ]+/ " , ' ' , $text ), ' ' );
preg_match_all ( '/./u' , $text , $words_array );
$words_array = array_slice ( $words_array [ 0 ], 0 , $num_words + 1 );
$sep = '' ;
} else {
$words_array = preg_split ( " /[ \n \r \t ]+/ " , $text , $num_words + 1 , PREG_SPLIT_NO_EMPTY );
$sep = ' ' ;
}
2011-09-20 13:14:23 -04:00
if ( count ( $words_array ) > $num_words ) {
array_pop ( $words_array );
2012-05-23 17:04:35 -04:00
$text = implode ( $sep , $words_array );
2011-09-20 13:14:23 -04:00
$text = $text . $more ;
} else {
2012-05-23 17:04:35 -04:00
$text = implode ( $sep , $words_array );
2011-09-20 13:14:23 -04:00
}
2013-11-30 13:36:10 -05:00
/**
* Filter the text content after words have been trimmed .
*
* @ since 3.3 . 0
*
* @ param string $text The trimmed text .
* @ param int $num_words The number of words to trim the text to . Default 5.
* @ param string $more An optional string to append to the end of the trimmed text , e . g . & hellip ; .
* @ param string $original_text The text before it was trimmed .
*/
2011-09-20 13:14:23 -04:00
return apply_filters ( 'wp_trim_words' , $text , $num_words , $more , $original_text );
}
2008-08-17 07:29:43 -04:00
/**
2008-08-27 02:49:21 -04:00
* Converts named entities into numbered entities .
2008-08-17 07:29:43 -04:00
*
* @ since 1.5 . 1
*
2008-08-27 02:49:21 -04:00
* @ param string $text The text within which entities will be converted .
2008-08-30 17:28:11 -04:00
* @ return string Text with converted entities .
2008-08-17 07:29:43 -04:00
*/
2005-04-05 13:25:57 -04:00
function ent2ncr ( $text ) {
2011-07-21 17:41:21 -04:00
2013-11-30 13:36:10 -05:00
/**
* Filter text before named entities are converted into numbered entities .
*
* A non - null string must be returned for the filter to be evaluated .
*
* @ since 3.3 . 0
*
* @ param null $converted_text The text to be converted . Default null .
* @ param string $text The text prior to entity conversion .
*/
2011-07-25 09:20:07 -04:00
$filtered = apply_filters ( 'pre_ent2ncr' , null , $text );
if ( null !== $filtered )
2011-07-21 17:41:21 -04:00
return $filtered ;
2005-04-05 13:25:57 -04:00
$to_ncr = array (
2005-07-02 19:44:35 -04:00
'"' => '"' ,
'&' => '&' ,
'<' => '<' ,
'>' => '>' ,
'|' => '|' ,
' ' => ' ' ,
'¡' => '¡' ,
'¢' => '¢' ,
'£' => '£' ,
'¤' => '¤' ,
'¥' => '¥' ,
'¦' => '¦' ,
'&brkbar;' => '¦' ,
'§' => '§' ,
'¨' => '¨' ,
'¨' => '¨' ,
'©' => '©' ,
'ª' => 'ª' ,
'«' => '«' ,
'¬' => '¬' ,
'­' => '­' ,
'®' => '®' ,
'¯' => '¯' ,
'&hibar;' => '¯' ,
'°' => '°' ,
'±' => '±' ,
'²' => '²' ,
'³' => '³' ,
'´' => '´' ,
'µ' => 'µ' ,
'¶' => '¶' ,
'·' => '·' ,
'¸' => '¸' ,
'¹' => '¹' ,
'º' => 'º' ,
'»' => '»' ,
'¼' => '¼' ,
'½' => '½' ,
'¾' => '¾' ,
'¿' => '¿' ,
'À' => 'À' ,
'Á' => 'Á' ,
'Â' => 'Â' ,
'Ã' => 'Ã' ,
'Ä' => 'Ä' ,
'Å' => 'Å' ,
'Æ' => 'Æ' ,
'Ç' => 'Ç' ,
'È' => 'È' ,
'É' => 'É' ,
'Ê' => 'Ê' ,
'Ë' => 'Ë' ,
'Ì' => 'Ì' ,
'Í' => 'Í' ,
'Î' => 'Î' ,
'Ï' => 'Ï' ,
'Ð' => 'Ð' ,
'Ñ' => 'Ñ' ,
'Ò' => 'Ò' ,
'Ó' => 'Ó' ,
'Ô' => 'Ô' ,
'Õ' => 'Õ' ,
'Ö' => 'Ö' ,
'×' => '×' ,
'Ø' => 'Ø' ,
'Ù' => 'Ù' ,
'Ú' => 'Ú' ,
'Û' => 'Û' ,
'Ü' => 'Ü' ,
'Ý' => 'Ý' ,
'Þ' => 'Þ' ,
'ß' => 'ß' ,
'à' => 'à' ,
'á' => 'á' ,
'â' => 'â' ,
'ã' => 'ã' ,
'ä' => 'ä' ,
'å' => 'å' ,
'æ' => 'æ' ,
'ç' => 'ç' ,
'è' => 'è' ,
'é' => 'é' ,
'ê' => 'ê' ,
'ë' => 'ë' ,
'ì' => 'ì' ,
'í' => 'í' ,
'î' => 'î' ,
'ï' => 'ï' ,
'ð' => 'ð' ,
'ñ' => 'ñ' ,
'ò' => 'ò' ,
'ó' => 'ó' ,
'ô' => 'ô' ,
'õ' => 'õ' ,
'ö' => 'ö' ,
'÷' => '÷' ,
'ø' => 'ø' ,
'ù' => 'ù' ,
'ú' => 'ú' ,
'û' => 'û' ,
'ü' => 'ü' ,
'ý' => 'ý' ,
'þ' => 'þ' ,
'ÿ' => 'ÿ' ,
'Œ' => 'Œ' ,
'œ' => 'œ' ,
'Š' => 'Š' ,
'š' => 'š' ,
'Ÿ' => 'Ÿ' ,
'ƒ' => 'ƒ' ,
'ˆ' => 'ˆ' ,
'˜' => '˜' ,
'Α' => 'Α' ,
'Β' => 'Β' ,
'Γ' => 'Γ' ,
'Δ' => 'Δ' ,
'Ε' => 'Ε' ,
'Ζ' => 'Ζ' ,
'Η' => 'Η' ,
'Θ' => 'Θ' ,
'Ι' => 'Ι' ,
'Κ' => 'Κ' ,
'Λ' => 'Λ' ,
'Μ' => 'Μ' ,
'Ν' => 'Ν' ,
'Ξ' => 'Ξ' ,
'Ο' => 'Ο' ,
'Π' => 'Π' ,
'Ρ' => 'Ρ' ,
'Σ' => 'Σ' ,
'Τ' => 'Τ' ,
'Υ' => 'Υ' ,
'Φ' => 'Φ' ,
'Χ' => 'Χ' ,
'Ψ' => 'Ψ' ,
'Ω' => 'Ω' ,
'α' => 'α' ,
'β' => 'β' ,
'γ' => 'γ' ,
'δ' => 'δ' ,
'ε' => 'ε' ,
'ζ' => 'ζ' ,
'η' => 'η' ,
'θ' => 'θ' ,
'ι' => 'ι' ,
'κ' => 'κ' ,
'λ' => 'λ' ,
'μ' => 'μ' ,
'ν' => 'ν' ,
'ξ' => 'ξ' ,
'ο' => 'ο' ,
'π' => 'π' ,
'ρ' => 'ρ' ,
'ς' => 'ς' ,
'σ' => 'σ' ,
'τ' => 'τ' ,
'υ' => 'υ' ,
'φ' => 'φ' ,
'χ' => 'χ' ,
'ψ' => 'ψ' ,
'ω' => 'ω' ,
'ϑ' => 'ϑ' ,
'ϒ' => 'ϒ' ,
'ϖ' => 'ϖ' ,
' ' => ' ' ,
' ' => ' ' ,
' ' => ' ' ,
'‌' => '‌' ,
'‍' => '‍' ,
'‎' => '‎' ,
'‏' => '‏' ,
'–' => '–' ,
'—' => '—' ,
'‘' => '‘' ,
'’' => '’' ,
'‚' => '‚' ,
'“' => '“' ,
'”' => '”' ,
'„' => '„' ,
'†' => '†' ,
'‡' => '‡' ,
'•' => '•' ,
'…' => '…' ,
'‰' => '‰' ,
'′' => '′' ,
'″' => '″' ,
'‹' => '‹' ,
'›' => '›' ,
'‾' => '‾' ,
'⁄' => '⁄' ,
'€' => '€' ,
'ℑ' => 'ℑ' ,
'℘' => '℘' ,
'ℜ' => 'ℜ' ,
'™' => '™' ,
'ℵ' => 'ℵ' ,
'↵' => '↵' ,
'⇐' => '⇐' ,
'⇑' => '⇑' ,
'⇒' => '⇒' ,
'⇓' => '⇓' ,
'⇔' => '⇔' ,
'∀' => '∀' ,
'∂' => '∂' ,
'∃' => '∃' ,
'∅' => '∅' ,
'∇' => '∇' ,
'∈' => '∈' ,
'∉' => '∉' ,
'∋' => '∋' ,
'∏' => '∏' ,
'∑' => '∑' ,
'−' => '−' ,
'∗' => '∗' ,
'√' => '√' ,
'∝' => '∝' ,
'∞' => '∞' ,
'∠' => '∠' ,
'∧' => '∧' ,
'∨' => '∨' ,
'∩' => '∩' ,
'∪' => '∪' ,
'∫' => '∫' ,
'∴' => '∴' ,
'∼' => '∼' ,
'≅' => '≅' ,
'≈' => '≈' ,
'≠' => '≠' ,
'≡' => '≡' ,
'≤' => '≤' ,
'≥' => '≥' ,
'⊂' => '⊂' ,
'⊃' => '⊃' ,
'⊄' => '⊄' ,
'⊆' => '⊆' ,
'⊇' => '⊇' ,
'⊕' => '⊕' ,
'⊗' => '⊗' ,
'⊥' => '⊥' ,
'⋅' => '⋅' ,
'⌈' => '⌈' ,
'⌉' => '⌉' ,
'⌊' => '⌊' ,
'⌋' => '⌋' ,
'⟨' => '〈' ,
'⟩' => '〉' ,
'←' => '←' ,
'↑' => '↑' ,
'→' => '→' ,
'↓' => '↓' ,
'↔' => '↔' ,
'◊' => '◊' ,
'♠' => '♠' ,
'♣' => '♣' ,
'♥' => '♥' ,
'♦' => '♦'
2005-04-05 13:25:57 -04:00
);
2006-03-13 21:48:36 -05:00
return str_replace ( array_keys ( $to_ncr ), array_values ( $to_ncr ), $text );
2005-04-05 13:25:57 -04:00
}
2008-08-17 07:29:43 -04:00
/**
2008-08-30 17:28:11 -04:00
* Formats text for the rich text editor .
2008-08-17 07:29:43 -04:00
*
2008-08-30 17:28:11 -04:00
* The filter 'richedit_pre' is applied here . If $text is empty the filter will
* be applied to an empty string .
2008-08-17 07:29:43 -04:00
*
* @ since 2.0 . 0
*
2008-08-27 02:49:21 -04:00
* @ param string $text The text to be formatted .
* @ return string The formatted text after filter is applied .
2008-08-17 07:29:43 -04:00
*/
2005-11-17 12:47:29 -05:00
function wp_richedit_pre ( $text ) {
2013-11-30 13:36:10 -05:00
if ( empty ( $text ) ) {
/**
* Filter text returned for the rich text editor .
*
* This filter is first evaluated , and the value returned , if an empty string
* is passed to wp_richedit_pre () . If an empty string is passed , it results
* in a break tag and line feed .
*
* If a non - empty string is passed , the filter is evaluated on the wp_richedit_pre ()
* return after being formatted .
*
* @ since 2.0 . 0
*
* @ param string $output Text for the rich text editor .
*/
return apply_filters ( 'richedit_pre' , '' );
}
2005-11-17 12:47:29 -05:00
2008-07-08 19:38:53 -04:00
$output = convert_chars ( $text );
2005-11-17 12:47:29 -05:00
$output = wpautop ( $output );
2013-03-13 11:24:38 -04:00
$output = htmlspecialchars ( $output , ENT_NOQUOTES , get_option ( 'blog_charset' ) );
2005-11-17 12:47:29 -05:00
2013-11-30 13:36:10 -05:00
/** This filter is documented in wp-includes/formatting.php */
return apply_filters ( 'richedit_pre' , $output );
2005-11-17 12:47:29 -05:00
}
2008-08-27 02:49:21 -04:00
/**
2008-08-30 17:28:11 -04:00
* Formats text for the HTML editor .
2008-08-27 02:49:21 -04:00
*
2008-08-30 17:28:11 -04:00
* Unless $output is empty it will pass through htmlspecialchars before the
* 'htmledit_pre' filter is applied .
2008-08-27 02:49:21 -04:00
*
2008-08-30 17:28:11 -04:00
* @ since 2.5 . 0
2008-08-27 02:49:21 -04:00
*
* @ param string $output The text to be formatted .
* @ return string Formatted text after filter applied .
*/
2008-02-09 02:29:36 -05:00
function wp_htmledit_pre ( $output ) {
if ( ! empty ( $output ) )
2013-03-13 11:24:38 -04:00
$output = htmlspecialchars ( $output , ENT_NOQUOTES , get_option ( 'blog_charset' ) ); // convert only < > &
2008-02-09 02:29:36 -05:00
2013-11-30 13:36:10 -05:00
/**
* Filter the text before it is formatted for the HTML editor .
*
* @ since 2.5 . 0
*
* @ param string $output The HTML - formatted text .
*/
return apply_filters ( 'htmledit_pre' , $output );
2008-02-09 02:29:36 -05:00
}
2009-06-20 13:42:24 -04:00
/**
* Perform a deep string replace operation to ensure the values in $search are no longer present
2009-09-14 10:03:32 -04:00
*
2009-06-20 13:42:24 -04:00
* Repeats the replacement operation until it no longer replaces anything so as to remove " nested " values
* e . g . $subject = '%0%0%0DDD' , $search = '%0D' , $result = '' rather than the '%0%0DD' that
* str_replace would return
2009-09-14 10:03:32 -04:00
*
2009-06-20 13:42:24 -04:00
* @ since 2.8 . 1
* @ access private
2009-09-14 10:03:32 -04:00
*
2013-08-20 01:57:10 -04:00
* @ param string | array $search The value being searched for , otherwise known as the needle . An array may be used to designate multiple needles .
* @ param string $subject The string being searched and replaced on , otherwise known as the haystack .
* @ return string The string with the replaced svalues .
2009-06-20 13:42:24 -04:00
*/
2010-04-03 23:07:14 -04:00
function _deep_replace ( $search , $subject ) {
$subject = ( string ) $subject ;
2013-08-20 01:57:10 -04:00
$count = 1 ;
while ( $count ) {
$subject = str_replace ( $search , '' , $subject , $count );
2009-06-20 13:42:24 -04:00
}
2009-09-14 10:03:32 -04:00
2009-06-20 13:42:24 -04:00
return $subject ;
}
2009-05-29 16:31:52 -04:00
/**
2013-07-16 13:44:42 -04:00
* Escapes data for use in a MySQL query .
2009-05-29 16:31:52 -04:00
*
2013-07-16 13:44:42 -04:00
* Usually you should prepare queries using wpdb :: prepare () .
* Sometimes , spot - escaping is required or useful . One example
* is preparing an array for use in an IN clause .
2009-05-29 16:31:52 -04:00
*
* @ since 2.8 . 0
2013-08-05 18:11:30 -04:00
* @ param string | array $data Unescaped data
* @ return string | array Escaped data
2009-05-29 16:31:52 -04:00
*/
2013-07-16 13:44:42 -04:00
function esc_sql ( $data ) {
2009-05-29 16:31:52 -04:00
global $wpdb ;
2013-07-16 13:44:42 -04:00
return $wpdb -> _escape ( $data );
2009-05-29 16:31:52 -04:00
}
2008-08-17 07:29:43 -04:00
/**
2009-05-18 12:00:33 -04:00
* Checks and cleans a URL .
*
* A number of characters are removed from the URL . If the URL is for displaying
2011-09-03 12:02:41 -04:00
* ( the default behaviour ) ampersands are also replaced . The 'clean_url' filter
2009-05-18 12:00:33 -04:00
* is applied to the returned cleaned URL .
*
* @ since 2.8 . 0
*
* @ param string $url The URL to be cleaned .
* @ param array $protocols Optional . An array of acceptable protocols .
2011-09-24 15:52:26 -04:00
* Defaults to 'http' , 'https' , 'ftp' , 'ftps' , 'mailto' , 'news' , 'irc' , 'gopher' , 'nntp' , 'feed' , 'telnet' , 'mms' , 'rtsp' , 'svn' if not set .
2010-02-22 13:25:51 -05:00
* @ param string $_context Private . Use esc_url_raw () for database usage .
2010-02-13 05:58:01 -05:00
* @ return string The cleaned $url after the 'clean_url' filter is applied .
2009-05-18 12:00:33 -04:00
*/
2010-02-22 13:25:51 -05:00
function esc_url ( $url , $protocols = null , $_context = 'display' ) {
$original_url = $url ;
2010-04-25 04:16:10 -04:00
if ( '' == $url )
return $url ;
2010-02-22 13:25:51 -05:00
$url = preg_replace ( '|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\\x80-\\xff]|i' , '' , $url );
$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
2011-07-26 15:44:18 -04:00
* link starting with / , # or ? or a php file).
2010-02-22 13:25:51 -05:00
*/
2011-07-26 15:44:18 -04:00
if ( strpos ( $url , ':' ) === false && ! in_array ( $url [ 0 ], array ( '/' , '#' , '?' ) ) &&
! preg_match ( '/^[a-z0-9-]+?\.php/i' , $url ) )
2010-02-22 13:25:51 -05:00
$url = 'http://' . $url ;
// Replace ampersands and single quotes only when displaying.
if ( 'display' == $_context ) {
2010-12-29 15:45:37 -05:00
$url = wp_kses_normalize_entities ( $url );
$url = str_replace ( '&' , '&' , $url );
2010-02-22 13:25:51 -05:00
$url = str_replace ( " ' " , ''' , $url );
}
2013-07-10 09:45:22 -04:00
if ( '/' === $url [ 0 ] ) {
$good_protocol_url = $url ;
} else {
if ( ! is_array ( $protocols ) )
$protocols = wp_allowed_protocols ();
$good_protocol_url = wp_kses_bad_protocol ( $url , $protocols );
if ( strtolower ( $good_protocol_url ) != strtolower ( $url ) )
return '' ;
}
2010-02-22 13:25:51 -05:00
2013-11-30 13:36:10 -05:00
/**
* Filter a string cleaned and escaped for output as a URL .
*
* @ since 2.3 . 0
*
* @ param string $good_protocol_url The cleaned URL to be returned .
* @ param string $original_url The URL prior to cleaning .
* @ param string $_context If 'display' , replace ampersands and single quotes only .
*/
return apply_filters ( 'clean_url' , $good_protocol_url , $original_url , $_context );
2009-05-18 12:00:33 -04:00
}
/**
* Performs esc_url () for database usage .
*
* @ since 2.8 . 0
2008-08-17 07:29:43 -04:00
*
2009-05-18 12:00:33 -04:00
* @ param string $url The URL to be cleaned .
* @ param array $protocols An array of acceptable protocols .
* @ return string The cleaned URL .
*/
function esc_url_raw ( $url , $protocols = null ) {
2010-02-22 13:25:51 -05:00
return esc_url ( $url , $protocols , 'db' );
2009-05-18 12:00:33 -04:00
}
2008-08-17 07:29:43 -04:00
/**
2008-08-27 02:49:21 -04:00
* Convert entities , while preserving already - encoded entities .
2008-08-17 07:29:43 -04:00
*
* @ link http :// www . php . net / htmlentities Borrowed from the PHP Manual user notes .
*
* @ since 1.2 . 2
*
2008-08-27 02:49:21 -04:00
* @ param string $myHTML The text to be converted .
* @ return string Converted text .
2008-08-17 07:29:43 -04:00
*/
2006-04-18 23:03:27 -04:00
function htmlentities2 ( $myHTML ) {
2008-08-17 07:29:43 -04:00
$translation_table = get_html_translation_table ( HTML_ENTITIES , ENT_QUOTES );
2006-04-18 23:03:27 -04:00
$translation_table [ chr ( 38 )] = '&' ;
2008-08-17 07:29:43 -04:00
return preg_replace ( " /&(?![A-Za-z] { 0,4} \ w { 2,3};|#[0-9] { 2,3};)/ " , " & " , strtr ( $myHTML , $translation_table ) );
2006-04-18 23:03:27 -04:00
}
2008-08-17 07:29:43 -04:00
/**
2009-09-15 06:11:59 -04:00
* Escape single quotes , htmlspecialchar " < > &, and fix line endings.
2008-08-17 07:29:43 -04:00
*
2010-02-12 21:54:54 -05:00
* Escapes text strings for echoing in JS . It is intended to be used for inline JS
* ( in a tag attribute , for example onclick = " ... " ) . Note that the strings have to
* be in single quotes . The filter 'js_escape' is also applied here .
2008-08-17 07:29:43 -04:00
*
2009-05-09 03:27:22 -04:00
* @ since 2.8 . 0
2008-08-17 07:29:43 -04:00
*
2008-08-27 02:49:21 -04:00
* @ param string $text The text to be escaped .
* @ return string Escaped text .
2008-08-17 07:29:43 -04:00
*/
2009-05-09 03:27:22 -04:00
function esc_js ( $text ) {
2009-01-04 18:37:47 -05:00
$safe_text = wp_check_invalid_utf8 ( $text );
2009-05-18 11:11:07 -04:00
$safe_text = _wp_specialchars ( $safe_text , ENT_COMPAT );
2009-01-04 18:37:47 -05:00
$safe_text = preg_replace ( '/&#(x)?0*(?(1)27|39);?/i' , " ' " , stripslashes ( $safe_text ) );
2009-09-15 06:11:59 -04:00
$safe_text = str_replace ( " \r " , '' , $safe_text );
$safe_text = str_replace ( " \n " , '\\n' , addslashes ( $safe_text ) );
2013-11-30 13:36:10 -05:00
/**
* Filter a string cleaned and escaped for output in JavaScript .
*
* Text passed to esc_js () is stripped of invalid or special characters ,
* and properly slashed for output .
*
2013-11-30 14:05:10 -05:00
* @ since 2.0 . 6
2013-11-30 13:36:10 -05:00
*
* @ param string $safe_text The text after it has been escaped .
* @ param string $text The text prior to being escaped .
*/
2009-01-04 18:37:47 -05:00
return apply_filters ( 'js_escape' , $safe_text , $text );
2006-05-05 03:49:05 -04:00
}
2006-06-23 21:28:08 -04:00
2009-05-18 11:11:07 -04:00
/**
* Escaping for HTML blocks .
*
* @ since 2.8 . 0
*
* @ param string $text
* @ return string
*/
function esc_html ( $text ) {
$safe_text = wp_check_invalid_utf8 ( $text );
$safe_text = _wp_specialchars ( $safe_text , ENT_QUOTES );
2013-11-30 13:36:10 -05:00
/**
* Filter a string cleaned and escaped for output in HTML .
*
* Text passed to esc_html () is stripped of invalid or special characters
* before output .
*
* @ since 2.8 . 0
*
* @ param string $safe_text The text after it has been escaped .
* @ param string $text The text prior to being escaped .
*/
2009-05-18 11:11:07 -04:00
return apply_filters ( 'esc_html' , $safe_text , $text );
}
2008-08-27 02:49:21 -04:00
/**
* Escaping for HTML attributes .
*
2009-04-27 17:58:04 -04:00
* @ since 2.8 . 0
2008-08-27 02:49:21 -04:00
*
* @ param string $text
* @ return string
*/
2009-05-05 15:43:53 -04:00
function esc_attr ( $text ) {
2009-01-04 17:25:50 -05:00
$safe_text = wp_check_invalid_utf8 ( $text );
2009-05-18 11:11:07 -04:00
$safe_text = _wp_specialchars ( $safe_text , ENT_QUOTES );
2013-11-30 13:36:10 -05:00
/**
* Filter a string cleaned and escaped for output in an HTML attribute .
*
* Text passed to esc_attr () is stripped of invalid or special characters
* before output .
*
2013-11-30 14:05:10 -05:00
* @ since 2.0 . 6
2013-11-30 13:36:10 -05:00
*
* @ param string $safe_text The text after it has been escaped .
* @ param string $text The text prior to being escaped .
*/
2009-01-04 17:25:50 -05:00
return apply_filters ( 'attribute_escape' , $safe_text , $text );
2006-12-21 05:10:04 -05:00
}
2008-03-24 01:15:28 -04:00
2010-11-17 12:12:01 -05:00
/**
* Escaping for textarea values .
*
2013-02-01 13:07:08 -05:00
* @ since 3.1 . 0
2010-11-17 12:12:01 -05:00
*
* @ param string $text
* @ return string
*/
function esc_textarea ( $text ) {
2013-03-13 11:24:38 -04:00
$safe_text = htmlspecialchars ( $text , ENT_QUOTES , get_option ( 'blog_charset' ) );
2013-11-30 13:36:10 -05:00
/**
* Filter a string cleaned and escaped for output in a textarea element .
*
* @ since 3.1 . 0
*
* @ param string $safe_text The text after it has been escaped .
* @ param string $text The text prior to being escaped .
*/
2010-11-17 12:12:01 -05:00
return apply_filters ( 'esc_textarea' , $safe_text , $text );
}
2008-08-27 02:49:21 -04:00
/**
2013-02-01 13:07:08 -05:00
* Escape an HTML tag name .
2008-08-27 02:49:21 -04:00
*
2008-08-30 17:28:11 -04:00
* @ since 2.5 . 0
2008-08-27 02:49:21 -04:00
*
* @ param string $tag_name
* @ return string
*/
2008-03-24 01:15:28 -04:00
function tag_escape ( $tag_name ) {
2011-10-12 16:34:14 -04:00
$safe_tag = strtolower ( preg_replace ( '/[^a-zA-Z0-9_:]/' , '' , $tag_name ) );
2013-11-30 13:36:10 -05:00
/**
* Filter a string cleaned and escaped for output as an HTML tag .
*
* @ since 2.8 . 0
2013-12-04 15:03:09 -05:00
*
2013-11-30 13:36:10 -05:00
* @ param string $safe_tag The tag name after it has been escaped .
* @ param string $tag_name The text before it was escaped .
*/
return apply_filters ( 'tag_escape' , $safe_tag , $tag_name );
2008-03-24 01:15:28 -04:00
}
2008-08-27 02:49:21 -04:00
/**
2008-08-30 17:28:11 -04:00
* Convert full URL paths to absolute paths .
2008-08-27 02:49:21 -04:00
*
2008-08-30 17:28:11 -04:00
* Removes the http or https protocols and the domain . Keeps the path '/' at the
* beginning , so it isn ' t a true relative link , but from the web root base .
2008-08-27 02:49:21 -04:00
*
2008-08-30 17:28:11 -04:00
* @ since 2.1 . 0
2014-11-20 22:44:23 -05:00
* @ since 4.1 . 0 Support was added for relative URLs .
2008-08-30 17:28:11 -04:00
*
* @ param string $link Full URL path .
* @ return string Absolute path .
2008-08-27 02:49:21 -04:00
*/
2006-10-06 18:43:21 -04:00
function wp_make_link_relative ( $link ) {
2014-11-18 20:53:24 -05:00
return preg_replace ( '|^(https?:)?//[^/]+(/.*)|i' , '$2' , $link );
2006-10-05 20:34:58 -04:00
}
2006-10-06 18:43:21 -04:00
2008-08-27 02:49:21 -04:00
/**
* Sanitises various option values based on the nature of the option .
*
2008-08-30 17:28:11 -04:00
* This is basically a switch statement which will pass $value through a number
2008-12-09 13:03:31 -05:00
* of functions depending on the $option .
2008-08-27 02:49:21 -04:00
*
* @ since 2.0 . 5
*
* @ param string $option The name of the option .
* @ param string $value The unsanitised value .
* @ return string Sanitized value .
*/
2008-08-30 17:28:11 -04:00
function sanitize_option ( $option , $value ) {
2015-01-06 23:15:23 -05:00
global $wpdb ;
2007-05-24 22:22:30 -04:00
2010-04-25 04:16:10 -04:00
switch ( $option ) {
2012-02-16 10:42:02 -05:00
case 'admin_email' :
case 'new_admin_email' :
2015-01-06 23:15:23 -05:00
$value = $wpdb -> strip_invalid_text_for_column ( $wpdb -> options , 'option_value' , $value );
2012-02-16 10:42:02 -05:00
$value = sanitize_email ( $value );
if ( ! is_email ( $value ) ) {
2010-04-25 04:16:10 -04:00
$value = get_option ( $option ); // Resets option to stored value in the case of failed sanitization
2012-02-16 10:42:02 -05:00
if ( function_exists ( 'add_settings_error' ) )
add_settings_error ( $option , 'invalid_admin_email' , __ ( 'The email address entered did not appear to be a valid email address. Please enter a valid email address.' ) );
2011-06-27 11:56:42 -04:00
}
break ;
2011-09-21 15:05:06 -04:00
2008-11-13 02:54:27 -05:00
case 'thumbnail_size_w' :
case 'thumbnail_size_h' :
case 'medium_size_w' :
case 'medium_size_h' :
case 'large_size_w' :
case 'large_size_h' :
2007-05-24 22:22:30 -04:00
case 'mailserver_port' :
case 'comment_max_links' :
2007-08-22 13:57:36 -04:00
case 'page_on_front' :
2010-06-11 13:04:06 -04:00
case 'page_for_posts' :
2007-08-22 13:57:36 -04:00
case 'rss_excerpt_length' :
case 'default_category' :
case 'default_email_category' :
case 'default_link_category' :
2008-09-23 17:11:27 -04:00
case 'close_comments_days_old' :
case 'comments_per_page' :
case 'thread_comments_depth' :
2009-08-04 17:28:42 -04:00
case 'users_can_register' :
2010-02-13 01:08:15 -05:00
case 'start_of_week' :
2009-08-04 17:28:42 -04:00
$value = absint ( $value );
2007-05-24 22:22:30 -04:00
break ;
case 'posts_per_page' :
case 'posts_per_rss' :
$value = ( int ) $value ;
2010-04-25 04:16:10 -04:00
if ( empty ( $value ) )
$value = 1 ;
if ( $value < - 1 )
$value = abs ( $value );
2007-05-24 22:22:30 -04:00
break ;
case 'default_ping_status' :
case 'default_comment_status' :
// Options that if not there have 0 value but need to be something like "closed"
if ( $value == '0' || $value == '' )
$value = 'closed' ;
break ;
case 'blogdescription' :
case 'blogname' :
2015-01-06 23:15:23 -05:00
$value = $wpdb -> strip_invalid_text_for_column ( $wpdb -> options , 'option_value' , $value );
2012-09-14 15:32:53 -04:00
$value = wp_kses_post ( $value );
2009-05-18 11:11:07 -04:00
$value = esc_html ( $value );
2007-05-24 22:22:30 -04:00
break ;
case 'blog_charset' :
$value = preg_replace ( '/[^a-zA-Z0-9_-]/' , '' , $value ); // strips slashes
break ;
2012-09-14 16:26:20 -04:00
case 'blog_public' :
// This is the value if the settings checkbox is not checked on POST. Don't rely on this.
if ( null === $value )
$value = 1 ;
else
$value = intval ( $value );
break ;
2007-05-24 22:22:30 -04:00
case 'date_format' :
case 'time_format' :
case 'mailserver_url' :
case 'mailserver_login' :
case 'mailserver_pass' :
case 'upload_path' :
2015-01-06 23:15:23 -05:00
$value = $wpdb -> strip_invalid_text_for_column ( $wpdb -> options , 'option_value' , $value );
2012-10-17 13:44:40 -04:00
$value = strip_tags ( $value );
$value = wp_kses_data ( $value );
break ;
case 'ping_sites' :
$value = explode ( " \n " , $value );
$value = array_filter ( array_map ( 'trim' , $value ) );
$value = array_filter ( array_map ( 'esc_url_raw' , $value ) );
$value = implode ( " \n " , $value );
2007-05-24 22:22:30 -04:00
break ;
case 'gmt_offset' :
$value = preg_replace ( '/[^0-9:.-]/' , '' , $value ); // strips slashes
break ;
case 'siteurl' :
2015-01-06 23:15:23 -05:00
$value = $wpdb -> strip_invalid_text_for_column ( $wpdb -> options , 'option_value' , $value );
2010-04-25 04:16:10 -04:00
if ( ( bool ) preg_match ( '#http(s?)://(.+)#i' , $value ) ) {
$value = esc_url_raw ( $value );
} else {
$value = get_option ( $option ); // Resets option to stored value in the case of failed sanitization
if ( function_exists ( 'add_settings_error' ) )
add_settings_error ( 'siteurl' , 'invalid_siteurl' , __ ( 'The WordPress address you entered did not appear to be a valid URL. Please enter a valid URL.' ));
}
break ;
2007-05-24 22:22:30 -04:00
case 'home' :
2015-01-06 23:15:23 -05:00
$value = $wpdb -> strip_invalid_text_for_column ( $wpdb -> options , 'option_value' , $value );
2010-04-25 04:16:10 -04:00
if ( ( bool ) preg_match ( '#http(s?)://(.+)#i' , $value ) ) {
$value = esc_url_raw ( $value );
} else {
$value = get_option ( $option ); // Resets option to stored value in the case of failed sanitization
if ( function_exists ( 'add_settings_error' ) )
add_settings_error ( 'home' , 'invalid_home' , __ ( 'The Site address you entered did not appear to be a valid URL. Please enter a valid URL.' ));
}
2007-05-24 22:22:30 -04:00
break ;
2011-09-21 15:05:06 -04:00
2011-06-27 11:56:42 -04:00
case 'WPLANG' :
$allowed = get_available_languages ();
2014-09-03 04:03:16 -04:00
if ( ! is_multisite () && defined ( 'WPLANG' ) && '' !== WPLANG && 'en_US' !== WPLANG ) {
$allowed [] = WPLANG ;
}
if ( ! in_array ( $value , $allowed ) && ! empty ( $value ) ) {
2011-06-27 11:56:42 -04:00
$value = get_option ( $option );
2014-09-03 04:03:16 -04:00
}
2011-06-27 11:56:42 -04:00
break ;
2010-04-25 04:16:10 -04:00
2012-09-24 21:54:12 -04:00
case 'illegal_names' :
2015-01-06 23:15:23 -05:00
$value = $wpdb -> strip_invalid_text_for_column ( $wpdb -> options , 'option_value' , $value );
2012-09-24 21:54:12 -04:00
if ( ! is_array ( $value ) )
2013-06-19 18:06:42 -04:00
$value = explode ( ' ' , $value );
2012-09-24 21:54:12 -04:00
$value = array_values ( array_filter ( array_map ( 'trim' , $value ) ) );
if ( ! $value )
$value = '' ;
break ;
case 'limited_email_domains' :
case 'banned_email_domains' :
2015-01-06 23:15:23 -05:00
$value = $wpdb -> strip_invalid_text_for_column ( $wpdb -> options , 'option_value' , $value );
2012-09-24 21:54:12 -04:00
if ( ! is_array ( $value ) )
$value = explode ( " \n " , $value );
$domains = array_values ( array_filter ( array_map ( 'trim' , $value ) ) );
$value = array ();
foreach ( $domains as $domain ) {
if ( ! preg_match ( '/(--|\.\.)/' , $domain ) && preg_match ( '|^([a-zA-Z0-9-\.])+$|' , $domain ) )
$value [] = $domain ;
}
if ( ! $value )
$value = '' ;
break ;
2011-06-20 10:58:50 -04:00
case 'timezone_string' :
$allowed_zones = timezone_identifiers_list ();
if ( ! in_array ( $value , $allowed_zones ) && ! empty ( $value ) ) {
$value = get_option ( $option ); // Resets option to stored value in the case of failed sanitization
if ( function_exists ( 'add_settings_error' ) )
add_settings_error ( 'timezone_string' , 'invalid_timezone_string' , __ ( 'The timezone you have entered is not valid. Please select a valid timezone.' ) );
}
break ;
2011-09-21 15:05:06 -04:00
case 'permalink_structure' :
case 'category_base' :
case 'tag_base' :
2015-01-06 23:15:23 -05:00
$value = $wpdb -> strip_invalid_text_for_column ( $wpdb -> options , 'option_value' , $value );
2011-09-21 15:05:06 -04:00
$value = esc_url_raw ( $value );
$value = str_replace ( 'http://' , '' , $value );
2007-05-24 22:22:30 -04:00
break ;
2013-10-06 06:56:09 -04:00
case 'default_role' :
if ( ! get_role ( $value ) && get_role ( 'subscriber' ) )
$value = 'subscriber' ;
break ;
2014-05-16 07:10:14 -04:00
case 'moderation_keys' :
case 'blacklist_keys' :
2015-01-06 23:15:23 -05:00
$value = $wpdb -> strip_invalid_text_for_column ( $wpdb -> options , 'option_value' , $value );
2014-05-16 07:10:14 -04:00
$value = explode ( " \n " , $value );
$value = array_filter ( array_map ( 'trim' , $value ) );
$value = array_unique ( $value );
$value = implode ( " \n " , $value );
break ;
2007-05-24 22:22:30 -04:00
}
2013-11-30 13:36:10 -05:00
/**
* Filter an option value following sanitization .
*
* @ since 2.3 . 0
*
* @ param string $value The sanitized option value .
* @ param string $option The option name .
*/
$value = apply_filters ( " sanitize_option_ { $option } " , $value , $option );
2011-09-21 15:05:06 -04:00
2007-05-24 22:22:30 -04:00
return $value ;
}
2008-08-17 07:29:43 -04:00
/**
2008-08-27 02:49:21 -04:00
* Parses a string into variables to be stored in an array .
2008-08-17 07:29:43 -04:00
*
2008-08-30 17:28:11 -04:00
* Uses { @ link http :// www . php . net / parse_str parse_str ()} and stripslashes if
* { @ link http :// www . php . net / magic_quotes magic_quotes_gpc } is on .
2008-08-17 07:29:43 -04:00
*
* @ since 2.2 . 1
*
2008-08-27 02:49:21 -04:00
* @ param string $string The string to be parsed .
* @ param array $array Variables will be stored in this array .
2008-08-17 07:29:43 -04:00
*/
2007-06-14 18:46:59 -04:00
function wp_parse_str ( $string , & $array ) {
parse_str ( $string , $array );
if ( get_magic_quotes_gpc () )
2008-08-27 02:49:21 -04:00
$array = stripslashes_deep ( $array );
2013-11-30 13:36:10 -05:00
/**
* Filter the array of variables derived from a parsed string .
*
* @ since 2.3 . 0
*
* @ param array $array The array populated with variables .
*/
2007-06-14 18:46:59 -04:00
$array = apply_filters ( 'wp_parse_str' , $array );
}
2008-08-27 02:49:21 -04:00
/**
* Convert lone less than signs .
*
2008-08-30 17:28:11 -04:00
* KSES already converts lone greater than signs .
2008-08-27 02:49:21 -04:00
*
2008-08-30 17:28:11 -04:00
* @ since 2.3 . 0
2008-08-27 02:49:21 -04:00
*
* @ param string $text Text to be converted .
* @ return string Converted text .
*/
2007-07-06 08:53:15 -04:00
function wp_pre_kses_less_than ( $text ) {
return preg_replace_callback ( '%<[^>]*?((?=<)|>|$)%' , 'wp_pre_kses_less_than_callback' , $text );
}
2008-08-27 02:49:21 -04:00
/**
* Callback function used by preg_replace .
*
2008-08-30 17:28:11 -04:00
* @ since 2.3 . 0
2008-08-27 02:49:21 -04:00
*
* @ param array $matches Populated by matches to preg_replace .
2009-05-18 11:11:07 -04:00
* @ return string The text returned after esc_html if needed .
2008-08-27 02:49:21 -04:00
*/
2007-07-06 08:53:15 -04:00
function wp_pre_kses_less_than_callback ( $matches ) {
if ( false === strpos ( $matches [ 0 ], '>' ) )
2009-05-18 11:11:07 -04:00
return esc_html ( $matches [ 0 ]);
2007-07-06 08:53:15 -04:00
return $matches [ 0 ];
}
2008-02-22 00:53:47 -05:00
/**
2008-08-27 02:49:21 -04:00
* WordPress implementation of PHP sprintf () with filters .
*
2008-08-30 17:28:11 -04:00
* @ since 2.5 . 0
2008-08-27 02:49:21 -04:00
* @ link http :// www . php . net / sprintf
*
* @ param string $pattern The string which formatted args are inserted .
2015-01-10 01:57:22 -05:00
* @ param mixed $args , ... Arguments to be formatted into the $pattern string .
2008-08-27 02:49:21 -04:00
* @ return string The formatted string .
2008-02-22 00:53:47 -05:00
*/
function wp_sprintf ( $pattern ) {
2013-01-04 05:13:51 -05:00
$args = func_get_args ();
2008-02-22 00:53:47 -05:00
$len = strlen ( $pattern );
$start = 0 ;
$result = '' ;
$arg_index = 0 ;
while ( $len > $start ) {
// Last character: append and break
if ( strlen ( $pattern ) - 1 == $start ) {
$result .= substr ( $pattern , - 1 );
break ;
}
// Literal %: append and continue
if ( substr ( $pattern , $start , 2 ) == '%%' ) {
$start += 2 ;
$result .= '%' ;
continue ;
}
// Get fragment before next %
$end = strpos ( $pattern , '%' , $start + 1 );
if ( false === $end )
$end = $len ;
$fragment = substr ( $pattern , $start , $end - $start );
// Fragment has a specifier
2010-11-13 04:53:55 -05:00
if ( $pattern [ $start ] == '%' ) {
2008-02-22 00:53:47 -05:00
// Find numbered arguments or take the next one in order
if ( preg_match ( '/^%(\d+)\$/' , $fragment , $matches ) ) {
$arg = isset ( $args [ $matches [ 1 ]]) ? $args [ $matches [ 1 ]] : '' ;
$fragment = str_replace ( " % { $matches [ 1 ] } $ " , '%' , $fragment );
} else {
++ $arg_index ;
$arg = isset ( $args [ $arg_index ]) ? $args [ $arg_index ] : '' ;
}
2013-11-30 13:36:10 -05:00
/**
* Filter a fragment from the pattern passed to wp_sprintf () .
*
* If the fragment is unchanged , then sprintf () will be run on the fragment .
*
* @ since 2.5 . 0
*
* @ param string $fragment A fragment from the pattern .
* @ param string $arg The argument .
*/
2008-02-22 00:53:47 -05:00
$_fragment = apply_filters ( 'wp_sprintf' , $fragment , $arg );
if ( $_fragment != $fragment )
$fragment = $_fragment ;
else
$fragment = sprintf ( $fragment , strval ( $arg ) );
}
// Append to result and move to next fragment
$result .= $fragment ;
$start = $end ;
}
return $result ;
}
/**
2008-08-30 17:28:11 -04:00
* Localize list items before the rest of the content .
2008-08-27 02:49:21 -04:00
*
2008-08-30 17:28:11 -04:00
* The '%l' must be at the first characters can then contain the rest of the
* content . The list items will have ', ' , ', and' , and ' and ' added depending
* on the amount of list items in the $args parameter .
2008-02-22 00:53:47 -05:00
*
2008-08-30 17:28:11 -04:00
* @ since 2.5 . 0
*
* @ param string $pattern Content containing '%l' at the beginning .
* @ param array $args List items to prepend to the content and replace '%l' .
* @ return string Localized list items and rest of the content .
2008-02-22 00:53:47 -05:00
*/
function wp_sprintf_l ( $pattern , $args ) {
// Not a match
if ( substr ( $pattern , 0 , 2 ) != '%l' )
return $pattern ;
// Nothing to work with
if ( empty ( $args ) )
return '' ;
2013-11-30 13:36:10 -05:00
/**
* Filter the translated delimiters used by wp_sprintf_l () .
2014-02-26 11:50:15 -05:00
* Placeholders ( % s ) are included to assist translators and then
* removed before the array of strings reaches the filter .
2013-11-30 13:36:10 -05:00
*
* Please note : Ampersands and entities should be avoided here .
*
* @ since 2.5 . 0
*
* @ param array $delimiters An array of translated delimiters .
*/
$l = apply_filters ( 'wp_sprintf_l' , array (
2014-02-26 11:50:15 -05:00
/* translators: used to join items in a list with more than 2 items */
'between' => sprintf ( __ ( '%s, %s' ), '' , '' ),
/* translators: used to join last two items in a list with more than 2 times */
'between_last_two' => sprintf ( __ ( '%s, and %s' ), '' , '' ),
/* translators: used to join items in a list with only 2 items */
'between_only_two' => sprintf ( __ ( '%s and %s' ), '' , '' ),
2013-11-30 13:36:10 -05:00
) );
2008-02-22 00:53:47 -05:00
$args = ( array ) $args ;
$result = array_shift ( $args );
if ( count ( $args ) == 1 )
2008-03-26 02:37:19 -04:00
$result .= $l [ 'between_only_two' ] . array_shift ( $args );
2008-02-22 00:53:47 -05:00
// Loop when more than two args
2008-10-15 16:47:56 -04:00
$i = count ( $args );
while ( $i ) {
2008-02-22 00:53:47 -05:00
$arg = array_shift ( $args );
2008-10-15 16:47:56 -04:00
$i -- ;
2009-05-19 11:36:01 -04:00
if ( 0 == $i )
2008-02-22 00:53:47 -05:00
$result .= $l [ 'between_last_two' ] . $arg ;
else
$result .= $l [ 'between' ] . $arg ;
}
return $result . substr ( $pattern , 2 );
}
2008-03-03 16:05:23 -05:00
/**
2008-08-27 02:49:21 -04:00
* Safely extracts not more than the first $count characters from html string .
2008-03-03 16:05:23 -05:00
*
2008-08-27 02:49:21 -04:00
* UTF - 8 , tags and entities safe prefix extraction . Entities inside will * NOT *
* be counted as one character . For example & amp ; will be counted as 4 , & lt ; as
* 3 , etc .
2008-03-03 16:05:23 -05:00
*
2008-08-30 17:28:11 -04:00
* @ since 2.5 . 0
*
2013-06-21 08:45:11 -04:00
* @ param string $str String to get the excerpt from .
2008-08-27 02:49:21 -04:00
* @ param integer $count Maximum number of characters to take .
2013-05-08 20:22:02 -04:00
* @ param string $more Optional . What to append if $str needs to be trimmed . Defaults to empty string .
2008-08-27 02:49:21 -04:00
* @ return string The excerpt .
2008-03-03 16:05:23 -05:00
*/
2013-05-08 20:22:02 -04:00
function wp_html_excerpt ( $str , $count , $more = null ) {
if ( null === $more )
$more = '' ;
2009-09-14 09:57:48 -04:00
$str = wp_strip_all_tags ( $str , true );
2013-05-08 20:22:02 -04:00
$excerpt = mb_substr ( $str , 0 , $count );
2008-03-03 16:05:23 -05:00
// remove part of an entity at the end
2013-05-08 20:22:02 -04:00
$excerpt = preg_replace ( '/&[^;\s]{0,6}$/' , '' , $excerpt );
if ( $str != $excerpt )
$excerpt = trim ( $excerpt ) . $more ;
return $excerpt ;
2008-03-03 16:05:23 -05:00
}
2008-08-04 17:01:09 -04:00
/**
* Add a Base url to relative links in passed content .
*
2008-08-30 17:28:11 -04:00
* By default it supports the 'src' and 'href' attributes . However this can be
* changed via the 3 rd param .
2008-08-04 17:01:09 -04:00
*
2008-08-30 17:28:11 -04:00
* @ since 2.7 . 0
2008-08-04 17:01:09 -04:00
*
2008-08-27 02:49:21 -04:00
* @ param string $content String to search for links in .
* @ param string $base The base URL to prefix to links .
2008-08-04 17:01:09 -04:00
* @ param array $attrs The attributes which should be processed .
2008-08-27 02:49:21 -04:00
* @ return string The processed content .
2008-08-04 17:01:09 -04:00
*/
function links_add_base_url ( $content , $base , $attrs = array ( 'src' , 'href' ) ) {
2011-02-16 14:24:18 -05:00
global $_links_add_base ;
$_links_add_base = $base ;
2008-08-04 17:01:09 -04:00
$attrs = implode ( '|' , ( array ) $attrs );
2011-02-16 14:24:18 -05:00
return preg_replace_callback ( " !( $attrs )=([' \" ])(.+?) \\ 2!i " , '_links_add_base' , $content );
2008-08-04 17:01:09 -04:00
}
/**
* Callback to add a base url to relative links in passed content .
*
2008-08-30 17:28:11 -04:00
* @ since 2.7 . 0
* @ access private
2008-08-04 17:01:09 -04:00
*
2008-08-27 02:49:21 -04:00
* @ param string $m The matched link .
* @ return string The processed link .
2008-08-04 17:01:09 -04:00
*/
2011-02-16 14:24:18 -05:00
function _links_add_base ( $m ) {
global $_links_add_base ;
2008-08-04 17:01:09 -04:00
//1 = attribute name 2 = quotation mark 3 = URL
2008-08-09 01:36:14 -04:00
return $m [ 1 ] . '=' . $m [ 2 ] .
2012-04-14 15:14:10 -04:00
( preg_match ( '#^(\w{1,20}):#' , $m [ 3 ], $protocol ) && in_array ( $protocol [ 1 ], wp_allowed_protocols () ) ?
$m [ 3 ] :
2014-12-06 22:19:23 -05:00
WP_HTTP :: make_absolute_url ( $m [ 3 ], $_links_add_base )
)
2008-08-04 17:01:09 -04:00
. $m [ 2 ];
}
/**
* Adds a Target attribute to all links in passed content .
*
2014-11-24 00:30:25 -05:00
* This function by default only applies to `<a>` tags , however this can be
2008-08-30 17:28:11 -04:00
* modified by the 3 rd param .
2008-08-04 17:01:09 -04:00
*
2014-11-24 00:30:25 -05:00
* * NOTE :* Any current target attributed will be stripped and replaced .
2008-08-30 17:28:11 -04:00
*
* @ since 2.7 . 0
2008-08-04 17:01:09 -04:00
*
2008-08-27 02:49:21 -04:00
* @ param string $content String to search for links in .
* @ param string $target The Target to add to the links .
2008-08-04 17:01:09 -04:00
* @ param array $tags An array of tags to apply to .
2008-08-27 02:49:21 -04:00
* @ return string The processed content .
2008-08-04 17:01:09 -04:00
*/
function links_add_target ( $content , $target = '_blank' , $tags = array ( 'a' ) ) {
2011-02-16 14:24:18 -05:00
global $_links_add_target ;
$_links_add_target = $target ;
2008-08-04 17:01:09 -04:00
$tags = implode ( '|' , ( array ) $tags );
2013-11-22 11:25:10 -05:00
return preg_replace_callback ( " !<( $tags )([^>]*)>!i " , '_links_add_target' , $content );
2008-08-04 17:01:09 -04:00
}
2009-09-14 09:57:48 -04:00
2008-08-04 17:01:09 -04:00
/**
2008-08-27 02:49:21 -04:00
* Callback to add a target attribute to all links in passed content .
2008-08-04 17:01:09 -04:00
*
2008-08-30 17:28:11 -04:00
* @ since 2.7 . 0
* @ access private
2008-08-04 17:01:09 -04:00
*
2008-08-27 02:49:21 -04:00
* @ param string $m The matched link .
* @ return string The processed link .
2008-08-04 17:01:09 -04:00
*/
2011-02-16 14:24:18 -05:00
function _links_add_target ( $m ) {
global $_links_add_target ;
2008-08-04 17:01:09 -04:00
$tag = $m [ 1 ];
2013-11-22 11:25:10 -05:00
$link = preg_replace ( '|( target=([\'"])(.*?)\2)|i' , '' , $m [ 2 ]);
2011-02-16 14:24:18 -05:00
return '<' . $tag . $link . ' target="' . esc_attr ( $_links_add_target ) . '">' ;
2008-08-04 17:01:09 -04:00
}
2013-02-01 13:07:08 -05:00
/**
* Normalize EOL characters and strip duplicate whitespace .
*
* @ since 2.7 . 0
*
* @ param string $str The string to normalize .
* @ return string The normalized string .
*/
2008-10-23 16:03:16 -04:00
function normalize_whitespace ( $str ) {
2013-02-01 13:07:08 -05:00
$str = trim ( $str );
$str = str_replace ( " \r " , " \n " , $str );
2008-10-23 16:03:16 -04:00
$str = preg_replace ( array ( '/\n+/' , '/[ \t]+/' ), array ( " \n " , ' ' ), $str );
return $str ;
}
2009-09-14 09:57:48 -04:00
/**
* Properly strip all HTML tags including script and style
2014-02-04 20:43:12 -05:00
*
* This differs from strip_tags () because it removes the contents of
2014-11-24 00:30:25 -05:00
* the `<script>` and `<style>` tags . E . g . `strip_tags( '<script>something</script>' )`
2014-01-26 22:16:11 -05:00
* will return 'something' . wp_strip_all_tags will return ''
2009-09-14 09:57:48 -04:00
*
* @ since 2.9 . 0
*
* @ param string $string String containing HTML tags
* @ param bool $remove_breaks optional Whether to remove left over line breaks and white space chars
* @ return string The processed string .
*/
function wp_strip_all_tags ( $string , $remove_breaks = false ) {
$string = preg_replace ( '@<(script|style)[^>]*?>.*?</\\1>@si' , '' , $string );
$string = strip_tags ( $string );
if ( $remove_breaks )
2009-12-23 04:10:26 -05:00
$string = preg_replace ( '/[\r\n\t ]+/' , ' ' , $string );
2009-09-14 09:57:48 -04:00
2012-05-01 17:05:02 -04:00
return trim ( $string );
2009-09-14 09:57:48 -04:00
}
/**
* Sanitize a string from user input or from the db
*
* check for invalid UTF - 8 ,
* Convert single < characters to entity ,
* strip all tags ,
2010-01-31 10:41:19 -05:00
* remove line breaks , tabs and extra white space ,
2009-09-14 09:57:48 -04:00
* strip octets .
*
2010-03-26 15:23:39 -04:00
* @ since 2.9 . 0
2009-09-14 09:57:48 -04:00
*
* @ param string $str
* @ return string
*/
function sanitize_text_field ( $str ) {
$filtered = wp_check_invalid_utf8 ( $str );
if ( strpos ( $filtered , '<' ) !== false ) {
$filtered = wp_pre_kses_less_than ( $filtered );
2009-12-23 04:52:48 -05:00
// This will strip extra whitespace for us.
2009-09-14 09:57:48 -04:00
$filtered = wp_strip_all_tags ( $filtered , true );
} else {
2009-12-23 04:52:48 -05:00
$filtered = trim ( preg_replace ( '/[\r\n\t ]+/' , ' ' , $filtered ) );
2009-09-14 09:57:48 -04:00
}
2009-12-23 06:00:29 -05:00
$found = false ;
2009-12-23 04:52:48 -05:00
while ( preg_match ( '/%[a-f0-9]{2}/i' , $filtered , $match ) ) {
2009-09-14 09:57:48 -04:00
$filtered = str_replace ( $match [ 0 ], '' , $filtered );
2009-12-23 06:00:29 -05:00
$found = true ;
}
if ( $found ) {
// Strip out the whitespace that may now exist after removing the octets.
$filtered = trim ( preg_replace ( '/ +/' , ' ' , $filtered ) );
2009-12-23 04:52:48 -05:00
}
2009-09-14 09:57:48 -04:00
2013-11-30 13:36:10 -05:00
/**
* Filter a sanitized text field string .
*
* @ since 2.9 . 0
*
* @ param string $filtered The sanitized string .
* @ param string $str The string prior to being sanitized .
*/
return apply_filters ( 'sanitize_text_field' , $filtered , $str );
2009-09-14 09:57:48 -04:00
}
2010-11-02 13:19:55 -04:00
/**
* i18n friendly version of basename ()
*
* @ since 3.1 . 0
*
* @ param string $path A path .
* @ param string $suffix If the filename ends in suffix this will also be cut off .
* @ return string
*/
function wp_basename ( $path , $suffix = '' ) {
2012-10-25 18:31:17 -04:00
return urldecode ( basename ( str_replace ( array ( '%2F' , '%5C' ), '/' , urlencode ( $path ) ), $suffix ) );
2010-11-02 13:19:55 -04:00
}
2010-05-27 12:11:27 -04:00
/**
* Forever eliminate " Wordpress " from the planet ( or at least the little bit we can influence ) .
*
* Violating our coding standards for a good function name .
*
* @ since 3.0 . 0
*/
function capital_P_dangit ( $text ) {
2010-07-08 15:35:29 -04:00
// Simple replacement for titles
2013-11-12 22:56:09 -05:00
$current_filter = current_filter ();
if ( 'the_title' === $current_filter || 'wp_title' === $current_filter )
2010-07-08 15:35:29 -04:00
return str_replace ( 'Wordpress' , 'WordPress' , $text );
// Still here? Use the more judicious replacement
static $dblq = false ;
if ( false === $dblq )
2012-07-09 01:08:43 -04:00
$dblq = _x ( '“' , 'opening curly double quote' );
2010-07-08 15:35:29 -04:00
return str_replace (
array ( ' Wordpress' , '‘Wordpress' , $dblq . 'Wordpress' , '>Wordpress' , '(Wordpress' ),
array ( ' WordPress' , '‘WordPress' , $dblq . 'WordPress' , '>WordPress' , '(WordPress' ),
$text );
2010-05-27 12:11:27 -04:00
}
2011-05-22 19:19:42 -04:00
/**
* Sanitize a mime type
*
2011-05-25 11:47:17 -04:00
* @ since 3.1 . 3
2011-05-22 19:19:42 -04:00
*
* @ param string $mime_type Mime type
* @ return string Sanitized mime type
*/
function sanitize_mime_type ( $mime_type ) {
2011-06-20 16:05:57 -04:00
$sani_mime_type = preg_replace ( '/[^-+*.a-zA-Z0-9\/]/' , '' , $mime_type );
2013-11-30 13:36:10 -05:00
/**
* Filter a mime type following sanitization .
*
* @ since 3.1 . 3
*
* @ param string $sani_mime_type The sanitized mime type .
* @ param string $mime_type The mime type prior to sanitization .
*/
2011-05-22 19:19:42 -04:00
return apply_filters ( 'sanitize_mime_type' , $sani_mime_type , $mime_type );
}
2012-01-04 14:45:13 -05:00
/**
* Sanitize space or carriage return separated URLs that are used to send trackbacks .
*
* @ since 3.4 . 0
*
* @ param string $to_ping Space or carriage return separated URLs
* @ return string URLs starting with the http or https protocol , separated by a carriage return .
*/
function sanitize_trackback_urls ( $to_ping ) {
2012-09-03 23:36:19 -04:00
$urls_to_ping = preg_split ( '/[\r\n\t ]/' , trim ( $to_ping ), - 1 , PREG_SPLIT_NO_EMPTY );
2012-01-04 14:45:13 -05:00
foreach ( $urls_to_ping as $k => $url ) {
if ( ! preg_match ( '#^https?://.#i' , $url ) )
unset ( $urls_to_ping [ $k ] );
}
$urls_to_ping = array_map ( 'esc_url_raw' , $urls_to_ping );
$urls_to_ping = implode ( " \n " , $urls_to_ping );
2013-11-30 13:36:10 -05:00
/**
* Filter a list of trackback URLs following sanitization .
*
* The string returned here consists of a space or carriage return - delimited list
* of trackback URLs .
*
* @ since 3.4 . 0
*
* @ param string $urls_to_ping Sanitized space or carriage return separated URLs .
* @ param string $to_ping Space or carriage return separated URLs before sanitization .
*/
2012-01-04 14:45:13 -05:00
return apply_filters ( 'sanitize_trackback_urls' , $urls_to_ping , $to_ping );
}
2013-03-01 11:34:48 -05:00
/**
* Add slashes to a string or array of strings .
*
* This should be used when preparing data for core API that expects slashed data .
* This should not be used to escape data going directly into an SQL query .
*
* @ since 3.6 . 0
*
* @ param string | array $value String or array of strings to slash .
* @ return string | array Slashed $value
*/
function wp_slash ( $value ) {
if ( is_array ( $value ) ) {
foreach ( $value as $k => $v ) {
if ( is_array ( $v ) ) {
$value [ $k ] = wp_slash ( $v );
} else {
$value [ $k ] = addslashes ( $v );
}
}
} else {
$value = addslashes ( $value );
}
return $value ;
}
/**
* Remove slashes from a string or array of strings .
*
* This should be used to remove slashes from data passed to core API that
* expects data to be unslashed .
*
* @ since 3.6 . 0
*
* @ param string | array $value String or array of strings to unslash .
* @ return string | array Unslashed $value
*/
function wp_unslash ( $value ) {
return stripslashes_deep ( $value );
2013-07-12 15:38:37 -04:00
}
/**
* Extract and return the first URL from passed content .
*
* @ since 3.6 . 0
*
* @ param string $content A string which might contain a URL .
* @ return string The found URL .
*/
function get_url_in_content ( $content ) {
2014-01-17 02:47:10 -05:00
if ( empty ( $content ) ) {
return false ;
}
2013-07-12 15:38:37 -04:00
2014-01-17 02:47:10 -05:00
if ( preg_match ( '/<a\s[^>]*?href=([\'"])(.+?)\1/is' , $content , $matches ) ) {
2013-07-12 15:38:37 -04:00
return esc_url_raw ( $matches [ 2 ] );
2014-01-17 02:47:10 -05:00
}
2013-07-12 15:38:37 -04:00
return false ;
}
2014-06-09 15:30:14 -04:00
/**
* Returns the regexp for common whitespace characters .
*
* By default , spaces include new lines , tabs , nbsp entities , and the UTF - 8 nbsp .
* This is designed to replace the PCRE \s sequence . In ticket #22692, that
* sequence was found to be unreliable due to random inclusion of the A0 byte .
*
* @ since 4.0 . 0
*
* @ return string The spaces regexp .
*/
function wp_spaces_regexp () {
static $spaces ;
if ( empty ( $spaces ) ) {
2014-06-09 21:55:15 -04:00
/**
2014-06-10 02:46:15 -04:00
* Filter the regexp for common whitespace characters .
2014-06-09 21:55:15 -04:00
*
2014-06-10 02:46:15 -04:00
* This string is substituted for the \s sequence as needed in regular
* expressions . For websites not written in English , different characters
* may represent whitespace . For websites not encoded in UTF - 8 , the 0xC2 0xA0
* sequence may not be in use .
2014-06-09 21:55:15 -04:00
*
* @ since 4.0 . 0
*
2014-06-10 02:46:15 -04:00
* @ param string $spaces Regexp pattern for matching common whitespace characters .
2014-06-09 21:55:15 -04:00
*/
2014-06-09 15:30:14 -04:00
$spaces = apply_filters ( 'wp_spaces_regexp' , '[\r\n\t ]|\xC2\xA0| ' );
}
return $spaces ;
2014-06-09 21:55:15 -04:00
}
2015-03-11 18:49:28 -04:00
/**
* Print the important emoji - related styles .
*
* @ since 4.2 . 0
*/
function print_emoji_styles () {
2015-03-24 19:33:32 -04:00
static $printed = false ;
if ( $printed ) {
return ;
}
$printed = true ;
2015-03-11 18:49:28 -04:00
?>
< style type = " text/css " >
img . wp - smiley ,
img . emoji {
2015-03-13 14:45:27 -04:00
display : inline ! important ;
2015-03-11 18:49:28 -04:00
border : none ! important ;
box - shadow : none ! important ;
height : 1 em ! important ;
width : 1 em ! important ;
2015-03-15 19:16:29 -04:00
margin : 0 . 07 em ! important ;
2015-03-11 18:49:28 -04:00
vertical - align : - 0.1 em ! important ;
background : none ! important ;
padding : 0 ! important ;
}
</ style >
< ? php
}
2015-03-24 19:33:32 -04:00
function print_emoji_detection_script () {
global $wp_version ;
static $printed = false ;
if ( $printed ) {
return ;
}
$printed = true ;
$settings = array (
/**
* Filter the URL where emoji images are hosted .
*
* @ since 4.2 . 0
*
* @ param string The emoji base URL .
*/
2015-03-31 00:31:29 -04:00
'baseUrl' => apply_filters ( 'emoji_url' , set_url_scheme ( '//s.w.org/images/core/emoji/72x72' ) ),
2015-03-24 19:33:32 -04:00
/**
* Filter the extension of the emoji files .
*
* @ since 4.2 . 0
*
* @ param string The emoji extension . Default . png .
*/
'ext' => apply_filters ( 'emoji_ext' , '.png' ),
);
$version = 'ver=' . $wp_version ;
if ( SCRIPT_DEBUG ) {
$settings [ 'source' ] = array (
'wpemoji' => includes_url ( " js/wp-emoji.js? $version " ),
'twemoji' => includes_url ( " js/twemoji.js? $version " ),
);
?>
< script type = " text/javascript " >
window . _wpemojiSettings = < ? php echo wp_json_encode ( $settings ); ?> ;
< ? php readfile ( ABSPATH . WPINC . " /js/wp-emoji-loader.js " ); ?>
</ script >
< ? php
} else {
$settings [ 'source' ] = array (
'concatemoji' => includes_url ( " js/wp-emoji-release.min.js? $version " ),
);
2015-03-25 00:09:26 -04:00
/*
* If you 're looking at a src version of this file, you' ll see an " include "
* statement below . This is used by the `grunt build` process to directly
* include a minified version of wp - emoji - loader . js , instead of using the
* readfile () method from above .
*
* If you 're looking at a build version of this file, you' ll see a string of
* minified JavaScript . If you need to debug it , please turn on SCRIPT_DEBUG
* and edit wp - emoji - loader . js directly .
*/
2015-03-24 19:33:32 -04:00
?>
< script type = " text/javascript " >
window . _wpemojiSettings = < ? php echo wp_json_encode ( $settings ); ?> ;
! function ( a , b , c ){ function d ( a ){ var c = b . createElement ( " canvas " ), d = c . getContext && c . getContext ( " 2d " ); return d && d . fillText ? ( d . textBaseline = " top " , d . font = " 600 32px Arial " , " flag " === a ? ( d . fillText ( String . fromCharCode ( 55356 , 56812 , 55356 , 56807 ), 0 , 0 ), c . toDataURL () . length > 3e3 ) : ( d . fillText ( String . fromCharCode ( 55357 , 56835 ), 0 , 0 ), 0 !== d . getImageData ( 16 , 16 , 1 , 1 ) . data [ 0 ])) :! 1 } function e ( a ){ var c = b . createElement ( " script " ); c . src = a , c . type = " text/javascript " , b . getElementsByTagName ( " head " )[ 0 ] . appendChild ( c )} var f ; c . supports = { simple : d ( " simple " ), flag : d ( " flag " )}, c . supports . simple && c . supports . flag || ( f = c . source || {}, f . concatemoji ? e ( f . concatemoji ) : f . wpemoji && f . twemoji && ( e ( f . twemoji ), e ( f . wpemoji )))}( window , document , window . _wpemojiSettings );
</ script >
< ? php
}
}
2015-03-11 18:49:28 -04:00
/**
* Convert any 4 byte emoji in a string to their equivalent HTML entity .
2015-03-15 21:43:28 -04:00
*
2015-03-11 18:49:28 -04:00
* Currently , only Unicode 7 emoji are supported . Unicode 8 emoji will be added
* when the spec in finalised , along with the new skin - tone modifiers .
*
* This allows us to store emoji in a DB using the utf8 character set .
*
* @ since 4.2 . 0
*
* @ param string $content The content to encode .
* @ return string The encoded content .
*/
function wp_encode_emoji ( $content ) {
if ( function_exists ( 'mb_convert_encoding' ) ) {
$regex = ' / (
\x23\xE2\x83\xA3 # Digits
[ \x30 - \x39 ] \xE2\x83\xA3
| \xF0\x9F [ \x85 - \x88 ][ \xA6 - \xBF ] # Enclosed characters
| \xF0\x9F [ \x8C - \x97 ][ \x80 - \xBF ] # Misc
| \xF0\x9F\x98 [ \x80 - \xBF ] # Smilies
| \xF0\x9F\x99 [ \x80 - \x8F ]
| \xF0\x9F\x9A [ \x80 - \xBF ] # Transport and map symbols
| \xF0\x9F\x99 [ \x80 - \x85 ]
) / x ' ;
$matches = array ();
if ( preg_match_all ( $regex , $content , $matches ) ) {
if ( ! empty ( $matches [ 1 ] ) ) {
foreach ( $matches [ 1 ] as $emoji ) {
/*
* UTF - 32 's hex encoding is the same as HTML' s hex encoding .
* So , by converting the emoji from UTF - 8 to UTF - 32 , we magically
* get the correct hex encoding .
*/
$unpacked = unpack ( 'H*' , mb_convert_encoding ( $emoji , 'UTF-32' , 'UTF-8' ) );
if ( isset ( $unpacked [ 1 ] ) ) {
2015-03-29 23:27:31 -04:00
$entity = '&#x' . ltrim ( $unpacked [ 1 ], '0' ) . ';' ;
2015-03-11 18:49:28 -04:00
$content = str_replace ( $emoji , $entity , $content );
}
}
}
}
}
return $content ;
}
/**
2015-03-15 21:43:28 -04:00
* Convert emoji to a static img element .
2015-03-11 18:49:28 -04:00
*
* @ since 4.2 . 0
*
2015-03-12 09:17:26 -04:00
* @ param string $text The content to encode .
2015-03-11 18:49:28 -04:00
* @ return string The encoded content .
*/
2015-03-12 09:17:26 -04:00
function wp_staticize_emoji ( $text ) {
$text = wp_encode_emoji ( $text );
2015-03-11 18:49:28 -04:00
if ( ! class_exists ( 'DOMDocument' ) ) {
2015-03-12 09:17:26 -04:00
return $text ;
2015-03-11 18:49:28 -04:00
}
2015-03-24 19:33:32 -04:00
/** This filter is documented in wp-includes/formatting.php */
2015-03-31 00:31:29 -04:00
$cdn_url = apply_filters ( 'emoji_url' , set_url_scheme ( '//s.w.org/images/core/emoji/72x72' ) );
2015-03-15 21:43:28 -04:00
2015-03-24 19:33:32 -04:00
/** This filter is documented in wp-includes/formatting.php */
2015-03-11 18:49:28 -04:00
$ext = apply_filters ( 'emoji_ext' , '.png' );
2015-03-12 09:17:26 -04:00
$output = '' ;
2015-03-15 21:43:28 -04:00
/*
2015-03-15 21:56:27 -04:00
* HTML loop taken from smiley function , which was taken from texturize function .
2015-03-15 21:43:28 -04:00
* It ' ll never be consolidated .
*
* First , capture the tags as well as in between .
*/
$textarr = preg_split ( '/(<.*>)/U' , $text , - 1 , PREG_SPLIT_DELIM_CAPTURE );
$stop = count ( $textarr );
2015-03-11 18:49:28 -04:00
2015-03-15 21:43:28 -04:00
// Ignore processing of specific tags.
2015-03-12 09:17:26 -04:00
$tags_to_ignore = 'code|pre|style|script|textarea' ;
$ignore_block_element = '' ;
2015-03-11 18:49:28 -04:00
2015-03-12 09:17:26 -04:00
for ( $i = 0 ; $i < $stop ; $i ++ ) {
$content = $textarr [ $i ];
2015-03-11 18:49:28 -04:00
2015-03-15 21:43:28 -04:00
// If we're in an ignore block, wait until we find its closing tag.
2015-03-12 09:17:26 -04:00
if ( '' == $ignore_block_element && preg_match ( '/^<(' . $tags_to_ignore . ')>/' , $content , $matches ) ) {
$ignore_block_element = $matches [ 1 ];
}
2015-03-11 18:49:28 -04:00
2015-03-15 21:43:28 -04:00
// If it's not a tag and not in ignore block.
2015-03-12 09:17:26 -04:00
if ( '' == $ignore_block_element && strlen ( $content ) > 0 && '<' != $content [ 0 ] ) {
$matches = array ();
if ( preg_match_all ( '/(DZ(e[6-9a-f]|f[0-9a-f]);){2}/' , $content , $matches ) ) {
if ( ! empty ( $matches [ 0 ] ) ) {
foreach ( $matches [ 0 ] as $flag ) {
$chars = str_replace ( array ( '&#x' , ';' ), '' , $flag );
2015-03-11 18:49:28 -04:00
2015-03-12 09:17:26 -04:00
list ( $char1 , $char2 ) = str_split ( $chars , 5 );
2015-03-29 23:09:26 -04:00
$entity = sprintf ( '<img src="%s" alt="%s" class="wp-smiley" style="height: 1em; max-height: 1em;" />' , $cdn_url . $char1 . '-' . $char2 . $ext , html_entity_decode ( $flag ) );
2015-03-11 18:49:28 -04:00
2015-03-12 09:17:26 -04:00
$content = str_replace ( $flag , $entity , $content );
}
2015-03-11 18:49:28 -04:00
}
}
2015-03-12 09:17:26 -04:00
// Loosely match the Emoji Unicode range.
$regex = '/(&#x[2-3][0-9a-f]{3};|[1-6][0-9a-f]{2};)/' ;
2015-03-11 18:49:28 -04:00
2015-03-12 09:17:26 -04:00
$matches = array ();
if ( preg_match_all ( $regex , $content , $matches ) ) {
if ( ! empty ( $matches [ 1 ] ) ) {
foreach ( $matches [ 1 ] as $emoji ) {
$char = str_replace ( array ( '&#x' , ';' ), '' , $emoji );
2015-03-29 23:09:26 -04:00
$entity = sprintf ( '<img src="%s" alt="%s" class="wp-smiley" style="height: 1em; max-height: 1em;" />' , $cdn_url . $char . $ext , html_entity_decode ( $emoji ) );
2015-03-11 18:49:28 -04:00
2015-03-12 09:17:26 -04:00
$content = str_replace ( $emoji , $entity , $content );
}
2015-03-11 18:49:28 -04:00
}
}
}
2015-03-15 21:43:28 -04:00
// Did we exit ignore block.
2015-03-12 09:17:26 -04:00
if ( '' != $ignore_block_element && '</' . $ignore_block_element . '>' == $content ) {
$ignore_block_element = '' ;
2015-03-11 18:49:28 -04:00
}
2015-03-12 09:17:26 -04:00
$output .= $content ;
2015-03-11 18:49:28 -04:00
}
2015-03-12 09:17:26 -04:00
return $output ;
2015-03-11 18:49:28 -04:00
}
/**
* Convert emoji in emails into static images .
*
2015-03-16 06:46:26 -04:00
* @ ignore
2015-03-15 21:43:28 -04:00
* @ since 4.2 . 0
2015-03-11 18:49:28 -04:00
*
2015-03-15 21:43:28 -04:00
* @ param array $mail The email data array .
2015-03-11 18:49:28 -04:00
* @ return array The email data array , with emoji in the message staticized .
*/
2015-03-16 06:46:26 -04:00
function _wp_staticize_emoji_for_email ( $mail ) {
2015-03-22 19:16:28 -04:00
if ( ! isset ( $mail [ 'message' ] ) ) {
return $mail ;
}
/*
* We can only transform the emoji into images if it ' s a text / html email .
* To do that , here ' s a cut down version of the same process that happens
* in wp_mail () - get the Content - Type from the headers , if there is one ,
* then pass it through the wp_mail_content_type filter , in case a plugin
* is handling changing the Content - Type .
*/
$headers = array ();
if ( isset ( $mail [ 'headers' ] ) ) {
if ( is_array ( $mail [ 'headers' ] ) ) {
$headers = $mail [ 'headers' ];
} else {
$headers = explode ( " \n " , str_replace ( " \r \n " , " \n " , $mail [ 'headers' ] ) );
}
}
foreach ( $headers as $header ) {
if ( strpos ( $header , ':' ) === false ) {
continue ;
}
// Explode them out
list ( $name , $content ) = explode ( ':' , trim ( $header ), 2 );
// Cleanup crew
$name = trim ( $name );
$content = trim ( $content );
if ( 'content-type' === strtolower ( $name ) ) {
if ( strpos ( $content , ';' ) !== false ) {
list ( $type , $charset ) = explode ( ';' , $content );
$content_type = trim ( $type );
} else {
$content_type = trim ( $content );
}
break ;
}
}
// Set Content-Type if we don't have a content-type from the input headers
if ( ! isset ( $content_type ) ) {
$content_type = 'text/plain' ;
}
/** This filter is documented in wp-includes/pluggable.php */
$content_type = apply_filters ( 'wp_mail_content_type' , $content_type );
if ( 'text/html' === $content_type ) {
2015-03-20 08:32:26 -04:00
$mail [ 'message' ] = wp_staticize_emoji ( $mail [ 'message' ], true );
}
2015-03-22 19:16:28 -04:00
2015-03-11 18:49:28 -04:00
return $mail ;
}