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
**/
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 ,
2008-08-17 07:29:43 -04:00
* < code >
* 'cause today' s effort makes it worth tomorrow ' s " holiday " ...
* </ code >
* Becomes :
* < code >
* & #8217;cause today’s effort makes it worth tomorrow’s “holiday”…
* </ code >
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
* @ return string The string replaced with html entities
*/
2004-02-09 01:57:02 -05:00
function wptexturize ( $text ) {
2006-10-04 02:07:48 -04:00
global $wp_cockneyreplace ;
2012-01-31 09:28:30 -05:00
static $static_characters , $static_replacements , $dynamic_characters , $dynamic_replacements ,
$default_no_texturize_tags , $default_no_texturize_shortcodes ;
2010-01-15 17:11:12 -05:00
2011-04-13 13:11:35 -04:00
// No need to set up these static variables more than once
2012-01-31 09:28:30 -05:00
if ( ! isset ( $static_characters ) ) {
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 ) ) {
$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.
$cockney = array ( " 'tain't " , " 'twere " , " 'twas " , " 'tis " , " 'twill " , " 'til " , " 'bout " , " 'nuff " , " 'round " , " 'cause " );
$cockneyreplace = array ( $apos . " tain " . $apos . " t " , $apos . " twere " , $apos . " twas " , $apos . " tis " , $apos . " twill " , $apos . " til " , $apos . " bout " , $apos . " nuff " , $apos . " round " , $apos . " cause " );
2009-10-21 17:57:27 -04:00
} else {
2012-01-31 09:06:32 -05:00
$cockney = $cockneyreplace = array ();
}
$static_characters = array_merge ( array ( '---' , ' -- ' , '--' , ' - ' , 'xn–' , '...' , '``' , '\'\'' , ' (tm)' ), $cockney );
$static_replacements = array_merge ( array ( $em_dash , ' ' . $em_dash . ' ' , $en_dash , ' ' . $en_dash . ' ' , 'xn--' , '…' , $opening_quote , $closing_quote , ' ™' ), $cockneyreplace );
$dynamic = array ();
if ( " ' " != $apos ) {
$dynamic [ '/\'(\d\d(?:’|\')?s)/' ] = $apos . '$1' ; // '99's
$dynamic [ '/\'(\d)/' ] = $apos . '$1' ; // '99
2009-10-21 17:57:27 -04:00
}
2012-01-31 09:06:32 -05:00
if ( " ' " != $opening_single_quote )
$dynamic [ '/(\s|\A|[([{<]|")\'/' ] = '$1' . $opening_single_quote ; // opening single quote, even after (, {, <, [
if ( '"' != $double_prime )
$dynamic [ '/(\d)"/' ] = '$1' . $double_prime ; // 9" (double prime)
if ( " ' " != $prime )
$dynamic [ '/(\d)\'/' ] = '$1' . $prime ; // 9' (prime)
if ( " ' " != $apos )
$dynamic [ '/(\S)\'([^\'\s])/' ] = '$1' . $apos . '$2' ; // apostrophe in a word
if ( '"' != $opening_quote )
$dynamic [ '/(\s|\A|[([{<])"(?!\s)/' ] = '$1' . $opening_quote . '$2' ; // opening double quote, even after (, {, <, [
if ( '"' != $closing_quote )
$dynamic [ '/"(\s|\S|\Z)/' ] = $closing_quote . '$1' ; // closing double quote
if ( " ' " != $closing_single_quote )
2012-02-10 17:28:37 -05:00
$dynamic [ '/\'([\s.]|\Z)/' ] = $closing_single_quote . '$1' ; // closing single quote
2010-05-03 16:26:11 -04:00
2012-01-31 09:06:32 -05:00
$dynamic [ '/\b(\d+)x(\d+)\b/' ] = '$1×$2' ; // 9x9 (times)
2010-05-03 16:26:11 -04:00
2012-01-31 09:06:32 -05:00
$dynamic_characters = array_keys ( $dynamic );
$dynamic_replacements = array_values ( $dynamic );
2006-11-21 17:00:10 -05:00
}
2004-02-09 01:57:02 -05:00
2009-10-21 17:57:27 -04:00
// Transform into regexp sub-expression used in _wptexturize_pushpop_element
// Must do this everytime in case plugins use these filters in a context sensitive manner
$no_texturize_tags = '(' . implode ( '|' , apply_filters ( 'no_texturize_tags' , $default_no_texturize_tags ) ) . ')' ;
$no_texturize_shortcodes = '(' . implode ( '|' , 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
2011-04-13 13:11:35 -04:00
$textarr = preg_split ( '/(<.*>|\[.*\])/Us' , $text , - 1 , PREG_SPLIT_DELIM_CAPTURE );
foreach ( $textarr as & $curl ) {
if ( empty ( $curl ) )
continue ;
2006-02-12 02:53:23 -05:00
2011-04-13 13:11:35 -04:00
// Only call _wptexturize_pushpop_element if first char is correct tag opening
$first = $curl [ 0 ];
if ( '<' === $first ) {
_wptexturize_pushpop_element ( $curl , $no_texturize_tags_stack , $no_texturize_tags , '<' , '>' );
} elseif ( '[' === $first ) {
_wptexturize_pushpop_element ( $curl , $no_texturize_shortcodes_stack , $no_texturize_shortcodes , '[' , ']' );
} elseif ( empty ( $no_texturize_shortcodes_stack ) && empty ( $no_texturize_tags_stack ) ) {
// This is not a tag, nor is the texturization disabled static strings
2006-11-21 17:00:10 -05:00
$curl = str_replace ( $static_characters , $static_replacements , $curl );
// regular expressions
$curl = preg_replace ( $dynamic_characters , $dynamic_replacements , $curl );
2004-02-09 01:57:02 -05:00
}
2006-04-03 20:47:33 -04:00
$curl = preg_replace ( '/&([^#])(?![a-zA-Z1-4]{1,8};)/' , '&$1' , $curl );
2004-02-09 01:57:02 -05:00
}
2011-04-13 13:11:35 -04:00
return implode ( '' , $textarr );
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
* on tag close . Assumes first character of $text is tag opening .
*
* @ access private
* @ since 2.9 . 0
*
* @ param string $text Text to check . First character is assumed to be $opening
* @ param array $stack Array used as stack of opened tag elements
* @ param string $disabled_elements Tags to match against formatted as regexp sub - expression
* @ param string $opening Tag opening character , assumed to be 1 character long
* @ param string $opening Tag closing character
* @ return object
*/
function _wptexturize_pushpop_element ( $text , & $stack , $disabled_elements , $opening = '<' , $closing = '>' ) {
// Check if it is a closing tag -- otherwise assume opening tag
if ( strncmp ( $opening . '/' , $text , 2 )) {
// Opening? Check $text+1 against disabled elements
if ( preg_match ( '/^' . $disabled_elements . '\b/' , substr ( $text , 1 ), $matches )) {
/*
* 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
*/
array_push ( $stack , $matches [ 1 ]);
}
} else {
// Closing? Check $text+2 against disabled elements
$c = preg_quote ( $closing , '/' );
if ( preg_match ( '/^' . $disabled_elements . $c . '/' , substr ( $text , 2 ), $matches )) {
2009-05-15 17:37:18 -04:00
$last = array_pop ( $stack );
2009-10-21 17:57:27 -04:00
// Make sure it matches the opening tag
if ( $last != $matches [ 1 ])
array_push ( $stack , $last );
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
* replace double line - breaks with HTML paragraph tags . The remaining
* line - breaks after conversion become << br />> tags , unless $br is set to '0'
2008-08-30 17:28:11 -04:00
* or 'false' .
2008-08-17 07:29:43 -04:00
*
* @ since 0.71
*
* @ param string $pee The text which has to be formatted .
2012-03-28 11:43:31 -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
2004-02-09 01:57:02 -05:00
$pee = $pee . " \n " ; // just to make things a little easier, pad the end
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 ;
}
2004-02-09 01:57:02 -05:00
$pee = preg_replace ( '|<br />\s*<br />|' , " \n \n " , $pee );
2004-04-22 03:41:57 -04:00
// Space things out a little
2012-03-02 14:59:50 -05:00
$allblocks = '(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|option|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)' ;
2006-11-30 18:32:45 -05:00
$pee = preg_replace ( '!(<' . $allblocks . '[^>]*>)!' , " \n $ 1 " , $pee );
$pee = preg_replace ( '!(</' . $allblocks . '>)!' , " $ 1 \n \n " , $pee );
2006-11-19 02:56:05 -05:00
$pee = str_replace ( array ( " \r \n " , " \r " ), " \n " , $pee ); // cross-platform newlines
2008-01-17 10:44:05 -05:00
if ( strpos ( $pee , '<object' ) !== false ) {
$pee = preg_replace ( '|\s*<param([^>]*)>\s*|' , " <param $ 1> " , $pee ); // no pee inside object/embed
$pee = preg_replace ( '|\s*</embed>\s*|' , '</embed>' , $pee );
}
2004-02-09 01:57:02 -05:00
$pee = preg_replace ( " / \n \n +/ " , " \n \n " , $pee ); // take care of duplicates
2008-10-20 15:25:02 -04:00
// make paragraphs, including one at the end
$pees = preg_split ( '/\n\s*\n/' , $pee , - 1 , PREG_SPLIT_NO_EMPTY );
$pee = '' ;
foreach ( $pees as $tinkle )
$pee .= '<p>' . trim ( $tinkle , " \n " ) . " </p> \n " ;
2009-02-08 11:08:02 -05:00
$pee = preg_replace ( '|<p>\s*</p>|' , '' , $pee ); // under certain strange conditions it could create a P of entirely whitespace
$pee = preg_replace ( '!<p>([^<]+)</(div|address|form)>!' , " <p> $ 1</p></ $ 2> " , $pee );
2006-11-30 18:32:45 -05:00
$pee = preg_replace ( '!<p>\s*(</?' . $allblocks . '[^>]*>)\s*</p>!' , " $ 1 " , $pee ); // don't pee all over a tag
2004-02-09 01:57:02 -05:00
$pee = preg_replace ( " |<p>(<li.+?)</p>| " , " $ 1 " , $pee ); // problem with nested lists
$pee = preg_replace ( '|<p><blockquote([^>]*)>|i' , " <blockquote $ 1><p> " , $pee );
$pee = str_replace ( '</blockquote></p>' , '</p></blockquote>' , $pee );
2006-11-30 18:32:45 -05:00
$pee = preg_replace ( '!<p>\s*(</?' . $allblocks . '[^>]*>)!' , " $ 1 " , $pee );
$pee = preg_replace ( '!(</?' . $allblocks . '[^>]*>)\s*</p>!' , " $ 1 " , $pee );
2012-03-28 11:43:31 -04:00
if ( $br ) {
2010-11-11 17:50:36 -05:00
$pee = preg_replace_callback ( '/<(script|style).*?<\/\\1>/s' , '_autop_newline_preservation_helper' , $pee );
2006-07-04 19:16:04 -04:00
$pee = preg_replace ( '|(?<!<br />)\s*\n|' , " <br /> \n " , $pee ); // optionally make line breaks
$pee = str_replace ( '<WPPreserveNewline />' , " \n " , $pee );
}
2006-11-30 18:32:45 -05:00
$pee = preg_replace ( '!(</?' . $allblocks . '[^>]*>)\s*<br />!' , " $ 1 " , $pee );
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
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
* @ param array $matches preg_replace_callback matches array
* @ returns string
*/
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
*
* Ensures that shortcodes are not wrapped in << p >>...<</ p >>.
*
* @ 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 ) ) );
$pattern =
'/'
. '<p>' // Opening paragraph
. '\\s*+' // Optional leading whitespace
. '(' // 1: The shortcode
. '\\[' // Opening bracket
. " ( $tagregexp ) " // 2: Shortcode name
. '\\b' // Word boundary
// 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
. ')?'
. ')'
. ')'
. '\\s*+' // optional trailing whitespace
. '<\\/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 ) {
2009-05-20 17:13:14 -04:00
$length = strlen ( $str );
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 ]);
2009-05-20 17:13:14 -04: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
2004-05-22 10:34:09 -04:00
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
*
2009-01-04 17:25:50 -05:00
* @ param string $string The text which is to be encoded .
* @ param mixed $quote_style Optional . Converts double quotes if set to ENT_COMPAT , both single and double if set to ENT_QUOTES or none if set to ENT_NOQUOTES . Also compatible with old values ; converting single quotes if set to 'single' , double if set to 'double' or both if otherwise set . Default is ENT_NOQUOTES .
* @ param string $charset Optional . The character encoding of the string . Default is false .
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
2011-07-29 16:43:45 -04:00
for ( $i = 0 ; $i < count ( $string ); $i += 2 )
$string [ $i ] = @ htmlspecialchars ( $string [ $i ], $quote_style , $charset );
2009-01-04 18:37:47 -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
*
* @ since 2.8
*
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 .
*
* @ since 2.8
*
* @ 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
2007-11-05 12:13:43 -05:00
$string_length = strlen ( $utf8_string );
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 {
if ( count ( $values ) == 0 ) $num_octets = ( $value < 224 ) ? 2 : 3 ;
$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 ) {
2006-11-30 15:26:42 -05:00
if ( $num_octets == 3 ) {
$unicode .= '%' . dechex ( $values [ 0 ]) . '%' . dechex ( $values [ 1 ]) . '%' . dechex ( $values [ 2 ]);
2007-11-05 12:13:43 -05:00
$unicode_length += 9 ;
2006-11-30 15:26:42 -05:00
} else {
$unicode .= '%' . dechex ( $values [ 0 ]) . '%' . dechex ( $values [ 1 ]);
2007-11-05 12:13:43 -05:00
$unicode_length += 6 ;
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' ,
);
2006-02-12 02:53:23 -05:00
2004-09-10 04:36:54 -04:00
$string = strtr ( $string , $chars );
} else {
// Assume ISO-8859-1 if not UTF-8
$chars [ 'in' ] = chr ( 128 ) . chr ( 131 ) . chr ( 138 ) . chr ( 142 ) . chr ( 154 ) . chr ( 158 )
. chr ( 159 ) . chr ( 162 ) . chr ( 165 ) . chr ( 181 ) . chr ( 192 ) . chr ( 193 ) . chr ( 194 )
. chr ( 195 ) . chr ( 196 ) . chr ( 197 ) . chr ( 199 ) . chr ( 200 ) . chr ( 201 ) . chr ( 202 )
. chr ( 203 ) . chr ( 204 ) . chr ( 205 ) . chr ( 206 ) . chr ( 207 ) . chr ( 209 ) . chr ( 210 )
. chr ( 211 ) . chr ( 212 ) . chr ( 213 ) . chr ( 214 ) . chr ( 216 ) . chr ( 217 ) . chr ( 218 )
. chr ( 219 ) . chr ( 220 ) . chr ( 221 ) . chr ( 224 ) . chr ( 225 ) . chr ( 226 ) . chr ( 227 )
. chr ( 228 ) . chr ( 229 ) . chr ( 231 ) . chr ( 232 ) . chr ( 233 ) . chr ( 234 ) . chr ( 235 )
. chr ( 236 ) . chr ( 237 ) . chr ( 238 ) . chr ( 239 ) . chr ( 241 ) . chr ( 242 ) . chr ( 243 )
. chr ( 244 ) . chr ( 245 ) . chr ( 246 ) . chr ( 248 ) . chr ( 249 ) . chr ( 250 ) . chr ( 251 )
. chr ( 252 ) . chr ( 253 ) . chr ( 255 );
$chars [ 'out' ] = " EfSZszYcYuAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy " ;
$string = strtr ( $string , $chars [ 'in' ], $chars [ 'out' ]);
$double_chars [ 'in' ] = array ( chr ( 140 ), chr ( 156 ), chr ( 198 ), chr ( 208 ), chr ( 222 ), chr ( 223 ), chr ( 230 ), chr ( 240 ), chr ( 254 ));
$double_chars [ 'out' ] = array ( 'OE' , 'oe' , 'AE' , 'DH' , 'TH' , 'ss' , 'ae' , 'dh' , 'th' );
$string = str_replace ( $double_chars [ 'in' ], $double_chars [ 'out' ], $string );
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
/**
2009-05-04 16:20:48 -04: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
2009-05-04 16:20:48 -04:00
* dashes with a single dash . Trim period , dash and underscore from beginning
* 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 ));
2009-05-04 16:20:48 -04:00
$special_chars = apply_filters ( 'sanitize_file_name_chars' , $special_chars , $filename_raw );
$filename = str_replace ( $special_chars , '' , $filename );
$filename = preg_replace ( '/[\s-]+/' , '-' , $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
if ( count ( $parts ) <= 2 )
return apply_filters ( 'sanitize_file_name' , $filename , $filename_raw );
// Process multiple extensions
$filename = array_shift ( $parts );
$extension = array_pop ( $parts );
$mimes = get_allowed_mime_types ();
2011-12-13 18:45:31 -05:00
// Loop over any intermediate extensions. Munge them with a trailing underscore if they are a 2 - 5 character
2009-11-11 18:07:29 -05:00
// long alpha string not in the extension whitelist.
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 ;
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
/**
2008-08-30 17:28:11 -04:00
* Sanitize 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-31 16:58:19 -04:00
* @ uses apply_filters () Calls 'sanitize_user' hook on username , raw username ,
* and $strict parameter .
2008-08-17 07:29:43 -04:00
*
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
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
/**
* Sanitize a string key .
*
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 );
return apply_filters ( 'sanitize_key' , $key , $raw_key );
2010-03-16 15:19:32 -04:00
}
2008-08-17 07:29:43 -04:00
/**
2008-08-30 17:28:11 -04:00
* Sanitizes title or use 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
*/
2010-10-23 08:55:55 -04: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 );
$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
}
2010-10-23 08:55:55 -04:00
function sanitize_title_for_query ( $title ) {
return sanitize_title ( $title , '' , 'query' );
}
2008-08-17 07:29:43 -04:00
/**
2011-09-18 15:53:59 -04:00
* Sanitizes 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
*/
2011-09-18 15:53:59 -04: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' ,
), '' , $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 .
2008-12-09 13:03:31 -05:00
* @ return string | false 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
/**
2009-05-22 17:31:42 -04:00
* Santizes a 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
2010-02-27 15:06:35 -05:00
* @ param string $fallback Optional . The value to return if the sanitization end ' s up as an empty string .
* 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
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
*
2008-08-27 02:49:21 -04:00
* Metadata tags << title >> and << category >> are removed , << br >> and << hr >> are
* 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
/**
2008-08-30 17:28:11 -04:00
* Will only balance the tags if forced to and the option is set to balance tags .
2008-08-17 07:29:43 -04:00
*
2011-12-16 15:57:05 -05:00
* The option 'use_balanceTags' is used to determine whether the tags will be balanced .
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 ) {
if ( ! $force && get_option ( 'use_balanceTags' ) == 0 )
return $text ;
return force_balance_tags ( $text );
}
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 = '' ;
2011-08-23 11:37:38 -04:00
$single_tags = array ( 'br' , 'hr' , 'img' , 'input' ); // Known single-entity/self-closing tags
$nestable_tags = array ( 'blockquote' , 'div' , 'span' , 'q' ); // Tags that can be immediately nested within themselves
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
2010-04-01 09:18:34 -04:00
else if ( $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
2005-01-06 05:24:11 -05:00
// If self-closing or '', don't do anything.
2010-04-01 09:18:34 -04:00
if ( substr ( $regex [ 2 ], - 1 ) == '/' || $tag == '' ) {
// do nothing
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 ] .= '/' ;
} else { // Push the tag onto the stack
// 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 ) {
2005-01-06 05:24:11 -05:00
$tagqueue = '</' . array_pop ( $tagstack ) . '>' ;
$stacksize -- ;
}
2004-02-09 01:57:02 -05:00
$stacksize = array_push ( $tagstack , $tag );
}
// Attributes
$attributes = $regex [ 2 ];
2010-04-01 09:18:34 -04:00
if ( ! empty ( $attributes ) )
2004-02-09 01:57:02 -05:00
$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 ) {
$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
/**
* Holder for the 'format_to_post' filter .
*
* @ since 0.71
*
* @ param string $content The text to pass through the filter .
2008-08-27 02:49:21 -04:00
* @ return string Text returned from the 'format_to_post' filter .
2008-08-17 07:29:43 -04:00
*/
2004-02-09 01:57:02 -05:00
function format_to_post ( $content ) {
2004-04-04 19:15:54 -04:00
$content = apply_filters ( 'format_to_post' , $content );
2004-02-09 01:57:02 -05:00
return $content ;
}
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 ) {
2006-06-07 23:17:01 -04:00
$string = preg_replace ( '/^([0-9])/' , '\\\\\\\\\1' , $string );
2004-02-09 01:57:02 -05:00
$string = preg_replace ( '/([a-z])/i' , '\\\\\1' , $string );
return $string ;
}
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
*
2008-08-27 02:49:21 -04:00
* Will remove trailing slash if it exists already before adding a trailing
* 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
* @ uses untrailingslashit () Unslashes string if it was slashed already .
2008-08-17 07:29:43 -04:00
*
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
*/
2004-02-09 01:57:02 -05:00
function trailingslashit ( $string ) {
2007-03-10 03:32:57 -05:00
return untrailingslashit ( $string ) . '/' ;
2004-02-09 01:57:02 -05:00
}
2008-08-17 07:29:43 -04:00
/**
2008-08-27 02:49:21 -04:00
* Removes trailing slash if it exists .
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
*
2008-08-27 02:49:21 -04:00
* @ param string $string What to remove the trailing slash from .
* @ return string String without the trailing slash .
2008-08-17 07:29:43 -04:00
*/
2007-03-10 01:25:33 -05:00
function untrailingslashit ( $string ) {
2007-03-10 03:32:57 -05:00
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 );
2009-09-27 01:33:56 -04:00
return esc_sql ( $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
*
2011-05-14 05:50:20 -04:00
* @ param array | string $value The array or string to be stripped .
2008-08-27 02:49:21 -04:00
* @ return array | string Stripped array ( or string in the callback ) .
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 );
}
} else {
$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
*
2008-08-31 16:58:19 -04:00
* @ param string $emailaddy Email address .
* @ param int $mailto Optional . Range from 0 to 1. Used for encoding .
* @ return string Converted email address .
2008-08-17 07:29:43 -04:00
*/
2004-02-09 01:57:02 -05:00
function antispambot ( $emailaddy , $mailto = 0 ) {
$emailNOSPAMaddy = '' ;
srand (( float ) microtime () * 1000000 );
for ( $i = 0 ; $i < strlen ( $emailaddy ); $i = $i + 1 ) {
$j = floor ( rand ( 0 , 1 + $mailto ));
if ( $j == 0 ) {
$emailNOSPAMaddy .= '&#' . ord ( substr ( $emailaddy , $i , 1 )) . ';' ;
} elseif ( $j == 1 ) {
$emailNOSPAMaddy .= substr ( $emailaddy , $i , 1 );
} elseif ( $j == 2 ) {
$emailNOSPAMaddy .= '%' . zeroise ( dechex ( ord ( substr ( $emailaddy , $i , 1 ))), 2 );
}
}
$emailNOSPAMaddy = str_replace ( '@' , '@' , $emailNOSPAMaddy );
return $emailNOSPAMaddy ;
}
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
foreach ( $textarr as $piece ) {
if ( empty ( $piece ) || ( $piece [ 0 ] == '<' && ! preg_match ( '|^<\s*[\w]{1,20}+://|' , $piece ) ) ) {
$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
2012-04-11 17:14:13 -04:00
$r = preg_replace ( '#(<a( [^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i' , " $ 1 $ 3</a> " , $r );
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 )
*
* < code >
* _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
* 7 => '1 3 5 7 9' , // 9 characters: End of $string
* );
* </ code >
*
2012-02-10 08:57:21 -05:00
* @ since 3.4 . 0
* @ access private
*
2012-02-10 08:42:15 -05:00
* @ param string $string The string to split
* @ param int $goal The desired chunk length .
* @ 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 ) {
2006-02-28 04:49:06 -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 );
2009-09-27 01:33:56 -04:00
$text = esc_sql ( $text );
2005-01-21 13:24:14 -05:00
return $text ;
}
2008-08-17 07:29:43 -04:00
/**
2008-08-31 16:58:19 -04:00
* Callback to used 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 .
*
* Looks up one smiley code in the $wpsmiliestrans global array and returns an
* < img > string for that smiley .
*
* @ global array $wpsmiliestrans
* @ since 2.8 . 0
*
* @ param string $smiley Smiley code to convert to image .
* @ return string Image string for smiley .
*/
function translate_smiley ( $smiley ) {
global $wpsmiliestrans ;
if ( count ( $smiley ) == 0 ) {
return '' ;
}
$smiley = trim ( reset ( $smiley ));
$img = $wpsmiliestrans [ $smiley ];
2009-05-05 15:43:53 -04:00
$smiley_masked = esc_attr ( $smiley );
2009-09-14 10:03:32 -04:00
2010-08-31 14:26:18 -04:00
$srcurl = apply_filters ( 'smilies_src' , includes_url ( " images/smilies/ $img " ), $img , site_url ());
2009-01-06 13:20:47 -05:00
2009-07-22 14:27:13 -04:00
return " <img src=' $srcurl ' alt=' $smiley_masked ' class='wp-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
*/
2004-02-09 01:57:02 -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 = '' ;
2009-01-06 13:20:47 -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
$textarr = preg_split ( " /(<.*>)/U " , $text , - 1 , PREG_SPLIT_DELIM_CAPTURE ); // capture the tags as well as in between
2007-09-03 19:32:58 -04:00
$stop = count ( $textarr ); // loop stuff
for ( $i = 0 ; $i < $stop ; $i ++ ) {
$content = $textarr [ $i ];
2010-11-13 04:53:55 -05:00
if (( strlen ( $content ) > 0 ) && ( '<' != $content [ 0 ])) { // If it's not a tag
2009-01-06 13:20:47 -05:00
$content = preg_replace_callback ( $wp_smiliessearch , 'translate_smiley' , $content );
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 ) {
return apply_filters ( 'is_email' , false , $email , 'email_too_short' );
}
// Test for an @ character after the first position
if ( strpos ( $email , '@' , 1 ) === false ) {
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 ) ) {
return apply_filters ( 'is_email' , false , $email , 'local_invalid_chars' );
}
// DOMAIN PART
// Test for sequences of periods
if ( preg_match ( '/\.{2,}/' , $domain ) ) {
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 ) {
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 ) ) {
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 ) {
return apply_filters ( 'is_email' , false , $email , 'sub_hyphen_limits' );
}
// Test for invalid characters
if ( ! preg_match ( '/^[a-z0-9-]+$/i' , $sub ) ) {
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!
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
* @ usedby wp_mail () handles charsets in email subjects
*
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
/**
* 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
2010-11-18 14:12:48 -05:00
* @ param array $match the preg_replace_callback matches array
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
*
2008-08-30 17:28:11 -04:00
* Requires and returns a date in the Y - m - d H : i : s format . Simply subtracts the
2009-08-20 02:59:02 -04:00
* value of the 'gmt_offset' option . Return format can be overridden using the
2011-05-18 14:56:42 -04:00
* $format parameter . The DateTime and DateTimeZone classes are used to respect
* time zone differences in DST .
2008-08-17 07:29:43 -04:00
*
* @ since 1.2 . 0
*
2009-01-17 05:20:49 -05:00
* @ uses get_option () to retrieve the the value of 'gmt_offset' .
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
*/
2009-08-20 02:59:02 -04:00
function get_gmt_from_date ( $string , $format = 'Y-m-d H:i:s' ) {
2008-08-17 07:29:43 -04:00
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 );
2010-05-06 16:40:29 -04:00
$tz = get_option ( 'timezone_string' );
2011-05-18 14:56:42 -04:00
if ( $tz ) {
date_default_timezone_set ( $tz );
$datetime = new DateTime ( $string );
$datetime -> setTimezone ( new DateTimeZone ( 'UTC' ) );
$offset = $datetime -> getOffset ();
$datetime -> modify ( '+' . $offset / 3600 . ' hours' );
$string_gmt = gmdate ( $format , $datetime -> format ( 'U' ));
date_default_timezone_set ( 'UTC' );
} else {
$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' ) * 3600 );
}
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
*
2008-08-30 17:28:11 -04:00
* Requires and returns in the Y - m - d H : i : s format . Simply adds the value of
2009-08-20 02:59:02 -04:00
* 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 )
2008-08-27 02:49:21 -04:00
* @ return string Formatted date relative to the GMT offset .
2008-08-17 07:29:43 -04:00
*/
2009-08-20 02:59:02 -04:00
function get_date_from_gmt ( $string , $format = 'Y-m-d H:i:s' ) {
2008-08-17 07:29:43 -04:00
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 );
$string_time = gmmktime ( $matches [ 4 ], $matches [ 5 ], $matches [ 6 ], $matches [ 2 ], $matches [ 3 ], $matches [ 1 ]);
2009-08-20 02:59:02 -04:00
$string_localtime = gmdate ( $format , $string_time + get_option ( 'gmt_offset' ) * 3600 );
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 ;
$offset = $sign * 3600 * ( $hours + $minutes );
}
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!)
$offset = 3600 * get_option ( 'gmt_offset' );
}
$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 );
2008-10-13 18:14:52 -04:00
} else if ( $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 ) {
return apply_filters ( 'sanitize_email' , '' , $email , 'email_too_short' );
}
// Test for an @ character after the first position
if ( strpos ( $email , '@' , 1 ) === false ) {
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 ) {
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 ) {
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 ) {
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 ) ) {
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 ) ) {
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!
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 = '' ) {
2004-12-18 19:10:10 -05:00
if ( empty ( $to ) )
$to = time ();
2005-03-10 03:01:02 -05:00
$diff = ( int ) abs ( $to - $from );
2004-12-18 19:10:10 -05:00
if ( $diff <= 3600 ) {
$mins = round ( $diff / 60 );
2006-12-21 18:06:18 -05:00
if ( $mins <= 1 ) {
$mins = 1 ;
}
2010-01-21 16:37:43 -05:00
/* translators: min=minute */
2009-02-20 14:35:16 -05:00
$since = sprintf ( _n ( '%s min' , '%s mins' , $mins ), $mins );
2004-12-18 19:10:10 -05:00
} else if (( $diff <= 86400 ) && ( $diff > 3600 )) {
$hours = round ( $diff / 3600 );
2006-12-21 18:06:18 -05:00
if ( $hours <= 1 ) {
2007-12-06 14:49:33 -05:00
$hours = 1 ;
2006-12-21 18:06:18 -05:00
}
2009-02-20 14:35:16 -05:00
$since = sprintf ( _n ( '%s hour' , '%s hours' , $hours ), $hours );
2004-12-18 19:10:10 -05:00
} elseif ( $diff >= 86400 ) {
$days = round ( $diff / 86400 );
2006-12-21 18:06:18 -05:00
if ( $days <= 1 ) {
$days = 1 ;
}
2009-02-20 14:35:16 -05:00
$since = sprintf ( _n ( '%s day' , '%s days' , $days ), $days );
2004-12-18 19:10:10 -05:00
}
return $since ;
}
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
2009-12-16 11:38:58 -05: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
2009-12-16 11:38:58 -05: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 );
2005-03-13 20:02:04 -05:00
$text = apply_filters ( 'the_content' , $text );
$text = str_replace ( ']]>' , ']]>' , $text );
2008-09-22 17:21:05 -04:00
$excerpt_length = apply_filters ( 'excerpt_length' , 55 );
2009-12-16 11:38:58 -05:00
$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
}
2009-04-17 02:59:33 -04:00
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 .
*
* @ since 3.3 . 0
*
* @ param string $text Text to trim .
* @ param int $num_words Number of words . Default 55.
* @ param string $more What to append if $text needs to be trimmed . Default '…' .
* @ 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 );
2011-09-20 13:14:23 -04:00
$words_array = preg_split ( " /[ \n \r \t ]+/ " , $text , $num_words + 1 , PREG_SPLIT_NO_EMPTY );
if ( count ( $words_array ) > $num_words ) {
array_pop ( $words_array );
$text = implode ( ' ' , $words_array );
$text = $text . $more ;
} else {
$text = implode ( ' ' , $words_array );
}
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
2011-07-25 09:20:07 -04:00
// Allow a plugin to short-circuit and override the mappings.
$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 ) {
// Filtering a blank results in an annoying <br />\n
2005-12-10 14:03:22 -05:00
if ( empty ( $text ) ) 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 );
2008-07-08 19:38:53 -04:00
$output = htmlspecialchars ( $output , ENT_NOQUOTES );
2005-11-17 12:47:29 -05:00
2005-12-10 14:03:22 -05:00
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 ) )
$output = htmlspecialchars ( $output , ENT_NOQUOTES ); // convert only < > &
return apply_filters ( 'htmledit_pre' , $output );
}
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
*
2009-06-20 13:42:24 -04:00
* @ param string | array $search
* @ param string $subject
* @ return string The processed string
*/
2010-04-03 23:07:14 -04:00
function _deep_replace ( $search , $subject ) {
2009-06-20 13:42:24 -04:00
$found = true ;
2010-04-03 23:07:14 -04:00
$subject = ( string ) $subject ;
while ( $found ) {
2009-06-20 13:42:24 -04:00
$found = false ;
2010-04-03 23:07:14 -04:00
foreach ( ( array ) $search as $val ) {
while ( strpos ( $subject , $val ) !== false ) {
2009-06-20 13:42:24 -04:00
$found = true ;
2010-04-03 23:07:14 -04:00
$subject = str_replace ( $val , '' , $subject );
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
/**
* Escapes data for use in a MySQL query
*
* This is just a handy shortcut for $wpdb -> escape (), for completeness ' sake
*
* @ since 2.8 . 0
* @ param string $sql Unescaped SQL data
* @ return string The cleaned $sql
*/
function esc_sql ( $sql ) {
global $wpdb ;
return $wpdb -> escape ( $sql );
}
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
* @ uses wp_kses_bad_protocol () To only permit protocols in the URL set
* via $protocols or the common ones set in the function .
*
* @ 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 );
}
2011-09-29 18:33:51 -04:00
if ( ! is_array ( $protocols ) )
$protocols = wp_allowed_protocols ();
2010-02-22 13:25:51 -05:00
if ( wp_kses_bad_protocol ( $url , $protocols ) != $url )
return '' ;
return apply_filters ( 'clean_url' , $url , $original_url , $_context );
2009-05-18 12:00:33 -04:00
}
/**
* Performs esc_url () for database usage .
*
* @ since 2.8 . 0
2010-02-22 13:25:51 -05:00
* @ uses esc_url ()
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 ) );
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 );
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 );
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 .
*
* @ since 3.1
*
* @ param string $text
* @ return string
*/
function esc_textarea ( $text ) {
2010-12-16 04:24:22 -05:00
$safe_text = htmlspecialchars ( $text , ENT_QUOTES );
2010-11-17 12:12:01 -05:00
return apply_filters ( 'esc_textarea' , $safe_text , $text );
}
2008-08-27 02:49:21 -04:00
/**
* Escape a HTML tag name .
*
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 ) );
2008-03-24 01:15:28 -04:00
return apply_filters ( 'tag_escape' , $safe_tag , $tag_name );
}
2008-01-29 12:20:27 -05:00
/**
2008-08-27 02:49:21 -04:00
* Escapes text for SQL LIKE special characters % and _ .
2008-01-29 12:20:27 -05:00
*
2008-08-30 17:28:11 -04:00
* @ since 2.5 . 0
2008-08-27 02:49:21 -04:00
*
* @ param string $text The text to be escaped .
* @ return string text , safe for inclusion in LIKE query .
2008-01-29 12:20:27 -05:00
*/
function like_escape ( $text ) {
2010-02-04 16:40:02 -05:00
return str_replace ( array ( " % " , " _ " ), array ( " \\ % " , " \\ _ " ), $text );
2008-01-29 12:20:27 -05:00
}
2006-12-21 05:10:04 -05: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
*
* @ 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 ) {
2008-08-30 17:28:11 -04:00
return preg_replace ( '|https?://[^/]+(/.*)|i' , '$1' , $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 ) {
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' :
$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' :
2009-10-13 13:04:22 -04:00
case 'embed_size_h' :
2007-05-24 22:22:30 -04:00
case 'default_post_edit_rows' :
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 ;
2009-10-13 18:36:24 -04:00
case 'embed_size_w' :
if ( '' !== $value )
$value = absint ( $value );
break ;
2007-05-24 22:22:30 -04:00
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' :
$value = addslashes ( $value );
$value = wp_filter_post_kses ( $value ); // calls stripslashes then addslashes
$value = stripslashes ( $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 ;
case 'date_format' :
case 'time_format' :
case 'mailserver_url' :
case 'mailserver_login' :
case 'mailserver_pass' :
case 'ping_sites' :
case 'upload_path' :
$value = strip_tags ( $value );
$value = addslashes ( $value );
$value = wp_filter_kses ( $value ); // calls stripslashes then addslashes
$value = stripslashes ( $value );
break ;
case 'gmt_offset' :
$value = preg_replace ( '/[^0-9:.-]/' , '' , $value ); // strips slashes
break ;
case 'siteurl' :
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' :
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 ();
if ( ! in_array ( $value , $allowed ) && ! empty ( $value ) )
$value = get_option ( $option );
break ;
2010-04-25 04:16:10 -04:00
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' :
$value = esc_url_raw ( $value );
$value = str_replace ( 'http://' , '' , $value );
2007-05-24 22:22:30 -04:00
break ;
}
2011-09-21 15:05:06 -04:00
$value = apply_filters ( " sanitize_option_ { $option } " , $value , $option );
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
* @ uses apply_filters () for the 'wp_parse_str' filter .
2008-08-17 07:29:43 -04:00
*
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 );
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
*
* @ uses wp_pre_kses_less_than_callback in the callback function .
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 .
*
2009-05-18 11:11:07 -04:00
* @ uses esc_html to format the $matches text .
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 .
* @ param mixed $args , ... Arguments to be formatted into the $pattern string .
* @ return string The formatted string .
2008-02-22 00:53:47 -05:00
*/
function wp_sprintf ( $pattern ) {
$args = func_get_args ( );
$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 ] : '' ;
}
// Apply filters OR sprintf
$_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 '' ;
// Translate and filter the delimiter set (avoid ampersands and entities here)
$l = apply_filters ( 'wp_sprintf_l' , array (
2011-05-21 11:20:25 -04:00
/* translators: used between list items, there is a space after the comma */
2009-03-10 19:02:29 -04:00
'between' => __ ( ', ' ),
/* translators: used between list items, there is a space after the and */
'between_last_two' => __ ( ', and ' ),
/* translators: used between only two list items, there is a space after the and */
'between_only_two' => __ ( ' and ' ),
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
*
2008-08-27 02:49:21 -04:00
* @ param integer $str String to get the excerpt from .
* @ param integer $count Maximum number of characters to take .
* @ return string The excerpt .
2008-03-03 16:05:23 -05:00
*/
function wp_html_excerpt ( $str , $count ) {
2009-09-14 09:57:48 -04:00
$str = wp_strip_all_tags ( $str , true );
2009-03-04 14:41:18 -05:00
$str = mb_substr ( $str , 0 , $count );
2008-03-03 16:05:23 -05:00
// remove part of an entity at the end
$str = preg_replace ( '/&[^;\s]{0,6}$/' , '' , $str );
return $str ;
}
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 ] :
path_join ( $_links_add_base , $m [ 3 ] ) )
2008-08-04 17:01:09 -04:00
. $m [ 2 ];
}
/**
* Adds a Target attribute to all links in passed content .
*
2008-08-30 17:28:11 -04:00
* This function by default only applies to < a > tags , however this can be
* modified by the 3 rd param .
2008-08-04 17:01:09 -04:00
*
2011-05-14 05:50:20 -04:00
* < b > NOTE :</ b > 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 );
2011-02-16 14:24:18 -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 ];
$link = preg_replace ( '|(target=[\'"](.*?)[\'"])|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
}
2008-10-23 16:03:16 -04:00
// normalize EOL characters and strip duplicate whitespace
function normalize_whitespace ( $str ) {
$str = trim ( $str );
$str = str_replace ( " \r " , " \n " , $str );
$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
*
* @ 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
}
$match = array ();
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
return apply_filters ( 'sanitize_text_field' , $filtered , $str );
}
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 = '' ) {
return urldecode ( basename ( str_replace ( '%2F' , '/' , urlencode ( $path ) ), $suffix ) );
}
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
if ( 'the_title' === current_filter () )
return str_replace ( 'Wordpress' , 'WordPress' , $text );
// Still here? Use the more judicious replacement
static $dblq = false ;
if ( false === $dblq )
$dblq = _x ( '“' , 'opening curly quote' );
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 );
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 ) {
$urls_to_ping = preg_split ( '/\r\n\t /' , trim ( $to_ping ), - 1 , PREG_SPLIT_NO_EMPTY );
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 );
return apply_filters ( 'sanitize_trackback_urls' , $urls_to_ping , $to_ping );
}