web/wp-includes/formatting.php
changeset 194 32102edaa81b
parent 136 bde1974c263b
child 204 09a1c134465b
equal deleted inserted replaced
193:2f6f6f7551ca 194:32102edaa81b
    26  * @param string $text The text to be formatted
    26  * @param string $text The text to be formatted
    27  * @return string The string replaced with html entities
    27  * @return string The string replaced with html entities
    28  */
    28  */
    29 function wptexturize($text) {
    29 function wptexturize($text) {
    30 	global $wp_cockneyreplace;
    30 	global $wp_cockneyreplace;
    31 	static $static_setup = false, $opening_quote, $closing_quote, $default_no_texturize_tags, $default_no_texturize_shortcodes, $static_characters, $static_replacements, $dynamic_characters, $dynamic_replacements;
    31 	static $static_characters, $static_replacements, $dynamic_characters, $dynamic_replacements,
    32 	$output = '';
    32 		$default_no_texturize_tags, $default_no_texturize_shortcodes;
    33 	$curl = '';
    33 
    34 	$textarr = preg_split('/(<.*>|\[.*\])/Us', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
    34 	// No need to set up these static variables more than once
    35 	$stop = count($textarr);
    35 	if ( ! isset( $static_characters ) ) {
    36 	
    36 		/* translators: opening curly double quote */
    37 	// No need to setup these variables more than once
    37 		$opening_quote = _x( '&#8220;', 'opening curly double quote' );
    38 	if (!$static_setup) {
    38 		/* translators: closing curly double quote */
    39 		/* translators: opening curly quote */
    39 		$closing_quote = _x( '&#8221;', 'closing curly double quote' );
    40 		$opening_quote = _x('&#8220;', 'opening curly quote');
    40 
    41 		/* translators: closing curly quote */
    41 		/* translators: apostrophe, for example in 'cause or can't */
    42 		$closing_quote = _x('&#8221;', 'closing curly quote');
    42 		$apos = _x( '&#8217;', 'apostrophe' );
       
    43 
       
    44 		/* translators: prime, for example in 9' (nine feet) */
       
    45 		$prime = _x( '&#8242;', 'prime' );
       
    46 		/* translators: double prime, for example in 9" (nine inches) */
       
    47 		$double_prime = _x( '&#8243;', 'double prime' );
       
    48 
       
    49 		/* translators: opening curly single quote */
       
    50 		$opening_single_quote = _x( '&#8216;', 'opening curly single quote' );
       
    51 		/* translators: closing curly single quote */
       
    52 		$closing_single_quote = _x( '&#8217;', 'closing curly single quote' );
       
    53 
       
    54 		/* translators: en dash */
       
    55 		$en_dash = _x( '&#8211;', 'en dash' );
       
    56 		/* translators: em dash */
       
    57 		$em_dash = _x( '&#8212;', 'em dash' );
    43 
    58 
    44 		$default_no_texturize_tags = array('pre', 'code', 'kbd', 'style', 'script', 'tt');
    59 		$default_no_texturize_tags = array('pre', 'code', 'kbd', 'style', 'script', 'tt');
    45 		$default_no_texturize_shortcodes = array('code');
    60 		$default_no_texturize_shortcodes = array('code');
    46 
    61 
    47 		// if a plugin has provided an autocorrect array, use it
    62 		// if a plugin has provided an autocorrect array, use it
    48 		if ( isset($wp_cockneyreplace) ) {
    63 		if ( isset($wp_cockneyreplace) ) {
    49 			$cockney = array_keys($wp_cockneyreplace);
    64 			$cockney = array_keys($wp_cockneyreplace);
    50 			$cockneyreplace = array_values($wp_cockneyreplace);
    65 			$cockneyreplace = array_values($wp_cockneyreplace);
       
    66 		} elseif ( "'" != $apos ) { // Only bother if we're doing a replacement.
       
    67 			$cockney = array( "'tain't", "'twere", "'twas", "'tis", "'twill", "'til", "'bout", "'nuff", "'round", "'cause" );
       
    68 			$cockneyreplace = array( $apos . "tain" . $apos . "t", $apos . "twere", $apos . "twas", $apos . "tis", $apos . "twill", $apos . "til", $apos . "bout", $apos . "nuff", $apos . "round", $apos . "cause" );
    51 		} else {
    69 		} else {
    52 			$cockney = array("'tain't","'twere","'twas","'tis","'twill","'til","'bout","'nuff","'round","'cause");
    70 			$cockney = $cockneyreplace = array();
    53 			$cockneyreplace = array("&#8217;tain&#8217;t","&#8217;twere","&#8217;twas","&#8217;tis","&#8217;twill","&#8217;til","&#8217;bout","&#8217;nuff","&#8217;round","&#8217;cause");
       
    54 		}
    71 		}
    55 
    72 
    56 		$static_characters = array_merge(array('---', ' -- ', '--', ' - ', 'xn&#8211;', '...', '``', '\'s', '\'\'', ' (tm)'), $cockney);
    73 		$static_characters = array_merge( array( '---', ' -- ', '--', ' - ', 'xn&#8211;', '...', '``', '\'\'', ' (tm)' ), $cockney );
    57 		$static_replacements = array_merge(array('&#8212;', ' &#8212; ', '&#8211;', ' &#8211; ', 'xn--', '&#8230;', $opening_quote, '&#8217;s', $closing_quote, ' &#8482;'), $cockneyreplace);
    74 		$static_replacements = array_merge( array( $em_dash, ' ' . $em_dash . ' ', $en_dash, ' ' . $en_dash . ' ', 'xn--', '&#8230;', $opening_quote, $closing_quote, ' &#8482;' ), $cockneyreplace );
    58 
    75 
    59 		$dynamic_characters = array('/\'(\d\d(?:&#8217;|\')?s)/', '/(\s|\A|[([{<]|")\'/', '/(\d+)"/', '/(\d+)\'/', '/(\S)\'([^\'\s])/', '/(\s|\A|[([{<])"(?!\s)/', '/"(\s|\S|\Z)/', '/\'([\s.]|\Z)/', '/(\d+)x(\d+)/');
    76 		$dynamic = array();
    60 		$dynamic_replacements = array('&#8217;$1','$1&#8216;', '$1&#8243;', '$1&#8242;', '$1&#8217;$2', '$1' . $opening_quote . '$2', $closing_quote . '$1', '&#8217;$1', '$1&#215;$2');
    77 		if ( "'" != $apos ) {
    61 
    78 			$dynamic[ '/\'(\d\d(?:&#8217;|\')?s)/' ] = $apos . '$1'; // '99's
    62 		$static_setup = true;
    79 			$dynamic[ '/\'(\d)/'                   ] = $apos . '$1'; // '99
       
    80 		}
       
    81 		if ( "'" != $opening_single_quote )
       
    82 			$dynamic[ '/(\s|\A|[([{<]|")\'/'       ] = '$1' . $opening_single_quote; // opening single quote, even after (, {, <, [
       
    83 		if ( '"' != $double_prime )
       
    84 			$dynamic[ '/(\d)"/'                    ] = '$1' . $double_prime; // 9" (double prime)
       
    85 		if ( "'" != $prime )
       
    86 			$dynamic[ '/(\d)\'/'                   ] = '$1' . $prime; // 9' (prime)
       
    87 		if ( "'" != $apos )
       
    88 			$dynamic[ '/(\S)\'([^\'\s])/'          ] = '$1' . $apos . '$2'; // apostrophe in a word
       
    89 		if ( '"' != $opening_quote )
       
    90 			$dynamic[ '/(\s|\A|[([{<])"(?!\s)/'    ] = '$1' . $opening_quote . '$2'; // opening double quote, even after (, {, <, [
       
    91 		if ( '"' != $closing_quote )
       
    92 			$dynamic[ '/"(\s|\S|\Z)/'              ] = $closing_quote . '$1'; // closing double quote
       
    93 		if ( "'" != $closing_single_quote )
       
    94 			$dynamic[ '/\'([\s.]|\Z)/'             ] = $closing_single_quote . '$1'; // closing single quote
       
    95 
       
    96 		$dynamic[ '/\b(\d+)x(\d+)\b/'              ] = '$1&#215;$2'; // 9x9 (times)
       
    97 
       
    98 		$dynamic_characters = array_keys( $dynamic );
       
    99 		$dynamic_replacements = array_values( $dynamic );
    63 	}
   100 	}
    64 
   101 
    65 	// Transform into regexp sub-expression used in _wptexturize_pushpop_element
   102 	// Transform into regexp sub-expression used in _wptexturize_pushpop_element
    66 	// Must do this everytime in case plugins use these filters in a context sensitive manner
   103 	// Must do this everytime in case plugins use these filters in a context sensitive manner
    67 	$no_texturize_tags = '(' . implode('|', apply_filters('no_texturize_tags', $default_no_texturize_tags) ) . ')';
   104 	$no_texturize_tags = '(' . implode('|', apply_filters('no_texturize_tags', $default_no_texturize_tags) ) . ')';
    68 	$no_texturize_shortcodes = '(' . implode('|', apply_filters('no_texturize_shortcodes', $default_no_texturize_shortcodes) ) . ')';
   105 	$no_texturize_shortcodes = '(' . implode('|', apply_filters('no_texturize_shortcodes', $default_no_texturize_shortcodes) ) . ')';
    69 
   106 
    70 	$no_texturize_tags_stack = array();
   107 	$no_texturize_tags_stack = array();
    71 	$no_texturize_shortcodes_stack = array();
   108 	$no_texturize_shortcodes_stack = array();
    72 
   109 
    73 	for ( $i = 0; $i < $stop; $i++ ) {
   110 	$textarr = preg_split('/(<.*>|\[.*\])/Us', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
    74 		$curl = $textarr[$i];
   111 
    75 
   112 	foreach ( $textarr as &$curl ) {
    76 		if ( !empty($curl) && '<' != $curl{0} && '[' != $curl{0}
   113 		if ( empty( $curl ) )
    77 				&& empty($no_texturize_shortcodes_stack) && empty($no_texturize_tags_stack)) { 
   114 			continue;
    78 			// This is not a tag, nor is the texturization disabled
   115 
    79 			// static strings
   116 		// Only call _wptexturize_pushpop_element if first char is correct tag opening
       
   117 		$first = $curl[0];
       
   118 		if ( '<' === $first ) {
       
   119 			_wptexturize_pushpop_element($curl, $no_texturize_tags_stack, $no_texturize_tags, '<', '>');
       
   120 		} elseif ( '[' === $first ) {
       
   121 			_wptexturize_pushpop_element($curl, $no_texturize_shortcodes_stack, $no_texturize_shortcodes, '[', ']');
       
   122 		} elseif ( empty($no_texturize_shortcodes_stack) && empty($no_texturize_tags_stack) ) {
       
   123 			// This is not a tag, nor is the texturization disabled static strings
    80 			$curl = str_replace($static_characters, $static_replacements, $curl);
   124 			$curl = str_replace($static_characters, $static_replacements, $curl);
    81 			// regular expressions
   125 			// regular expressions
    82 			$curl = preg_replace($dynamic_characters, $dynamic_replacements, $curl);
   126 			$curl = preg_replace($dynamic_characters, $dynamic_replacements, $curl);
    83 		} elseif (!empty($curl)) {
       
    84 			/*
       
    85 			 * Only call _wptexturize_pushpop_element if first char is correct
       
    86 			 * tag opening
       
    87 			 */
       
    88 			if ('<' == $curl{0})
       
    89 				_wptexturize_pushpop_element($curl, $no_texturize_tags_stack, $no_texturize_tags, '<', '>');
       
    90 			elseif ('[' == $curl{0})
       
    91 				_wptexturize_pushpop_element($curl, $no_texturize_shortcodes_stack, $no_texturize_shortcodes, '[', ']');
       
    92 		}
   127 		}
    93 
       
    94 		$curl = preg_replace('/&([^#])(?![a-zA-Z1-4]{1,8};)/', '&#038;$1', $curl);
   128 		$curl = preg_replace('/&([^#])(?![a-zA-Z1-4]{1,8};)/', '&#038;$1', $curl);
    95 		$output .= $curl;
   129 	}
    96 	}
   130 	return implode( '', $textarr );
    97 
       
    98 	return $output;
       
    99 }
   131 }
   100 
   132 
   101 /**
   133 /**
   102  * Search for disabled element tags. Push element to stack on tag open and pop
   134  * Search for disabled element tags. Push element to stack on tag open and pop
   103  * on tag close. Assumes first character of $text is tag opening.
   135  * on tag close. Assumes first character of $text is tag opening.
   118 		// Opening? Check $text+1 against disabled elements
   150 		// Opening? Check $text+1 against disabled elements
   119 		if (preg_match('/^' . $disabled_elements . '\b/', substr($text, 1), $matches)) {
   151 		if (preg_match('/^' . $disabled_elements . '\b/', substr($text, 1), $matches)) {
   120 			/*
   152 			/*
   121 			 * This disables texturize until we find a closing tag of our type
   153 			 * This disables texturize until we find a closing tag of our type
   122 			 * (e.g. <pre>) even if there was invalid nesting before that
   154 			 * (e.g. <pre>) even if there was invalid nesting before that
   123 			 * 
   155 			 *
   124 			 * Example: in the case <pre>sadsadasd</code>"baba"</pre>
   156 			 * Example: in the case <pre>sadsadasd</code>"baba"</pre>
   125 			 *          "baba" won't be texturize
   157 			 *          "baba" won't be texturize
   126 			 */
   158 			 */
   127 
   159 
   128 			array_push($stack, $matches[1]);
   160 			array_push($stack, $matches[1]);
   139 		}
   171 		}
   140 	}
   172 	}
   141 }
   173 }
   142 
   174 
   143 /**
   175 /**
   144  * Accepts matches array from preg_replace_callback in wpautop() or a string.
       
   145  *
       
   146  * Ensures that the contents of a <<pre>>...<</pre>> HTML block are not
       
   147  * converted into paragraphs or line-breaks.
       
   148  *
       
   149  * @since 1.2.0
       
   150  *
       
   151  * @param array|string $matches The array or string
       
   152  * @return string The pre block without paragraph/line-break conversion.
       
   153  */
       
   154 function clean_pre($matches) {
       
   155 	if ( is_array($matches) )
       
   156 		$text = $matches[1] . $matches[2] . "</pre>";
       
   157 	else
       
   158 		$text = $matches;
       
   159 
       
   160 	$text = str_replace('<br />', '', $text);
       
   161 	$text = str_replace('<p>', "\n", $text);
       
   162 	$text = str_replace('</p>', '', $text);
       
   163 
       
   164 	return $text;
       
   165 }
       
   166 
       
   167 /**
       
   168  * Replaces double line-breaks with paragraph elements.
   176  * Replaces double line-breaks with paragraph elements.
   169  *
   177  *
   170  * A group of regex replaces used to identify text formatted with newlines and
   178  * A group of regex replaces used to identify text formatted with newlines and
   171  * replace double line-breaks with HTML paragraph tags. The remaining
   179  * replace double line-breaks with HTML paragraph tags. The remaining
   172  * line-breaks after conversion become <<br />> tags, unless $br is set to '0'
   180  * line-breaks after conversion become <<br />> tags, unless $br is set to '0'
   173  * or 'false'.
   181  * or 'false'.
   174  *
   182  *
   175  * @since 0.71
   183  * @since 0.71
   176  *
   184  *
   177  * @param string $pee The text which has to be formatted.
   185  * @param string $pee The text which has to be formatted.
   178  * @param int|bool $br Optional. If set, this will convert all remaining line-breaks after paragraphing. Default true.
   186  * @param bool $br Optional. If set, this will convert all remaining line-breaks after paragraphing. Default true.
   179  * @return string Text which has been converted into correct paragraph tags.
   187  * @return string Text which has been converted into correct paragraph tags.
   180  */
   188  */
   181 function wpautop($pee, $br = 1) {
   189 function wpautop($pee, $br = true) {
       
   190 	$pre_tags = array();
   182 
   191 
   183 	if ( trim($pee) === '' )
   192 	if ( trim($pee) === '' )
   184 		return '';
   193 		return '';
       
   194 
   185 	$pee = $pee . "\n"; // just to make things a little easier, pad the end
   195 	$pee = $pee . "\n"; // just to make things a little easier, pad the end
       
   196 
       
   197 	if ( strpos($pee, '<pre') !== false ) {
       
   198 		$pee_parts = explode( '</pre>', $pee );
       
   199 		$last_pee = array_pop($pee_parts);
       
   200 		$pee = '';
       
   201 		$i = 0;
       
   202 
       
   203 		foreach ( $pee_parts as $pee_part ) {
       
   204 			$start = strpos($pee_part, '<pre');
       
   205 
       
   206 			// Malformed html?
       
   207 			if ( $start === false ) {
       
   208 				$pee .= $pee_part;
       
   209 				continue;
       
   210 			}
       
   211 
       
   212 			$name = "<pre wp-pre-tag-$i></pre>";
       
   213 			$pre_tags[$name] = substr( $pee_part, $start ) . '</pre>';
       
   214 
       
   215 			$pee .= substr( $pee_part, 0, $start ) . $name;
       
   216 			$i++;
       
   217 		}
       
   218 
       
   219 		$pee .= $last_pee;
       
   220 	}
       
   221 
   186 	$pee = preg_replace('|<br />\s*<br />|', "\n\n", $pee);
   222 	$pee = preg_replace('|<br />\s*<br />|', "\n\n", $pee);
   187 	// Space things out a little
   223 	// Space things out a little
   188 	$allblocks = '(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|map|area|blockquote|address|math|style|input|p|h[1-6]|hr|fieldset|legend)';
   224 	$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)';
   189 	$pee = preg_replace('!(<' . $allblocks . '[^>]*>)!', "\n$1", $pee);
   225 	$pee = preg_replace('!(<' . $allblocks . '[^>]*>)!', "\n$1", $pee);
   190 	$pee = preg_replace('!(</' . $allblocks . '>)!', "$1\n\n", $pee);
   226 	$pee = preg_replace('!(</' . $allblocks . '>)!', "$1\n\n", $pee);
   191 	$pee = str_replace(array("\r\n", "\r"), "\n", $pee); // cross-platform newlines
   227 	$pee = str_replace(array("\r\n", "\r"), "\n", $pee); // cross-platform newlines
   192 	if ( strpos($pee, '<object') !== false ) {
   228 	if ( strpos($pee, '<object') !== false ) {
   193 		$pee = preg_replace('|\s*<param([^>]*)>\s*|', "<param$1>", $pee); // no pee inside object/embed
   229 		$pee = preg_replace('|\s*<param([^>]*)>\s*|', "<param$1>", $pee); // no pee inside object/embed
   205 	$pee = preg_replace("|<p>(<li.+?)</p>|", "$1", $pee); // problem with nested lists
   241 	$pee = preg_replace("|<p>(<li.+?)</p>|", "$1", $pee); // problem with nested lists
   206 	$pee = preg_replace('|<p><blockquote([^>]*)>|i', "<blockquote$1><p>", $pee);
   242 	$pee = preg_replace('|<p><blockquote([^>]*)>|i', "<blockquote$1><p>", $pee);
   207 	$pee = str_replace('</blockquote></p>', '</p></blockquote>', $pee);
   243 	$pee = str_replace('</blockquote></p>', '</p></blockquote>', $pee);
   208 	$pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)!', "$1", $pee);
   244 	$pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)!', "$1", $pee);
   209 	$pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee);
   245 	$pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee);
   210 	if ($br) {
   246 	if ( $br ) {
   211 		$pee = preg_replace_callback('/<(script|style).*?<\/\\1>/s', create_function('$matches', 'return str_replace("\n", "<WPPreserveNewline />", $matches[0]);'), $pee);
   247 		$pee = preg_replace_callback('/<(script|style).*?<\/\\1>/s', '_autop_newline_preservation_helper', $pee);
   212 		$pee = preg_replace('|(?<!<br />)\s*\n|', "<br />\n", $pee); // optionally make line breaks
   248 		$pee = preg_replace('|(?<!<br />)\s*\n|', "<br />\n", $pee); // optionally make line breaks
   213 		$pee = str_replace('<WPPreserveNewline />', "\n", $pee);
   249 		$pee = str_replace('<WPPreserveNewline />', "\n", $pee);
   214 	}
   250 	}
   215 	$pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*<br />!', "$1", $pee);
   251 	$pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*<br />!', "$1", $pee);
   216 	$pee = preg_replace('!<br />(\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)!', '$1', $pee);
   252 	$pee = preg_replace('!<br />(\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)!', '$1', $pee);
   217 	if (strpos($pee, '<pre') !== false)
       
   218 		$pee = preg_replace_callback('!(<pre[^>]*>)(.*?)</pre>!is', 'clean_pre', $pee );
       
   219 	$pee = preg_replace( "|\n</p>$|", '</p>', $pee );
   253 	$pee = preg_replace( "|\n</p>$|", '</p>', $pee );
   220 
   254 
       
   255 	if ( !empty($pre_tags) )
       
   256 		$pee = str_replace(array_keys($pre_tags), array_values($pre_tags), $pee);
       
   257 
   221 	return $pee;
   258 	return $pee;
       
   259 }
       
   260 
       
   261 /**
       
   262  * Newline preservation help function for wpautop
       
   263  *
       
   264  * @since 3.1.0
       
   265  * @access private
       
   266  * @param array $matches preg_replace_callback matches array
       
   267  * @returns string
       
   268  */
       
   269 function _autop_newline_preservation_helper( $matches ) {
       
   270 	return str_replace("\n", "<WPPreserveNewline />", $matches[0]);
   222 }
   271 }
   223 
   272 
   224 /**
   273 /**
   225  * Don't auto-p wrap shortcodes that stand alone
   274  * Don't auto-p wrap shortcodes that stand alone
   226  *
   275  *
   229  * @since 2.9.0
   278  * @since 2.9.0
   230  *
   279  *
   231  * @param string $pee The content.
   280  * @param string $pee The content.
   232  * @return string The filtered content.
   281  * @return string The filtered content.
   233  */
   282  */
   234 function shortcode_unautop($pee) {
   283 function shortcode_unautop( $pee ) {
   235 	global $shortcode_tags;
   284 	global $shortcode_tags;
   236 
   285 
   237 	if ( !empty($shortcode_tags) && is_array($shortcode_tags) ) {
   286 	if ( empty( $shortcode_tags ) || !is_array( $shortcode_tags ) ) {
   238 		$tagnames = array_keys($shortcode_tags);
   287 		return $pee;
   239 		$tagregexp = join( '|', array_map('preg_quote', $tagnames) );
   288 	}
   240 		$pee = preg_replace('/<p>\\s*?(\\[(' . $tagregexp . ')\\b.*?\\/?\\](?:.+?\\[\\/\\2\\])?)\\s*<\\/p>/s', '$1', $pee);
   289 
   241 	}
   290 	$tagregexp = join( '|', array_map( 'preg_quote', array_keys( $shortcode_tags ) ) );
   242 
   291 
   243 	return $pee;
   292 	$pattern =
       
   293 		  '/'
       
   294 		. '<p>'                              // Opening paragraph
       
   295 		. '\\s*+'                            // Optional leading whitespace
       
   296 		. '('                                // 1: The shortcode
       
   297 		.     '\\['                          // Opening bracket
       
   298 		.     "($tagregexp)"                 // 2: Shortcode name
       
   299 		.     '\\b'                          // Word boundary
       
   300 		                                     // Unroll the loop: Inside the opening shortcode tag
       
   301 		.     '[^\\]\\/]*'                   // Not a closing bracket or forward slash
       
   302 		.     '(?:'
       
   303 		.         '\\/(?!\\])'               // A forward slash not followed by a closing bracket
       
   304 		.         '[^\\]\\/]*'               // Not a closing bracket or forward slash
       
   305 		.     ')*?'
       
   306 		.     '(?:'
       
   307 		.         '\\/\\]'                   // Self closing tag and closing bracket
       
   308 		.     '|'
       
   309 		.         '\\]'                      // Closing bracket
       
   310 		.         '(?:'                      // Unroll the loop: Optionally, anything between the opening and closing shortcode tags
       
   311 		.             '[^\\[]*+'             // Not an opening bracket
       
   312 		.             '(?:'
       
   313 		.                 '\\[(?!\\/\\2\\])' // An opening bracket not followed by the closing shortcode tag
       
   314 		.                 '[^\\[]*+'         // Not an opening bracket
       
   315 		.             ')*+'
       
   316 		.             '\\[\\/\\2\\]'         // Closing shortcode tag
       
   317 		.         ')?'
       
   318 		.     ')'
       
   319 		. ')'
       
   320 		. '\\s*+'                            // optional trailing whitespace
       
   321 		. '<\\/p>'                           // closing paragraph
       
   322 		. '/s';
       
   323 
       
   324 	return preg_replace( $pattern, '$1', $pee );
   244 }
   325 }
   245 
   326 
   246 /**
   327 /**
   247  * Checks to see if a string is utf8 encoded.
   328  * Checks to see if a string is utf8 encoded.
   248  *
   329  *
   285  * @since 1.2.2
   366  * @since 1.2.2
   286  *
   367  *
   287  * @param string $string The text which is to be encoded.
   368  * @param string $string The text which is to be encoded.
   288  * @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.
   369  * @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.
   289  * @param string $charset Optional. The character encoding of the string. Default is false.
   370  * @param string $charset Optional. The character encoding of the string. Default is false.
   290  * @param boolean $double_encode Optional. Whether or not to encode existing html entities. Default is false.
   371  * @param boolean $double_encode Optional. Whether to encode existing html entities. Default is false.
   291  * @return string The encoded text with HTML entities.
   372  * @return string The encoded text with HTML entities.
   292  */
   373  */
   293 function _wp_specialchars( $string, $quote_style = ENT_NOQUOTES, $charset = false, $double_encode = false ) {
   374 function _wp_specialchars( $string, $quote_style = ENT_NOQUOTES, $charset = false, $double_encode = false ) {
   294 	$string = (string) $string;
   375 	$string = (string) $string;
   295 
   376 
   296 	if ( 0 === strlen( $string ) ) {
   377 	if ( 0 === strlen( $string ) )
   297 		return '';
   378 		return '';
   298 	}
       
   299 
   379 
   300 	// Don't bother if there are no specialchars - saves some processing
   380 	// Don't bother if there are no specialchars - saves some processing
   301 	if ( !preg_match( '/[&<>"\']/', $string ) ) {
   381 	if ( ! preg_match( '/[&<>"\']/', $string ) )
   302 		return $string;
   382 		return $string;
   303 	}
       
   304 
   383 
   305 	// Account for the previous behaviour of the function when the $quote_style is not an accepted value
   384 	// Account for the previous behaviour of the function when the $quote_style is not an accepted value
   306 	if ( empty( $quote_style ) ) {
   385 	if ( empty( $quote_style ) )
   307 		$quote_style = ENT_NOQUOTES;
   386 		$quote_style = ENT_NOQUOTES;
   308 	} elseif ( !in_array( $quote_style, array( 0, 2, 3, 'single', 'double' ), true ) ) {
   387 	elseif ( ! in_array( $quote_style, array( 0, 2, 3, 'single', 'double' ), true ) )
   309 		$quote_style = ENT_QUOTES;
   388 		$quote_style = ENT_QUOTES;
   310 	}
       
   311 
   389 
   312 	// Store the site charset as a static to avoid multiple calls to wp_load_alloptions()
   390 	// Store the site charset as a static to avoid multiple calls to wp_load_alloptions()
   313 	if ( !$charset ) {
   391 	if ( ! $charset ) {
   314 		static $_charset;
   392 		static $_charset;
   315 		if ( !isset( $_charset ) ) {
   393 		if ( ! isset( $_charset ) ) {
   316 			$alloptions = wp_load_alloptions();
   394 			$alloptions = wp_load_alloptions();
   317 			$_charset = isset( $alloptions['blog_charset'] ) ? $alloptions['blog_charset'] : '';
   395 			$_charset = isset( $alloptions['blog_charset'] ) ? $alloptions['blog_charset'] : '';
   318 		}
   396 		}
   319 		$charset = $_charset;
   397 		$charset = $_charset;
   320 	}
   398 	}
   321 	if ( in_array( $charset, array( 'utf8', 'utf-8', 'UTF8' ) ) ) {
   399 
       
   400 	if ( in_array( $charset, array( 'utf8', 'utf-8', 'UTF8' ) ) )
   322 		$charset = 'UTF-8';
   401 		$charset = 'UTF-8';
   323 	}
       
   324 
   402 
   325 	$_quote_style = $quote_style;
   403 	$_quote_style = $quote_style;
   326 
   404 
   327 	if ( $quote_style === 'double' ) {
   405 	if ( $quote_style === 'double' ) {
   328 		$quote_style = ENT_COMPAT;
   406 		$quote_style = ENT_COMPAT;
   330 	} elseif ( $quote_style === 'single' ) {
   408 	} elseif ( $quote_style === 'single' ) {
   331 		$quote_style = ENT_NOQUOTES;
   409 		$quote_style = ENT_NOQUOTES;
   332 	}
   410 	}
   333 
   411 
   334 	// Handle double encoding ourselves
   412 	// Handle double encoding ourselves
   335 	if ( !$double_encode ) {
   413 	if ( $double_encode ) {
       
   414 		$string = @htmlspecialchars( $string, $quote_style, $charset );
       
   415 	} else {
       
   416 		// Decode &amp; into &
   336 		$string = wp_specialchars_decode( $string, $_quote_style );
   417 		$string = wp_specialchars_decode( $string, $_quote_style );
   337 		$string = preg_replace( '/&(#?x?[0-9a-z]+);/i', '|wp_entity|$1|/wp_entity|', $string );
   418 
   338 	}
   419 		// Guarantee every &entity; is valid or re-encode the &
   339 
   420 		$string = wp_kses_normalize_entities( $string );
   340 	$string = @htmlspecialchars( $string, $quote_style, $charset );
   421 
   341 
   422 		// Now re-encode everything except &entity;
   342 	// Handle double encoding ourselves
   423 		$string = preg_split( '/(&#?x?[0-9a-z]+;)/i', $string, -1, PREG_SPLIT_DELIM_CAPTURE );
   343 	if ( !$double_encode ) {
   424 
   344 		$string = str_replace( array( '|wp_entity|', '|/wp_entity|' ), array( '&', ';' ), $string );
   425 		for ( $i = 0; $i < count( $string ); $i += 2 )
       
   426 			$string[$i] = @htmlspecialchars( $string[$i], $quote_style, $charset );
       
   427 
       
   428 		$string = implode( '', $string );
   345 	}
   429 	}
   346 
   430 
   347 	// Backwards compatibility
   431 	// Backwards compatibility
   348 	if ( 'single' === $_quote_style ) {
   432 	if ( 'single' === $_quote_style )
   349 		$string = str_replace( "'", '&#039;', $string );
   433 		$string = str_replace( "'", '&#039;', $string );
   350 	}
       
   351 
   434 
   352 	return $string;
   435 	return $string;
   353 }
   436 }
   354 
   437 
   355 /**
   438 /**
   527 		return $string;
   610 		return $string;
   528 
   611 
   529 	if (seems_utf8($string)) {
   612 	if (seems_utf8($string)) {
   530 		$chars = array(
   613 		$chars = array(
   531 		// Decompositions for Latin-1 Supplement
   614 		// Decompositions for Latin-1 Supplement
       
   615 		chr(194).chr(170) => 'a', chr(194).chr(186) => 'o',
   532 		chr(195).chr(128) => 'A', chr(195).chr(129) => 'A',
   616 		chr(195).chr(128) => 'A', chr(195).chr(129) => 'A',
   533 		chr(195).chr(130) => 'A', chr(195).chr(131) => 'A',
   617 		chr(195).chr(130) => 'A', chr(195).chr(131) => 'A',
   534 		chr(195).chr(132) => 'A', chr(195).chr(133) => 'A',
   618 		chr(195).chr(132) => 'A', chr(195).chr(133) => 'A',
   535 		chr(195).chr(135) => 'C', chr(195).chr(136) => 'E',
   619 		chr(195).chr(134) => 'AE',chr(195).chr(135) => 'C',
   536 		chr(195).chr(137) => 'E', chr(195).chr(138) => 'E',
   620 		chr(195).chr(136) => 'E', chr(195).chr(137) => 'E',
   537 		chr(195).chr(139) => 'E', chr(195).chr(140) => 'I',
   621 		chr(195).chr(138) => 'E', chr(195).chr(139) => 'E',
   538 		chr(195).chr(141) => 'I', chr(195).chr(142) => 'I',
   622 		chr(195).chr(140) => 'I', chr(195).chr(141) => 'I',
   539 		chr(195).chr(143) => 'I', chr(195).chr(145) => 'N',
   623 		chr(195).chr(142) => 'I', chr(195).chr(143) => 'I',
       
   624 		chr(195).chr(144) => 'D', chr(195).chr(145) => 'N',
   540 		chr(195).chr(146) => 'O', chr(195).chr(147) => 'O',
   625 		chr(195).chr(146) => 'O', chr(195).chr(147) => 'O',
   541 		chr(195).chr(148) => 'O', chr(195).chr(149) => 'O',
   626 		chr(195).chr(148) => 'O', chr(195).chr(149) => 'O',
   542 		chr(195).chr(150) => 'O', chr(195).chr(153) => 'U',
   627 		chr(195).chr(150) => 'O', chr(195).chr(153) => 'U',
   543 		chr(195).chr(154) => 'U', chr(195).chr(155) => 'U',
   628 		chr(195).chr(154) => 'U', chr(195).chr(155) => 'U',
   544 		chr(195).chr(156) => 'U', chr(195).chr(157) => 'Y',
   629 		chr(195).chr(156) => 'U', chr(195).chr(157) => 'Y',
   545 		chr(195).chr(159) => 's', chr(195).chr(160) => 'a',
   630 		chr(195).chr(158) => 'TH',chr(195).chr(159) => 's',
   546 		chr(195).chr(161) => 'a', chr(195).chr(162) => 'a',
   631 		chr(195).chr(160) => 'a', chr(195).chr(161) => 'a',
   547 		chr(195).chr(163) => 'a', chr(195).chr(164) => 'a',
   632 		chr(195).chr(162) => 'a', chr(195).chr(163) => 'a',
   548 		chr(195).chr(165) => 'a', chr(195).chr(167) => 'c',
   633 		chr(195).chr(164) => 'a', chr(195).chr(165) => 'a',
       
   634 		chr(195).chr(166) => 'ae',chr(195).chr(167) => 'c',
   549 		chr(195).chr(168) => 'e', chr(195).chr(169) => 'e',
   635 		chr(195).chr(168) => 'e', chr(195).chr(169) => 'e',
   550 		chr(195).chr(170) => 'e', chr(195).chr(171) => 'e',
   636 		chr(195).chr(170) => 'e', chr(195).chr(171) => 'e',
   551 		chr(195).chr(172) => 'i', chr(195).chr(173) => 'i',
   637 		chr(195).chr(172) => 'i', chr(195).chr(173) => 'i',
   552 		chr(195).chr(174) => 'i', chr(195).chr(175) => 'i',
   638 		chr(195).chr(174) => 'i', chr(195).chr(175) => 'i',
   553 		chr(195).chr(177) => 'n', chr(195).chr(178) => 'o',
   639 		chr(195).chr(176) => 'd', chr(195).chr(177) => 'n',
   554 		chr(195).chr(179) => 'o', chr(195).chr(180) => 'o',
   640 		chr(195).chr(178) => 'o', chr(195).chr(179) => 'o',
   555 		chr(195).chr(181) => 'o', chr(195).chr(182) => 'o',
   641 		chr(195).chr(180) => 'o', chr(195).chr(181) => 'o',
   556 		chr(195).chr(182) => 'o', chr(195).chr(185) => 'u',
   642 		chr(195).chr(182) => 'o', chr(195).chr(184) => 'o',
   557 		chr(195).chr(186) => 'u', chr(195).chr(187) => 'u',
   643 		chr(195).chr(185) => 'u', chr(195).chr(186) => 'u',
   558 		chr(195).chr(188) => 'u', chr(195).chr(189) => 'y',
   644 		chr(195).chr(187) => 'u', chr(195).chr(188) => 'u',
   559 		chr(195).chr(191) => 'y',
   645 		chr(195).chr(189) => 'y', chr(195).chr(190) => 'th',
       
   646 		chr(195).chr(191) => 'y', chr(195).chr(152) => 'O',
   560 		// Decompositions for Latin Extended-A
   647 		// Decompositions for Latin Extended-A
   561 		chr(196).chr(128) => 'A', chr(196).chr(129) => 'a',
   648 		chr(196).chr(128) => 'A', chr(196).chr(129) => 'a',
   562 		chr(196).chr(130) => 'A', chr(196).chr(131) => 'a',
   649 		chr(196).chr(130) => 'A', chr(196).chr(131) => 'a',
   563 		chr(196).chr(132) => 'A', chr(196).chr(133) => 'a',
   650 		chr(196).chr(132) => 'A', chr(196).chr(133) => 'a',
   564 		chr(196).chr(134) => 'C', chr(196).chr(135) => 'c',
   651 		chr(196).chr(134) => 'C', chr(196).chr(135) => 'c',
   620 		chr(197).chr(182) => 'Y', chr(197).chr(183) => 'y',
   707 		chr(197).chr(182) => 'Y', chr(197).chr(183) => 'y',
   621 		chr(197).chr(184) => 'Y', chr(197).chr(185) => 'Z',
   708 		chr(197).chr(184) => 'Y', chr(197).chr(185) => 'Z',
   622 		chr(197).chr(186) => 'z', chr(197).chr(187) => 'Z',
   709 		chr(197).chr(186) => 'z', chr(197).chr(187) => 'Z',
   623 		chr(197).chr(188) => 'z', chr(197).chr(189) => 'Z',
   710 		chr(197).chr(188) => 'z', chr(197).chr(189) => 'Z',
   624 		chr(197).chr(190) => 'z', chr(197).chr(191) => 's',
   711 		chr(197).chr(190) => 'z', chr(197).chr(191) => 's',
       
   712 		// Decompositions for Latin Extended-B
       
   713 		chr(200).chr(152) => 'S', chr(200).chr(153) => 's',
       
   714 		chr(200).chr(154) => 'T', chr(200).chr(155) => 't',
   625 		// Euro Sign
   715 		// Euro Sign
   626 		chr(226).chr(130).chr(172) => 'E',
   716 		chr(226).chr(130).chr(172) => 'E',
   627 		// GBP (Pound) Sign
   717 		// GBP (Pound) Sign
   628 		chr(194).chr(163) => '');
   718 		chr(194).chr(163) => '',
       
   719 		// Vowels with diacritic (Vietnamese)
       
   720 		// unmarked
       
   721 		chr(198).chr(160) => 'O', chr(198).chr(161) => 'o',
       
   722 		chr(198).chr(175) => 'U', chr(198).chr(176) => 'u',
       
   723 		// grave accent
       
   724 		chr(225).chr(186).chr(166) => 'A', chr(225).chr(186).chr(167) => 'a',
       
   725 		chr(225).chr(186).chr(176) => 'A', chr(225).chr(186).chr(177) => 'a',
       
   726 		chr(225).chr(187).chr(128) => 'E', chr(225).chr(187).chr(129) => 'e',
       
   727 		chr(225).chr(187).chr(146) => 'O', chr(225).chr(187).chr(147) => 'o',
       
   728 		chr(225).chr(187).chr(156) => 'O', chr(225).chr(187).chr(157) => 'o',
       
   729 		chr(225).chr(187).chr(170) => 'U', chr(225).chr(187).chr(171) => 'u',
       
   730 		chr(225).chr(187).chr(178) => 'Y', chr(225).chr(187).chr(179) => 'y',
       
   731 		// hook
       
   732 		chr(225).chr(186).chr(162) => 'A', chr(225).chr(186).chr(163) => 'a',
       
   733 		chr(225).chr(186).chr(168) => 'A', chr(225).chr(186).chr(169) => 'a',
       
   734 		chr(225).chr(186).chr(178) => 'A', chr(225).chr(186).chr(179) => 'a',
       
   735 		chr(225).chr(186).chr(186) => 'E', chr(225).chr(186).chr(187) => 'e',
       
   736 		chr(225).chr(187).chr(130) => 'E', chr(225).chr(187).chr(131) => 'e',
       
   737 		chr(225).chr(187).chr(136) => 'I', chr(225).chr(187).chr(137) => 'i',
       
   738 		chr(225).chr(187).chr(142) => 'O', chr(225).chr(187).chr(143) => 'o',
       
   739 		chr(225).chr(187).chr(148) => 'O', chr(225).chr(187).chr(149) => 'o',
       
   740 		chr(225).chr(187).chr(158) => 'O', chr(225).chr(187).chr(159) => 'o',
       
   741 		chr(225).chr(187).chr(166) => 'U', chr(225).chr(187).chr(167) => 'u',
       
   742 		chr(225).chr(187).chr(172) => 'U', chr(225).chr(187).chr(173) => 'u',
       
   743 		chr(225).chr(187).chr(182) => 'Y', chr(225).chr(187).chr(183) => 'y',
       
   744 		// tilde
       
   745 		chr(225).chr(186).chr(170) => 'A', chr(225).chr(186).chr(171) => 'a',
       
   746 		chr(225).chr(186).chr(180) => 'A', chr(225).chr(186).chr(181) => 'a',
       
   747 		chr(225).chr(186).chr(188) => 'E', chr(225).chr(186).chr(189) => 'e',
       
   748 		chr(225).chr(187).chr(132) => 'E', chr(225).chr(187).chr(133) => 'e',
       
   749 		chr(225).chr(187).chr(150) => 'O', chr(225).chr(187).chr(151) => 'o',
       
   750 		chr(225).chr(187).chr(160) => 'O', chr(225).chr(187).chr(161) => 'o',
       
   751 		chr(225).chr(187).chr(174) => 'U', chr(225).chr(187).chr(175) => 'u',
       
   752 		chr(225).chr(187).chr(184) => 'Y', chr(225).chr(187).chr(185) => 'y',
       
   753 		// acute accent
       
   754 		chr(225).chr(186).chr(164) => 'A', chr(225).chr(186).chr(165) => 'a',
       
   755 		chr(225).chr(186).chr(174) => 'A', chr(225).chr(186).chr(175) => 'a',
       
   756 		chr(225).chr(186).chr(190) => 'E', chr(225).chr(186).chr(191) => 'e',
       
   757 		chr(225).chr(187).chr(144) => 'O', chr(225).chr(187).chr(145) => 'o',
       
   758 		chr(225).chr(187).chr(154) => 'O', chr(225).chr(187).chr(155) => 'o',
       
   759 		chr(225).chr(187).chr(168) => 'U', chr(225).chr(187).chr(169) => 'u',
       
   760 		// dot below
       
   761 		chr(225).chr(186).chr(160) => 'A', chr(225).chr(186).chr(161) => 'a',
       
   762 		chr(225).chr(186).chr(172) => 'A', chr(225).chr(186).chr(173) => 'a',
       
   763 		chr(225).chr(186).chr(182) => 'A', chr(225).chr(186).chr(183) => 'a',
       
   764 		chr(225).chr(186).chr(184) => 'E', chr(225).chr(186).chr(185) => 'e',
       
   765 		chr(225).chr(187).chr(134) => 'E', chr(225).chr(187).chr(135) => 'e',
       
   766 		chr(225).chr(187).chr(138) => 'I', chr(225).chr(187).chr(139) => 'i',
       
   767 		chr(225).chr(187).chr(140) => 'O', chr(225).chr(187).chr(141) => 'o',
       
   768 		chr(225).chr(187).chr(152) => 'O', chr(225).chr(187).chr(153) => 'o',
       
   769 		chr(225).chr(187).chr(162) => 'O', chr(225).chr(187).chr(163) => 'o',
       
   770 		chr(225).chr(187).chr(164) => 'U', chr(225).chr(187).chr(165) => 'u',
       
   771 		chr(225).chr(187).chr(176) => 'U', chr(225).chr(187).chr(177) => 'u',
       
   772 		chr(225).chr(187).chr(180) => 'Y', chr(225).chr(187).chr(181) => 'y',
       
   773 		);
   629 
   774 
   630 		$string = strtr($string, $chars);
   775 		$string = strtr($string, $chars);
   631 	} else {
   776 	} else {
   632 		// Assume ISO-8859-1 if not UTF-8
   777 		// Assume ISO-8859-1 if not UTF-8
   633 		$chars['in'] = chr(128).chr(131).chr(138).chr(142).chr(154).chr(158)
   778 		$chars['in'] = chr(128).chr(131).chr(138).chr(142).chr(154).chr(158)
   684 	// Process multiple extensions
   829 	// Process multiple extensions
   685 	$filename = array_shift($parts);
   830 	$filename = array_shift($parts);
   686 	$extension = array_pop($parts);
   831 	$extension = array_pop($parts);
   687 	$mimes = get_allowed_mime_types();
   832 	$mimes = get_allowed_mime_types();
   688 
   833 
   689 	// Loop over any intermediate extensions.  Munge them with a trailing underscore if they are a 2 - 5 character
   834 	// Loop over any intermediate extensions. Munge them with a trailing underscore if they are a 2 - 5 character
   690 	// long alpha string not in the extension whitelist.
   835 	// long alpha string not in the extension whitelist.
   691 	foreach ( (array) $parts as $part) {
   836 	foreach ( (array) $parts as $part) {
   692 		$filename .= '.' . $part;
   837 		$filename .= '.' . $part;
   693 		
   838 
   694 		if ( preg_match("/^[a-zA-Z]{2,5}\d?$/", $part) ) {
   839 		if ( preg_match("/^[a-zA-Z]{2,5}\d?$/", $part) ) {
   695 			$allowed = false;
   840 			$allowed = false;
   696 			foreach ( $mimes as $ext_preg => $mime_match ) {
   841 			foreach ( $mimes as $ext_preg => $mime_match ) {
   697 				$ext_preg = '!(^' . $ext_preg . ')$!i';
   842 				$ext_preg = '!^(' . $ext_preg . ')$!i';
   698 				if ( preg_match( $ext_preg, $part ) ) {
   843 				if ( preg_match( $ext_preg, $part ) ) {
   699 					$allowed = true;
   844 					$allowed = true;
   700 					break;
   845 					break;
   701 				}
   846 				}
   702 			}
   847 			}
   710 }
   855 }
   711 
   856 
   712 /**
   857 /**
   713  * Sanitize username stripping out unsafe characters.
   858  * Sanitize username stripping out unsafe characters.
   714  *
   859  *
   715  * If $strict is true, only alphanumeric characters (as well as _, space, ., -,
   860  * Removes tags, octets, entities, and if strict is enabled, will only keep
   716  * @) are returned.
   861  * alphanumeric, _, space, ., -, @. After sanitizing, it passes the username,
   717  * Removes tags, octets, entities, and if strict is enabled, will remove all
   862  * raw username (the username in the parameter), and the value of $strict as
   718  * non-ASCII characters. After sanitizing, it passes the username, raw username
   863  * parameters for the 'sanitize_user' filter.
   719  * (the username in the parameter), and the strict parameter as parameters for
       
   720  * the filter.
       
   721  *
   864  *
   722  * @since 2.0.0
   865  * @since 2.0.0
   723  * @uses apply_filters() Calls 'sanitize_user' hook on username, raw username,
   866  * @uses apply_filters() Calls 'sanitize_user' hook on username, raw username,
   724  *		and $strict parameter.
   867  *		and $strict parameter.
   725  *
   868  *
   727  * @param bool $strict If set limits $username to specific characters. Default false.
   870  * @param bool $strict If set limits $username to specific characters. Default false.
   728  * @return string The sanitized username, after passing through filters.
   871  * @return string The sanitized username, after passing through filters.
   729  */
   872  */
   730 function sanitize_user( $username, $strict = false ) {
   873 function sanitize_user( $username, $strict = false ) {
   731 	$raw_username = $username;
   874 	$raw_username = $username;
   732 	$username = wp_strip_all_tags($username);
   875 	$username = wp_strip_all_tags( $username );
       
   876 	$username = remove_accents( $username );
   733 	// Kill octets
   877 	// Kill octets
   734 	$username = preg_replace('|%([a-fA-F0-9][a-fA-F0-9])|', '', $username);
   878 	$username = preg_replace( '|%([a-fA-F0-9][a-fA-F0-9])|', '', $username );
   735 	$username = preg_replace('/&.+?;/', '', $username); // Kill entities
   879 	$username = preg_replace( '/&.+?;/', '', $username ); // Kill entities
   736 
   880 
   737 	// If strict, reduce to ASCII for max portability.
   881 	// If strict, reduce to ASCII for max portability.
   738 	if ( $strict )
   882 	if ( $strict )
   739 		$username = preg_replace('|[^a-z0-9 _.\-@]|i', '', $username);
   883 		$username = preg_replace( '|[^a-z0-9 _.\-@]|i', '', $username );
   740 
   884 
       
   885 	$username = trim( $username );
   741 	// Consolidate contiguous whitespace
   886 	// Consolidate contiguous whitespace
   742 	$username = preg_replace('|\s+|', ' ', $username);
   887 	$username = preg_replace( '|\s+|', ' ', $username );
   743 
   888 
   744 	return apply_filters('sanitize_user', $username, $raw_username, $strict);
   889 	return apply_filters( 'sanitize_user', $username, $raw_username, $strict );
       
   890 }
       
   891 
       
   892 /**
       
   893  * Sanitize a string key.
       
   894  *
       
   895  * Keys are used as internal identifiers. Lowercase alphanumeric characters, dashes and underscores are allowed.
       
   896  *
       
   897  * @since 3.0.0
       
   898  *
       
   899  * @param string $key String key
       
   900  * @return string Sanitized key
       
   901  */
       
   902 function sanitize_key( $key ) {
       
   903 	$raw_key = $key;
       
   904 	$key = strtolower( $key );
       
   905 	$key = preg_replace( '/[^a-z0-9_\-]/', '', $key );
       
   906 	return apply_filters( 'sanitize_key', $key, $raw_key );
   745 }
   907 }
   746 
   908 
   747 /**
   909 /**
   748  * Sanitizes title or use fallback title.
   910  * Sanitizes title or use fallback title.
   749  *
   911  *
   753  *
   915  *
   754  * @since 1.0.0
   916  * @since 1.0.0
   755  *
   917  *
   756  * @param string $title The string to be sanitized.
   918  * @param string $title The string to be sanitized.
   757  * @param string $fallback_title Optional. A title to use if $title is empty.
   919  * @param string $fallback_title Optional. A title to use if $title is empty.
       
   920  * @param string $context Optional. The operation for which the string is sanitized
   758  * @return string The sanitized string.
   921  * @return string The sanitized string.
   759  */
   922  */
   760 function sanitize_title($title, $fallback_title = '') {
   923 function sanitize_title($title, $fallback_title = '', $context = 'save') {
   761 	$raw_title = $title;
   924 	$raw_title = $title;
   762 	$title = strip_tags($title);
   925 
   763 	$title = apply_filters('sanitize_title', $title, $raw_title);
   926 	if ( 'save' == $context )
       
   927 		$title = remove_accents($title);
       
   928 
       
   929 	$title = apply_filters('sanitize_title', $title, $raw_title, $context);
   764 
   930 
   765 	if ( '' === $title || false === $title )
   931 	if ( '' === $title || false === $title )
   766 		$title = $fallback_title;
   932 		$title = $fallback_title;
   767 
   933 
   768 	return $title;
   934 	return $title;
   769 }
   935 }
   770 
   936 
   771 /**
   937 function sanitize_title_for_query($title) {
   772  * Sanitizes title, replacing whitespace with dashes.
   938 	return sanitize_title($title, '', 'query');
       
   939 }
       
   940 
       
   941 /**
       
   942  * Sanitizes title, replacing whitespace and a few other characters with dashes.
   773  *
   943  *
   774  * Limits the output to alphanumeric characters, underscore (_) and dash (-).
   944  * Limits the output to alphanumeric characters, underscore (_) and dash (-).
   775  * Whitespace becomes a dash.
   945  * Whitespace becomes a dash.
   776  *
   946  *
   777  * @since 1.2.0
   947  * @since 1.2.0
   778  *
   948  *
   779  * @param string $title The title to be sanitized.
   949  * @param string $title The title to be sanitized.
       
   950  * @param string $raw_title Optional. Not used.
       
   951  * @param string $context Optional. The operation for which the string is sanitized.
   780  * @return string The sanitized title.
   952  * @return string The sanitized title.
   781  */
   953  */
   782 function sanitize_title_with_dashes($title) {
   954 function sanitize_title_with_dashes($title, $raw_title = '', $context = 'display') {
   783 	$title = strip_tags($title);
   955 	$title = strip_tags($title);
   784 	// Preserve escaped octets.
   956 	// Preserve escaped octets.
   785 	$title = preg_replace('|%([a-fA-F0-9][a-fA-F0-9])|', '---$1---', $title);
   957 	$title = preg_replace('|%([a-fA-F0-9][a-fA-F0-9])|', '---$1---', $title);
   786 	// Remove percent signs that are not part of an octet.
   958 	// Remove percent signs that are not part of an octet.
   787 	$title = str_replace('%', '', $title);
   959 	$title = str_replace('%', '', $title);
   788 	// Restore octets.
   960 	// Restore octets.
   789 	$title = preg_replace('|---([a-fA-F0-9][a-fA-F0-9])---|', '%$1', $title);
   961 	$title = preg_replace('|---([a-fA-F0-9][a-fA-F0-9])---|', '%$1', $title);
   790 
   962 
   791 	$title = remove_accents($title);
       
   792 	if (seems_utf8($title)) {
   963 	if (seems_utf8($title)) {
   793 		if (function_exists('mb_strtolower')) {
   964 		if (function_exists('mb_strtolower')) {
   794 			$title = mb_strtolower($title, 'UTF-8');
   965 			$title = mb_strtolower($title, 'UTF-8');
   795 		}
   966 		}
   796 		$title = utf8_uri_encode($title, 200);
   967 		$title = utf8_uri_encode($title, 200);
   797 	}
   968 	}
   798 
   969 
   799 	$title = strtolower($title);
   970 	$title = strtolower($title);
   800 	$title = preg_replace('/&.+?;/', '', $title); // kill entities
   971 	$title = preg_replace('/&.+?;/', '', $title); // kill entities
   801 	$title = str_replace('.', '-', $title);
   972 	$title = str_replace('.', '-', $title);
       
   973 
       
   974 	if ( 'save' == $context ) {
       
   975 		// Convert nbsp, ndash and mdash to hyphens
       
   976 		$title = str_replace( array( '%c2%a0', '%e2%80%93', '%e2%80%94' ), '-', $title );
       
   977 
       
   978 		// Strip these characters entirely
       
   979 		$title = str_replace( array(
       
   980 			// iexcl and iquest
       
   981 			'%c2%a1', '%c2%bf',
       
   982 			// angle quotes
       
   983 			'%c2%ab', '%c2%bb', '%e2%80%b9', '%e2%80%ba',
       
   984 			// curly quotes
       
   985 			'%e2%80%98', '%e2%80%99', '%e2%80%9c', '%e2%80%9d',
       
   986 			'%e2%80%9a', '%e2%80%9b', '%e2%80%9e', '%e2%80%9f',
       
   987 			// copy, reg, deg, hellip and trade
       
   988 			'%c2%a9', '%c2%ae', '%c2%b0', '%e2%80%a6', '%e2%84%a2',
       
   989 		), '', $title );
       
   990 
       
   991 		// Convert times to x
       
   992 		$title = str_replace( '%c3%97', 'x', $title );
       
   993 	}
       
   994 
   802 	$title = preg_replace('/[^%a-z0-9 _-]/', '', $title);
   995 	$title = preg_replace('/[^%a-z0-9 _-]/', '', $title);
   803 	$title = preg_replace('/\s+/', '-', $title);
   996 	$title = preg_replace('/\s+/', '-', $title);
   804 	$title = preg_replace('|-+|', '-', $title);
   997 	$title = preg_replace('|-+|', '-', $title);
   805 	$title = trim($title, '-');
   998 	$title = trim($title, '-');
   806 
   999 
   826 }
  1019 }
   827 
  1020 
   828 /**
  1021 /**
   829  * Santizes a html classname to ensure it only contains valid characters
  1022  * Santizes a html classname to ensure it only contains valid characters
   830  *
  1023  *
   831  * Strips the string down to A-Z,a-z,0-9,'-' if this results in an empty
  1024  * Strips the string down to A-Z,a-z,0-9,_,-. If this results in an empty
   832  * string then it will return the alternative value supplied.
  1025  * string then it will return the alternative value supplied.
   833  *
  1026  *
   834  * @todo Expand to support the full range of CDATA that a class attribute can contain.
  1027  * @todo Expand to support the full range of CDATA that a class attribute can contain.
   835  *
  1028  *
   836  * @since 2.8.0
  1029  * @since 2.8.0
   837  *
  1030  *
   838  * @param string $class The classname to be sanitized
  1031  * @param string $class The classname to be sanitized
   839  * @param string $fallback The value to return if the sanitization end's up as an empty string.
  1032  * @param string $fallback Optional. The value to return if the sanitization end's up as an empty string.
       
  1033  * 	Defaults to an empty string.
   840  * @return string The sanitized value
  1034  * @return string The sanitized value
   841  */
  1035  */
   842 function sanitize_html_class($class, $fallback){
  1036 function sanitize_html_class( $class, $fallback = '' ) {
   843 	//Strip out any % encoded octets
  1037 	//Strip out any % encoded octets
   844 	$sanitized = preg_replace('|%[a-fA-F0-9][a-fA-F0-9]|', '', $class);
  1038 	$sanitized = preg_replace( '|%[a-fA-F0-9][a-fA-F0-9]|', '', $class );
   845 
  1039 
   846 	//Limit to A-Z,a-z,0-9,'-'
  1040 	//Limit to A-Z,a-z,0-9,_,-
   847 	$sanitized = preg_replace('/[^A-Za-z0-9-]/', '', $sanitized);
  1041 	$sanitized = preg_replace( '/[^A-Za-z0-9_-]/', '', $sanitized );
   848 
  1042 
   849 	if ('' == $sanitized)
  1043 	if ( '' == $sanitized )
   850 		$sanitized = $fallback;
  1044 		$sanitized = $fallback;
   851 
  1045 
   852 	return apply_filters('sanitize_html_class',$sanitized, $class, $fallback);
  1046 	return apply_filters( 'sanitize_html_class', $sanitized, $class, $fallback );
   853 }
  1047 }
   854 
  1048 
   855 /**
  1049 /**
   856  * Converts a number of characters from a string.
  1050  * Converts a number of characters from a string.
   857  *
  1051  *
   864  * @param string $content String of characters to be converted.
  1058  * @param string $content String of characters to be converted.
   865  * @param string $deprecated Not used.
  1059  * @param string $deprecated Not used.
   866  * @return string Converted string.
  1060  * @return string Converted string.
   867  */
  1061  */
   868 function convert_chars($content, $deprecated = '') {
  1062 function convert_chars($content, $deprecated = '') {
       
  1063 	if ( !empty( $deprecated ) )
       
  1064 		_deprecated_argument( __FUNCTION__, '0.71' );
       
  1065 
   869 	// Translation of invalid Unicode references range to valid range
  1066 	// Translation of invalid Unicode references range to valid range
   870 	$wp_htmltranswinuni = array(
  1067 	$wp_htmltranswinuni = array(
   871 	'&#128;' => '&#8364;', // the Euro sign
  1068 	'&#128;' => '&#8364;', // the Euro sign
   872 	'&#129;' => '',
  1069 	'&#129;' => '',
   873 	'&#130;' => '&#8218;', // these are Windows CP1252 specific characters
  1070 	'&#130;' => '&#8218;', // these are Windows CP1252 specific characters
   880 	'&#137;' => '&#8240;',
  1077 	'&#137;' => '&#8240;',
   881 	'&#138;' => '&#352;',
  1078 	'&#138;' => '&#352;',
   882 	'&#139;' => '&#8249;',
  1079 	'&#139;' => '&#8249;',
   883 	'&#140;' => '&#338;',
  1080 	'&#140;' => '&#338;',
   884 	'&#141;' => '',
  1081 	'&#141;' => '',
   885 	'&#142;' => '&#382;',
  1082 	'&#142;' => '&#381;',
   886 	'&#143;' => '',
  1083 	'&#143;' => '',
   887 	'&#144;' => '',
  1084 	'&#144;' => '',
   888 	'&#145;' => '&#8216;',
  1085 	'&#145;' => '&#8216;',
   889 	'&#146;' => '&#8217;',
  1086 	'&#146;' => '&#8217;',
   890 	'&#147;' => '&#8220;',
  1087 	'&#147;' => '&#8220;',
   896 	'&#153;' => '&#8482;',
  1093 	'&#153;' => '&#8482;',
   897 	'&#154;' => '&#353;',
  1094 	'&#154;' => '&#353;',
   898 	'&#155;' => '&#8250;',
  1095 	'&#155;' => '&#8250;',
   899 	'&#156;' => '&#339;',
  1096 	'&#156;' => '&#339;',
   900 	'&#157;' => '',
  1097 	'&#157;' => '',
   901 	'&#158;' => '',
  1098 	'&#158;' => '&#382;',
   902 	'&#159;' => '&#376;'
  1099 	'&#159;' => '&#376;'
   903 	);
  1100 	);
   904 
  1101 
   905 	// Remove metadata tags
  1102 	// Remove metadata tags
   906 	$content = preg_replace('/<title>(.+?)<\/title>/','',$content);
  1103 	$content = preg_replace('/<title>(.+?)<\/title>/','',$content);
   918 
  1115 
   919 	return $content;
  1116 	return $content;
   920 }
  1117 }
   921 
  1118 
   922 /**
  1119 /**
   923  * Callback used to change %uXXXX to &#YYY; syntax
       
   924  *
       
   925  * @since 2.8?
       
   926  *
       
   927  * @param array $matches Single Match
       
   928  * @return string An HTML entity
       
   929  */
       
   930 function funky_javascript_callback($matches) {
       
   931 	return "&#".base_convert($matches[1],16,10).";";
       
   932 }
       
   933 
       
   934 /**
       
   935  * Fixes javascript bugs in browsers.
       
   936  *
       
   937  * Converts unicode characters to HTML numbered entities.
       
   938  *
       
   939  * @since 1.5.0
       
   940  * @uses $is_macIE
       
   941  * @uses $is_winIE
       
   942  *
       
   943  * @param string $text Text to be made safe.
       
   944  * @return string Fixed text.
       
   945  */
       
   946 function funky_javascript_fix($text) {
       
   947 	// Fixes for browsers' javascript bugs
       
   948 	global $is_macIE, $is_winIE;
       
   949 
       
   950 	if ( $is_winIE || $is_macIE )
       
   951 		$text =  preg_replace_callback("/\%u([0-9A-F]{4,4})/",
       
   952 					       "funky_javascript_callback",
       
   953 					       $text);
       
   954 
       
   955 	return $text;
       
   956 }
       
   957 
       
   958 /**
       
   959  * Will only balance the tags if forced to and the option is set to balance tags.
  1120  * Will only balance the tags if forced to and the option is set to balance tags.
   960  *
  1121  *
   961  * The option 'use_balanceTags' is used for whether the tags will be balanced.
  1122  * The option 'use_balanceTags' is used to determine whether the tags will be balanced.
   962  * Both the $force parameter and 'use_balanceTags' option will have to be true
       
   963  * before the tags will be balanced.
       
   964  *
  1123  *
   965  * @since 0.71
  1124  * @since 0.71
   966  *
  1125  *
   967  * @param string $text Text to be balanced
  1126  * @param string $text Text to be balanced
   968  * @param bool $force Forces balancing, ignoring the value of the option. Default false.
  1127  * @param bool $force If true, forces balancing, ignoring the value of the option. Default false.
   969  * @return string Balanced text
  1128  * @return string Balanced text
   970  */
  1129  */
   971 function balanceTags( $text, $force = false ) {
  1130 function balanceTags( $text, $force = false ) {
   972 	if ( !$force && get_option('use_balanceTags') == 0 )
  1131 	if ( !$force && get_option('use_balanceTags') == 0 )
   973 		return $text;
  1132 		return $text;
   978  * Balances tags of string using a modified stack.
  1137  * Balances tags of string using a modified stack.
   979  *
  1138  *
   980  * @since 2.0.4
  1139  * @since 2.0.4
   981  *
  1140  *
   982  * @author Leonard Lin <leonard@acm.org>
  1141  * @author Leonard Lin <leonard@acm.org>
   983  * @license GPL v2.0
  1142  * @license GPL
   984  * @copyright November 4, 2001
  1143  * @copyright November 4, 2001
   985  * @version 1.1
  1144  * @version 1.1
   986  * @todo Make better - change loop condition to $text in 1.2
  1145  * @todo Make better - change loop condition to $text in 1.2
   987  * @internal Modified by Scott Reilly (coffee2code) 02 Aug 2004
  1146  * @internal Modified by Scott Reilly (coffee2code) 02 Aug 2004
   988  *		1.1  Fixed handling of append/stack pop order of end text
  1147  *		1.1  Fixed handling of append/stack pop order of end text
   991  *
  1150  *
   992  * @param string $text Text to be balanced.
  1151  * @param string $text Text to be balanced.
   993  * @return string Balanced text.
  1152  * @return string Balanced text.
   994  */
  1153  */
   995 function force_balance_tags( $text ) {
  1154 function force_balance_tags( $text ) {
   996 	$tagstack = array(); $stacksize = 0; $tagqueue = ''; $newtext = '';
  1155 	$tagstack = array();
   997 	$single_tags = array('br', 'hr', 'img', 'input'); //Known single-entity/self-closing tags
  1156 	$stacksize = 0;
   998 	$nestable_tags = array('blockquote', 'div', 'span'); //Tags that can be immediately nested within themselves
  1157 	$tagqueue = '';
   999 
  1158 	$newtext = '';
  1000 	# WP bug fix for comments - in case you REALLY meant to type '< !--'
  1159 	$single_tags = array( 'br', 'hr', 'img', 'input' ); // Known single-entity/self-closing tags
       
  1160 	$nestable_tags = array( 'blockquote', 'div', 'span', 'q' ); // Tags that can be immediately nested within themselves
       
  1161 
       
  1162 	// WP bug fix for comments - in case you REALLY meant to type '< !--'
  1001 	$text = str_replace('< !--', '<    !--', $text);
  1163 	$text = str_replace('< !--', '<    !--', $text);
  1002 	# WP bug fix for LOVE <3 (and other situations with '<' before a number)
  1164 	// WP bug fix for LOVE <3 (and other situations with '<' before a number)
  1003 	$text = preg_replace('#<([0-9]{1})#', '&lt;$1', $text);
  1165 	$text = preg_replace('#<([0-9]{1})#', '&lt;$1', $text);
  1004 
  1166 
  1005 	while (preg_match("/<(\/?\w*)\s*([^>]*)>/",$text,$regex)) {
  1167 	while ( preg_match("/<(\/?[\w:]*)\s*([^>]*)>/", $text, $regex) ) {
  1006 		$newtext .= $tagqueue;
  1168 		$newtext .= $tagqueue;
  1007 
  1169 
  1008 		$i = strpos($text,$regex[0]);
  1170 		$i = strpos($text, $regex[0]);
  1009 		$l = strlen($regex[0]);
  1171 		$l = strlen($regex[0]);
  1010 
  1172 
  1011 		// clear the shifter
  1173 		// clear the shifter
  1012 		$tagqueue = '';
  1174 		$tagqueue = '';
  1013 		// Pop or Push
  1175 		// Pop or Push
  1014 		if ( isset($regex[1][0]) && '/' == $regex[1][0] ) { // End Tag
  1176 		if ( isset($regex[1][0]) && '/' == $regex[1][0] ) { // End Tag
  1015 			$tag = strtolower(substr($regex[1],1));
  1177 			$tag = strtolower(substr($regex[1],1));
  1016 			// if too many closing tags
  1178 			// if too many closing tags
  1017 			if($stacksize <= 0) {
  1179 			if( $stacksize <= 0 ) {
  1018 				$tag = '';
  1180 				$tag = '';
  1019 				//or close to be safe $tag = '/' . $tag;
  1181 				// or close to be safe $tag = '/' . $tag;
  1020 			}
  1182 			}
  1021 			// if stacktop value = tag close value then pop
  1183 			// if stacktop value = tag close value then pop
  1022 			else if ($tagstack[$stacksize - 1] == $tag) { // found closing tag
  1184 			else if ( $tagstack[$stacksize - 1] == $tag ) { // found closing tag
  1023 				$tag = '</' . $tag . '>'; // Close Tag
  1185 				$tag = '</' . $tag . '>'; // Close Tag
  1024 				// Pop
  1186 				// Pop
  1025 				array_pop ($tagstack);
  1187 				array_pop( $tagstack );
  1026 				$stacksize--;
  1188 				$stacksize--;
  1027 			} else { // closing tag not at top, search for it
  1189 			} else { // closing tag not at top, search for it
  1028 				for ($j=$stacksize-1;$j>=0;$j--) {
  1190 				for ( $j = $stacksize-1; $j >= 0; $j-- ) {
  1029 					if ($tagstack[$j] == $tag) {
  1191 					if ( $tagstack[$j] == $tag ) {
  1030 					// add tag to tagqueue
  1192 					// add tag to tagqueue
  1031 						for ($k=$stacksize-1;$k>=$j;$k--){
  1193 						for ( $k = $stacksize-1; $k >= $j; $k--) {
  1032 							$tagqueue .= '</' . array_pop ($tagstack) . '>';
  1194 							$tagqueue .= '</' . array_pop( $tagstack ) . '>';
  1033 							$stacksize--;
  1195 							$stacksize--;
  1034 						}
  1196 						}
  1035 						break;
  1197 						break;
  1036 					}
  1198 					}
  1037 				}
  1199 				}
  1041 			$tag = strtolower($regex[1]);
  1203 			$tag = strtolower($regex[1]);
  1042 
  1204 
  1043 			// Tag Cleaning
  1205 			// Tag Cleaning
  1044 
  1206 
  1045 			// If self-closing or '', don't do anything.
  1207 			// If self-closing or '', don't do anything.
  1046 			if((substr($regex[2],-1) == '/') || ($tag == '')) {
  1208 			if ( substr($regex[2],-1) == '/' || $tag == '' ) {
       
  1209 				// do nothing
  1047 			}
  1210 			}
  1048 			// ElseIf it's a known single-entity tag but it doesn't close itself, do so
  1211 			// ElseIf it's a known single-entity tag but it doesn't close itself, do so
  1049 			elseif ( in_array($tag, $single_tags) ) {
  1212 			elseif ( in_array($tag, $single_tags) ) {
  1050 				$regex[2] .= '/';
  1213 				$regex[2] .= '/';
  1051 			} else {	// Push the tag onto the stack
  1214 			} else {	// Push the tag onto the stack
  1052 				// If the top of the stack is the same as the tag we want to push, close previous tag
  1215 				// If the top of the stack is the same as the tag we want to push, close previous tag
  1053 				if (($stacksize > 0) && !in_array($tag, $nestable_tags) && ($tagstack[$stacksize - 1] == $tag)) {
  1216 				if ( $stacksize > 0 && !in_array($tag, $nestable_tags) && $tagstack[$stacksize - 1] == $tag ) {
  1054 					$tagqueue = '</' . array_pop ($tagstack) . '>';
  1217 					$tagqueue = '</' . array_pop ($tagstack) . '>';
  1055 					$stacksize--;
  1218 					$stacksize--;
  1056 				}
  1219 				}
  1057 				$stacksize = array_push ($tagstack, $tag);
  1220 				$stacksize = array_push ($tagstack, $tag);
  1058 			}
  1221 			}
  1059 
  1222 
  1060 			// Attributes
  1223 			// Attributes
  1061 			$attributes = $regex[2];
  1224 			$attributes = $regex[2];
  1062 			if($attributes) {
  1225 			if( !empty($attributes) )
  1063 				$attributes = ' '.$attributes;
  1226 				$attributes = ' '.$attributes;
  1064 			}
  1227 
  1065 			$tag = '<'.$tag.$attributes.'>';
  1228 			$tag = '<' . $tag . $attributes . '>';
  1066 			//If already queuing a close tag, then put this tag on, too
  1229 			//If already queuing a close tag, then put this tag on, too
  1067 			if ($tagqueue) {
  1230 			if ( !empty($tagqueue) ) {
  1068 				$tagqueue .= $tag;
  1231 				$tagqueue .= $tag;
  1069 				$tag = '';
  1232 				$tag = '';
  1070 			}
  1233 			}
  1071 		}
  1234 		}
  1072 		$newtext .= substr($text,0,$i) . $tag;
  1235 		$newtext .= substr($text, 0, $i) . $tag;
  1073 		$text = substr($text,$i+$l);
  1236 		$text = substr($text, $i + $l);
  1074 	}
  1237 	}
  1075 
  1238 
  1076 	// Clear Tag Queue
  1239 	// Clear Tag Queue
  1077 	$newtext .= $tagqueue;
  1240 	$newtext .= $tagqueue;
  1078 
  1241 
  1079 	// Add Remaining text
  1242 	// Add Remaining text
  1080 	$newtext .= $text;
  1243 	$newtext .= $text;
  1081 
  1244 
  1082 	// Empty Stack
  1245 	// Empty Stack
  1083 	while($x = array_pop($tagstack)) {
  1246 	while( $x = array_pop($tagstack) )
  1084 		$newtext .= '</' . $x . '>'; // Add remaining tags to close
  1247 		$newtext .= '</' . $x . '>'; // Add remaining tags to close
  1085 	}
       
  1086 
  1248 
  1087 	// WP fix for the bug with HTML comments
  1249 	// WP fix for the bug with HTML comments
  1088 	$newtext = str_replace("< !--","<!--",$newtext);
  1250 	$newtext = str_replace("< !--","<!--",$newtext);
  1089 	$newtext = str_replace("<    !--","< !--",$newtext);
  1251 	$newtext = str_replace("<    !--","< !--",$newtext);
  1090 
  1252 
  1092 }
  1254 }
  1093 
  1255 
  1094 /**
  1256 /**
  1095  * Acts on text which is about to be edited.
  1257  * Acts on text which is about to be edited.
  1096  *
  1258  *
  1097  * Unless $richedit is set, it is simply a holder for the 'format_to_edit'
  1259  * The $content is run through esc_textarea(), which uses htmlspecialchars()
  1098  * filter. If $richedit is set true htmlspecialchars() will be run on the
  1260  * to convert special characters to HTML entities. If $richedit is set to true,
  1099  * content, converting special characters to HTMl entities.
  1261  * it is simply a holder for the 'format_to_edit' filter.
  1100  *
  1262  *
  1101  * @since 0.71
  1263  * @since 0.71
  1102  *
  1264  *
  1103  * @param string $content The text about to be edited.
  1265  * @param string $content The text about to be edited.
  1104  * @param bool $richedit Whether or not the $content should pass through htmlspecialchars(). Default false.
  1266  * @param bool $richedit Whether the $content should not pass through htmlspecialchars(). Default false (meaning it will be passed).
  1105  * @return string The text after the filter (and possibly htmlspecialchars()) has been run.
  1267  * @return string The text after the filter (and possibly htmlspecialchars()) has been run.
  1106  */
  1268  */
  1107 function format_to_edit($content, $richedit = false) {
  1269 function format_to_edit( $content, $richedit = false ) {
  1108 	$content = apply_filters('format_to_edit', $content);
  1270 	$content = apply_filters( 'format_to_edit', $content );
  1109 	if (! $richedit )
  1271 	if ( ! $richedit )
  1110 		$content = htmlspecialchars($content);
  1272 		$content = esc_textarea( $content );
  1111 	return $content;
  1273 	return $content;
  1112 }
  1274 }
  1113 
  1275 
  1114 /**
  1276 /**
  1115  * Holder for the 'format_to_post' filter.
  1277  * Holder for the 'format_to_post' filter.
  1126 
  1288 
  1127 /**
  1289 /**
  1128  * Add leading zeros when necessary.
  1290  * Add leading zeros when necessary.
  1129  *
  1291  *
  1130  * If you set the threshold to '4' and the number is '10', then you will get
  1292  * If you set the threshold to '4' and the number is '10', then you will get
  1131  * back '0010'. If you set the number to '4' and the number is '5000', then you
  1293  * back '0010'. If you set the threshold to '4' and the number is '5000', then you
  1132  * will get back '5000'.
  1294  * will get back '5000'.
  1133  *
  1295  *
  1134  * Uses sprintf to append the amount of zeros based on the $threshold parameter
  1296  * Uses sprintf to append the amount of zeros based on the $threshold parameter
  1135  * and the size of the number. If the number is large enough, then no zeros will
  1297  * and the size of the number. If the number is large enough, then no zeros will
  1136  * be appended.
  1298  * be appended.
  1203  *
  1365  *
  1204  * @param string $gpc The string returned from HTTP request data.
  1366  * @param string $gpc The string returned from HTTP request data.
  1205  * @return string Returns a string escaped with slashes.
  1367  * @return string Returns a string escaped with slashes.
  1206  */
  1368  */
  1207 function addslashes_gpc($gpc) {
  1369 function addslashes_gpc($gpc) {
  1208 	global $wpdb;
  1370 	if ( get_magic_quotes_gpc() )
  1209 
       
  1210 	if (get_magic_quotes_gpc()) {
       
  1211 		$gpc = stripslashes($gpc);
  1371 		$gpc = stripslashes($gpc);
  1212 	}
       
  1213 
  1372 
  1214 	return esc_sql($gpc);
  1373 	return esc_sql($gpc);
  1215 }
  1374 }
  1216 
  1375 
  1217 /**
  1376 /**
  1220  * If an array is passed, the array_map() function causes a callback to pass the
  1379  * If an array is passed, the array_map() function causes a callback to pass the
  1221  * value back to the function. The slashes from this value will removed.
  1380  * value back to the function. The slashes from this value will removed.
  1222  *
  1381  *
  1223  * @since 2.0.0
  1382  * @since 2.0.0
  1224  *
  1383  *
  1225  * @param array|string $value The array or string to be striped.
  1384  * @param array|string $value The array or string to be stripped.
  1226  * @return array|string Stripped array (or string in the callback).
  1385  * @return array|string Stripped array (or string in the callback).
  1227  */
  1386  */
  1228 function stripslashes_deep($value) {
  1387 function stripslashes_deep($value) {
  1229 	$value = is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value);
  1388 	if ( is_array($value) ) {
       
  1389 		$value = array_map('stripslashes_deep', $value);
       
  1390 	} elseif ( is_object($value) ) {
       
  1391 		$vars = get_object_vars( $value );
       
  1392 		foreach ($vars as $key=>$data) {
       
  1393 			$value->{$key} = stripslashes_deep( $data );
       
  1394 		}
       
  1395 	} else {
       
  1396 		$value = stripslashes($value);
       
  1397 	}
       
  1398 
  1230 	return $value;
  1399 	return $value;
  1231 }
  1400 }
  1232 
  1401 
  1233 /**
  1402 /**
  1234  * Navigates through an array and encodes the values to be used in a URL.
  1403  * Navigates through an array and encodes the values to be used in a URL.
  1235  *
  1404  *
  1236  * Uses a callback to pass the value of the array back to the function as a
       
  1237  * string.
       
  1238  *
  1405  *
  1239  * @since 2.2.0
  1406  * @since 2.2.0
  1240  *
  1407  *
  1241  * @param array|string $value The array or string to be encoded.
  1408  * @param array|string $value The array or string to be encoded.
  1242  * @return array|string $value The encoded array (or string from the callback).
  1409  * @return array|string $value The encoded array (or string from the callback).
  1243  */
  1410  */
  1244 function urlencode_deep($value) {
  1411 function urlencode_deep($value) {
  1245 	$value = is_array($value) ? array_map('urlencode_deep', $value) : urlencode($value);
  1412 	$value = is_array($value) ? array_map('urlencode_deep', $value) : urlencode($value);
  1246 	return $value;
  1413 	return $value;
       
  1414 }
       
  1415 
       
  1416 /**
       
  1417  * Navigates through an array and raw encodes the values to be used in a URL.
       
  1418  *
       
  1419  * @since 3.4.0
       
  1420  *
       
  1421  * @param array|string $value The array or string to be encoded.
       
  1422  * @return array|string $value The encoded array (or string from the callback).
       
  1423  */
       
  1424 function rawurlencode_deep( $value ) {
       
  1425 	return is_array( $value ) ? array_map( 'rawurlencode_deep', $value ) : rawurlencode( $value );
  1247 }
  1426 }
  1248 
  1427 
  1249 /**
  1428 /**
  1250  * Converts email addresses characters to HTML entities to block spam bots.
  1429  * Converts email addresses characters to HTML entities to block spam bots.
  1251  *
  1430  *
  1285  * @return string HTML A element with URI address.
  1464  * @return string HTML A element with URI address.
  1286  */
  1465  */
  1287 function _make_url_clickable_cb($matches) {
  1466 function _make_url_clickable_cb($matches) {
  1288 	$url = $matches[2];
  1467 	$url = $matches[2];
  1289 
  1468 
       
  1469 	if ( ')' == $matches[3] && strpos( $url, '(' ) ) {
       
  1470 		// If the trailing character is a closing parethesis, and the URL has an opening parenthesis in it, add the closing parenthesis to the URL.
       
  1471 		// Then we can let the parenthesis balancer do its thing below.
       
  1472 		$url .= $matches[3];
       
  1473 		$suffix = '';
       
  1474 	} else {
       
  1475 		$suffix = $matches[3];
       
  1476 	}
       
  1477 
       
  1478 	// Include parentheses in the URL only if paired
       
  1479 	while ( substr_count( $url, '(' ) < substr_count( $url, ')' ) ) {
       
  1480 		$suffix = strrchr( $url, ')' ) . $suffix;
       
  1481 		$url = substr( $url, 0, strrpos( $url, ')' ) );
       
  1482 	}
       
  1483 
  1290 	$url = esc_url($url);
  1484 	$url = esc_url($url);
  1291 	if ( empty($url) )
  1485 	if ( empty($url) )
  1292 		return $matches[0];
  1486 		return $matches[0];
  1293 
  1487 
  1294 	return $matches[1] . "<a href=\"$url\" rel=\"nofollow\">$url</a>";
  1488 	return $matches[1] . "<a href=\"$url\" rel=\"nofollow\">$url</a>" . $suffix;
  1295 }
  1489 }
  1296 
  1490 
  1297 /**
  1491 /**
  1298  * Callback to convert URL match to HTML A element.
  1492  * Callback to convert URL match to HTML A element.
  1299  *
  1493  *
  1345  * Converts URI, www and ftp, and email addresses. Finishes by fixing links
  1539  * Converts URI, www and ftp, and email addresses. Finishes by fixing links
  1346  * within links.
  1540  * within links.
  1347  *
  1541  *
  1348  * @since 0.71
  1542  * @since 0.71
  1349  *
  1543  *
  1350  * @param string $ret Content to convert URIs.
  1544  * @param string $text Content to convert URIs.
  1351  * @return string Content with converted URIs.
  1545  * @return string Content with converted URIs.
  1352  */
  1546  */
  1353 function make_clickable($ret) {
  1547 function make_clickable( $text ) {
  1354 	$ret = ' ' . $ret;
  1548 	$r = '';
  1355 	// in testing, using arrays here was found to be faster
  1549 	$textarr = preg_split( '/(<[^<>]+>)/', $text, -1, PREG_SPLIT_DELIM_CAPTURE ); // split out HTML tags
  1356 	$ret = preg_replace_callback('#(?<=[\s>])(\()?([\w]+?://(?:[\w\\x80-\\xff\#$%&~/=?@\[\](+-]|[.,;:](?![\s<]|(\))?([\s]|$))|(?(1)\)(?![\s<.,;:]|$)|\)))+)#is', '_make_url_clickable_cb', $ret);
  1550 	foreach ( $textarr as $piece ) {
  1357 	$ret = preg_replace_callback('#([\s>])((www|ftp)\.[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]+)#is', '_make_web_ftp_clickable_cb', $ret);
  1551 		if ( empty( $piece ) || ( $piece[0] == '<' && ! preg_match('|^<\s*[\w]{1,20}+://|', $piece) ) ) {
  1358 	$ret = preg_replace_callback('#([\s>])([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})#i', '_make_email_clickable_cb', $ret);
  1552 			$r .= $piece;
  1359 	// this one is not in an array because we need it to run last, for cleanup of accidental links within links
  1553 			continue;
  1360 	$ret = preg_replace("#(<a( [^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i", "$1$3</a>", $ret);
  1554 		}
  1361 	$ret = trim($ret);
  1555 
  1362 	return $ret;
  1556 		// Long strings might contain expensive edge cases ...
       
  1557 		if ( 10000 < strlen( $piece ) ) {
       
  1558 			// ... break it up
       
  1559 			foreach ( _split_str_by_whitespace( $piece, 2100 ) as $chunk ) { // 2100: Extra room for scheme and leading and trailing paretheses
       
  1560 				if ( 2101 < strlen( $chunk ) ) {
       
  1561 					$r .= $chunk; // Too big, no whitespace: bail.
       
  1562 				} else {
       
  1563 					$r .= make_clickable( $chunk );
       
  1564 				}
       
  1565 			}
       
  1566 		} else {
       
  1567 			$ret = " $piece "; // Pad with whitespace to simplify the regexes
       
  1568 
       
  1569 			$url_clickable = '~
       
  1570 				([\\s(<.,;:!?])                                        # 1: Leading whitespace, or punctuation
       
  1571 				(                                                      # 2: URL
       
  1572 					[\\w]{1,20}+://                                # Scheme and hier-part prefix
       
  1573 					(?=\S{1,2000}\s)                               # Limit to URLs less than about 2000 characters long
       
  1574 					[\\w\\x80-\\xff#%\\~/@\\[\\]*(+=&$-]*+         # Non-punctuation URL character
       
  1575 					(?:                                            # Unroll the Loop: Only allow puctuation URL character if followed by a non-punctuation URL character
       
  1576 						[\'.,;:!?)]                            # Punctuation URL character
       
  1577 						[\\w\\x80-\\xff#%\\~/@\\[\\]*(+=&$-]++ # Non-punctuation URL character
       
  1578 					)*
       
  1579 				)
       
  1580 				(\)?)                                                  # 3: Trailing closing parenthesis (for parethesis balancing post processing)
       
  1581 			~xS'; // The regex is a non-anchored pattern and does not have a single fixed starting character.
       
  1582 			      // Tell PCRE to spend more time optimizing since, when used on a page load, it will probably be used several times.
       
  1583 
       
  1584 			$ret = preg_replace_callback( $url_clickable, '_make_url_clickable_cb', $ret );
       
  1585 
       
  1586 			$ret = preg_replace_callback( '#([\s>])((www|ftp)\.[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]+)#is', '_make_web_ftp_clickable_cb', $ret );
       
  1587 			$ret = preg_replace_callback( '#([\s>])([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})#i', '_make_email_clickable_cb', $ret );
       
  1588 
       
  1589 			$ret = substr( $ret, 1, -1 ); // Remove our whitespace padding.
       
  1590 			$r .= $ret;
       
  1591 		}
       
  1592 	}
       
  1593 
       
  1594 	// Cleanup of accidental links within links
       
  1595 	$r = preg_replace( '#(<a( [^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i', "$1$3</a>", $r );
       
  1596 	return $r;
       
  1597 }
       
  1598 
       
  1599 /**
       
  1600  * Breaks a string into chunks by splitting at whitespace characters.
       
  1601  * The length of each returned chunk is as close to the specified length goal as possible,
       
  1602  * with the caveat that each chunk includes its trailing delimiter.
       
  1603  * Chunks longer than the goal are guaranteed to not have any inner whitespace.
       
  1604  *
       
  1605  * Joining the returned chunks with empty delimiters reconstructs the input string losslessly.
       
  1606  *
       
  1607  * Input string must have no null characters (or eventual transformations on output chunks must not care about null characters)
       
  1608  *
       
  1609  * <code>
       
  1610  * _split_str_by_whitespace( "1234 67890 1234 67890a cd 1234   890 123456789 1234567890a    45678   1 3 5 7 90 ", 10 ) ==
       
  1611  * array (
       
  1612  *   0 => '1234 67890 ',  // 11 characters: Perfect split
       
  1613  *   1 => '1234 ',        //  5 characters: '1234 67890a' was too long
       
  1614  *   2 => '67890a cd ',   // 10 characters: '67890a cd 1234' was too long
       
  1615  *   3 => '1234   890 ',  // 11 characters: Perfect split
       
  1616  *   4 => '123456789 ',   // 10 characters: '123456789 1234567890a' was too long
       
  1617  *   5 => '1234567890a ', // 12 characters: Too long, but no inner whitespace on which to split
       
  1618  *   6 => '   45678   ',  // 11 characters: Perfect split
       
  1619  *   7 => '1 3 5 7 9',    //  9 characters: End of $string
       
  1620  * );
       
  1621  * </code>
       
  1622  *
       
  1623  * @since 3.4.0
       
  1624  * @access private
       
  1625  *
       
  1626  * @param string $string The string to split
       
  1627  * @param    int $goal   The desired chunk length.
       
  1628  * @return array Numeric array of chunks.
       
  1629  */
       
  1630 function _split_str_by_whitespace( $string, $goal ) {
       
  1631 	$chunks = array();
       
  1632 
       
  1633 	$string_nullspace = strtr( $string, "\r\n\t\v\f ", "\000\000\000\000\000\000" );
       
  1634 
       
  1635 	while ( $goal < strlen( $string_nullspace ) ) {
       
  1636 		$pos = strrpos( substr( $string_nullspace, 0, $goal + 1 ), "\000" );
       
  1637 
       
  1638 		if ( false === $pos ) {
       
  1639 			$pos = strpos( $string_nullspace, "\000", $goal + 1 );
       
  1640 			if ( false === $pos ) {
       
  1641 				break;
       
  1642 			}
       
  1643 		}
       
  1644 
       
  1645 		$chunks[] = substr( $string, 0, $pos + 1 );
       
  1646 		$string = substr( $string, $pos + 1 );
       
  1647 		$string_nullspace = substr( $string_nullspace, $pos + 1 );
       
  1648 	}
       
  1649 
       
  1650 	if ( $string ) {
       
  1651 		$chunks[] = $string;
       
  1652 	}
       
  1653 
       
  1654 	return $chunks;
  1363 }
  1655 }
  1364 
  1656 
  1365 /**
  1657 /**
  1366  * Adds rel nofollow string to all HTML A elements in content.
  1658  * Adds rel nofollow string to all HTML A elements in content.
  1367  *
  1659  *
  1369  *
  1661  *
  1370  * @param string $text Content that may contain HTML A elements.
  1662  * @param string $text Content that may contain HTML A elements.
  1371  * @return string Converted content.
  1663  * @return string Converted content.
  1372  */
  1664  */
  1373 function wp_rel_nofollow( $text ) {
  1665 function wp_rel_nofollow( $text ) {
  1374 	global $wpdb;
       
  1375 	// This is a pre save filter, so text is already escaped.
  1666 	// This is a pre save filter, so text is already escaped.
  1376 	$text = stripslashes($text);
  1667 	$text = stripslashes($text);
  1377 	$text = preg_replace_callback('|<a (.+?)>|i', 'wp_rel_nofollow_callback', $text);
  1668 	$text = preg_replace_callback('|<a (.+?)>|i', 'wp_rel_nofollow_callback', $text);
  1378 	$text = esc_sql($text);
  1669 	$text = esc_sql($text);
  1379 	return $text;
  1670 	return $text;
  1394 	$text = $matches[1];
  1685 	$text = $matches[1];
  1395 	$text = str_replace(array(' rel="nofollow"', " rel='nofollow'"), '', $text);
  1686 	$text = str_replace(array(' rel="nofollow"', " rel='nofollow'"), '', $text);
  1396 	return "<a $text rel=\"nofollow\">";
  1687 	return "<a $text rel=\"nofollow\">";
  1397 }
  1688 }
  1398 
  1689 
  1399 
       
  1400 /**
  1690 /**
  1401  * Convert one smiley code to the icon graphic file equivalent.
  1691  * Convert one smiley code to the icon graphic file equivalent.
  1402  *
  1692  *
  1403  * Looks up one smiley code in the $wpsmiliestrans global array and returns an
  1693  * Looks up one smiley code in the $wpsmiliestrans global array and returns an
  1404  * <img> string for that smiley.
  1694  * <img> string for that smiley.
  1413 	global $wpsmiliestrans;
  1703 	global $wpsmiliestrans;
  1414 
  1704 
  1415 	if (count($smiley) == 0) {
  1705 	if (count($smiley) == 0) {
  1416 		return '';
  1706 		return '';
  1417 	}
  1707 	}
  1418 
       
  1419 	$siteurl = get_option( 'siteurl' );
       
  1420 
  1708 
  1421 	$smiley = trim(reset($smiley));
  1709 	$smiley = trim(reset($smiley));
  1422 	$img = $wpsmiliestrans[$smiley];
  1710 	$img = $wpsmiliestrans[$smiley];
  1423 	$smiley_masked = esc_attr($smiley);
  1711 	$smiley_masked = esc_attr($smiley);
  1424 
  1712 
  1425 	$srcurl = apply_filters('smilies_src', "$siteurl/wp-includes/images/smilies/$img", $img, $siteurl);
  1713 	$srcurl = apply_filters('smilies_src', includes_url("images/smilies/$img"), $img, site_url());
  1426 
  1714 
  1427 	return " <img src='$srcurl' alt='$smiley_masked' class='wp-smiley' /> ";
  1715 	return " <img src='$srcurl' alt='$smiley_masked' class='wp-smiley' /> ";
  1428 }
  1716 }
  1429 
       
  1430 
  1717 
  1431 /**
  1718 /**
  1432  * Convert text equivalent of smilies to images.
  1719  * Convert text equivalent of smilies to images.
  1433  *
  1720  *
  1434  * Will only convert smilies if the option 'use_smilies' is true and the global
  1721  * Will only convert smilies if the option 'use_smilies' is true and the global
  1447 		// HTML loop taken from texturize function, could possible be consolidated
  1734 		// HTML loop taken from texturize function, could possible be consolidated
  1448 		$textarr = preg_split("/(<.*>)/U", $text, -1, PREG_SPLIT_DELIM_CAPTURE); // capture the tags as well as in between
  1735 		$textarr = preg_split("/(<.*>)/U", $text, -1, PREG_SPLIT_DELIM_CAPTURE); // capture the tags as well as in between
  1449 		$stop = count($textarr);// loop stuff
  1736 		$stop = count($textarr);// loop stuff
  1450 		for ($i = 0; $i < $stop; $i++) {
  1737 		for ($i = 0; $i < $stop; $i++) {
  1451 			$content = $textarr[$i];
  1738 			$content = $textarr[$i];
  1452 			if ((strlen($content) > 0) && ('<' != $content{0})) { // If it's not a tag
  1739 			if ((strlen($content) > 0) && ('<' != $content[0])) { // If it's not a tag
  1453 				$content = preg_replace_callback($wp_smiliessearch, 'translate_smiley', $content);
  1740 				$content = preg_replace_callback($wp_smiliessearch, 'translate_smiley', $content);
  1454 			}
  1741 			}
  1455 			$output .= $content;
  1742 			$output .= $content;
  1456 		}
  1743 		}
  1457 	} else {
  1744 	} else {
  1467  * Does not grok i18n domains. Not RFC compliant.
  1754  * Does not grok i18n domains. Not RFC compliant.
  1468  *
  1755  *
  1469  * @since 0.71
  1756  * @since 0.71
  1470  *
  1757  *
  1471  * @param string $email Email address to verify.
  1758  * @param string $email Email address to verify.
  1472  * @param boolean $check_dns Whether to check the DNS for the domain using checkdnsrr().
  1759  * @param boolean $deprecated Deprecated.
  1473  * @return string|bool Either false or the valid email address.
  1760  * @return string|bool Either false or the valid email address.
  1474  */
  1761  */
  1475 function is_email( $email, $check_dns = false ) {
  1762 function is_email( $email, $deprecated = false ) {
       
  1763 	if ( ! empty( $deprecated ) )
       
  1764 		_deprecated_argument( __FUNCTION__, '3.0' );
       
  1765 
  1476 	// Test for the minimum length the email can be
  1766 	// Test for the minimum length the email can be
  1477 	if ( strlen( $email ) < 3 ) {
  1767 	if ( strlen( $email ) < 3 ) {
  1478 		return apply_filters( 'is_email', false, $email, 'email_too_short' );
  1768 		return apply_filters( 'is_email', false, $email, 'email_too_short' );
  1479 	}
  1769 	}
  1480 
  1770 
  1522 		if ( !preg_match('/^[a-z0-9-]+$/i', $sub ) ) {
  1812 		if ( !preg_match('/^[a-z0-9-]+$/i', $sub ) ) {
  1523 			return apply_filters( 'is_email', false, $email, 'sub_invalid_chars' );
  1813 			return apply_filters( 'is_email', false, $email, 'sub_invalid_chars' );
  1524 		}
  1814 		}
  1525 	}
  1815 	}
  1526 
  1816 
  1527 	// DNS
       
  1528 	// Check the domain has a valid MX and A resource record
       
  1529 	if ( $check_dns && function_exists( 'checkdnsrr' ) && !( checkdnsrr( $domain . '.', 'MX' ) || checkdnsrr( $domain . '.', 'A' ) ) ) {
       
  1530 		return apply_filters( 'is_email', false, $email, 'dns_no_rr' );
       
  1531 	}
       
  1532 
       
  1533 	// Congratulations your email made it!
  1817 	// Congratulations your email made it!
  1534 	return apply_filters( 'is_email', $email, $email, null );
  1818 	return apply_filters( 'is_email', $email, $email, null );
  1535 }
  1819 }
  1536 
  1820 
  1537 /**
  1821 /**
  1547 	/* this may only work with iso-8859-1, I'm afraid */
  1831 	/* this may only work with iso-8859-1, I'm afraid */
  1548 	if (!preg_match('#\=\?(.+)\?Q\?(.+)\?\=#i', $string, $matches)) {
  1832 	if (!preg_match('#\=\?(.+)\?Q\?(.+)\?\=#i', $string, $matches)) {
  1549 		return $string;
  1833 		return $string;
  1550 	} else {
  1834 	} else {
  1551 		$subject = str_replace('_', ' ', $matches[2]);
  1835 		$subject = str_replace('_', ' ', $matches[2]);
  1552 		$subject = preg_replace_callback('#\=([0-9a-f]{2})#i', create_function('$match', 'return chr(hexdec(strtolower($match[1])));'), $subject);
  1836 		$subject = preg_replace_callback('#\=([0-9a-f]{2})#i', '_wp_iso_convert', $subject);
  1553 		return $subject;
  1837 		return $subject;
  1554 	}
  1838 	}
       
  1839 }
       
  1840 
       
  1841 /**
       
  1842  * Helper function to convert hex encoded chars to ascii
       
  1843  *
       
  1844  * @since 3.1.0
       
  1845  * @access private
       
  1846  * @param array $match the preg_replace_callback matches array
       
  1847  */
       
  1848 function _wp_iso_convert( $match ) {
       
  1849 	return chr( hexdec( strtolower( $match[1] ) ) );
  1555 }
  1850 }
  1556 
  1851 
  1557 /**
  1852 /**
  1558  * Returns a date in the GMT equivalent.
  1853  * Returns a date in the GMT equivalent.
  1559  *
  1854  *
  1560  * Requires and returns a date in the Y-m-d H:i:s format. Simply subtracts the
  1855  * Requires and returns a date in the Y-m-d H:i:s format. Simply subtracts the
  1561  * value of the 'gmt_offset' option. Return format can be overridden using the
  1856  * value of the 'gmt_offset' option. Return format can be overridden using the
  1562  * $format parameter
  1857  * $format parameter. The DateTime and DateTimeZone classes are used to respect
       
  1858  * time zone differences in DST.
  1563  *
  1859  *
  1564  * @since 1.2.0
  1860  * @since 1.2.0
  1565  *
  1861  *
  1566  * @uses get_option() to retrieve the the value of 'gmt_offset'.
  1862  * @uses get_option() to retrieve the the value of 'gmt_offset'.
  1567  * @param string $string The date to be converted.
  1863  * @param string $string The date to be converted.
  1568  * @param string $format The format string for the returned date (default is Y-m-d H:i:s)
  1864  * @param string $format The format string for the returned date (default is Y-m-d H:i:s)
  1569  * @return string GMT version of the date provided.
  1865  * @return string GMT version of the date provided.
  1570  */
  1866  */
  1571 function get_gmt_from_date($string, $format = 'Y-m-d H:i:s') {
  1867 function get_gmt_from_date($string, $format = 'Y-m-d H:i:s') {
  1572 	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);
  1868 	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);
  1573 	$string_time = gmmktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
  1869 	$tz = get_option('timezone_string');
  1574 	$string_gmt = gmdate($format, $string_time - get_option('gmt_offset') * 3600);
  1870 	if ( $tz ) {
       
  1871 		date_default_timezone_set( $tz );
       
  1872 		$datetime = new DateTime( $string );
       
  1873 		$datetime->setTimezone( new DateTimeZone('UTC') );
       
  1874 		$offset = $datetime->getOffset();
       
  1875 		$datetime->modify( '+' . $offset / 3600 . ' hours');
       
  1876 		$string_gmt = gmdate($format, $datetime->format('U'));
       
  1877 
       
  1878 		date_default_timezone_set('UTC');
       
  1879 	} else {
       
  1880 		$string_time = gmmktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
       
  1881 		$string_gmt = gmdate($format, $string_time - get_option('gmt_offset') * 3600);
       
  1882 	}
  1575 	return $string_gmt;
  1883 	return $string_gmt;
  1576 }
  1884 }
  1577 
  1885 
  1578 /**
  1886 /**
  1579  * Converts a GMT date into the correct format for the blog.
  1887  * Converts a GMT date into the correct format for the blog.
  1721 	foreach ( $subs as $sub ) {
  2029 	foreach ( $subs as $sub ) {
  1722 		// Test for leading and trailing hyphens
  2030 		// Test for leading and trailing hyphens
  1723 		$sub = trim( $sub, " \t\n\r\0\x0B-" );
  2031 		$sub = trim( $sub, " \t\n\r\0\x0B-" );
  1724 
  2032 
  1725 		// Test for invalid characters
  2033 		// Test for invalid characters
  1726 		$sub = preg_replace( '/^[^a-z0-9-]+$/i', '', $sub );
  2034 		$sub = preg_replace( '/[^a-z0-9-]+/i', '', $sub );
  1727 
  2035 
  1728 		// If there's anything left, add it to the valid subs
  2036 		// If there's anything left, add it to the valid subs
  1729 		if ( '' !== $sub ) {
  2037 		if ( '' !== $sub ) {
  1730 			$new_subs[] = $sub;
  2038 			$new_subs[] = $sub;
  1731 		}
  2039 		}
  1765 	if ($diff <= 3600) {
  2073 	if ($diff <= 3600) {
  1766 		$mins = round($diff / 60);
  2074 		$mins = round($diff / 60);
  1767 		if ($mins <= 1) {
  2075 		if ($mins <= 1) {
  1768 			$mins = 1;
  2076 			$mins = 1;
  1769 		}
  2077 		}
       
  2078 		/* translators: min=minute */
  1770 		$since = sprintf(_n('%s min', '%s mins', $mins), $mins);
  2079 		$since = sprintf(_n('%s min', '%s mins', $mins), $mins);
  1771 	} else if (($diff <= 86400) && ($diff > 3600)) {
  2080 	} else if (($diff <= 86400) && ($diff > 3600)) {
  1772 		$hours = round($diff / 3600);
  2081 		$hours = round($diff / 3600);
  1773 		if ($hours <= 1) {
  2082 		if ($hours <= 1) {
  1774 			$hours = 1;
  2083 			$hours = 1;
  1794  * The 55 word limit can be modified by plugins/themes using the excerpt_length filter
  2103  * The 55 word limit can be modified by plugins/themes using the excerpt_length filter
  1795  * The ' [...]' string can be modified by plugins/themes using the excerpt_more filter
  2104  * The ' [...]' string can be modified by plugins/themes using the excerpt_more filter
  1796  *
  2105  *
  1797  * @since 1.5.0
  2106  * @since 1.5.0
  1798  *
  2107  *
  1799  * @param string $text The excerpt. If set to empty an excerpt is generated.
  2108  * @param string $text Optional. The excerpt. If set to empty, an excerpt is generated.
  1800  * @return string The excerpt.
  2109  * @return string The excerpt.
  1801  */
  2110  */
  1802 function wp_trim_excerpt($text) {
  2111 function wp_trim_excerpt($text = '') {
  1803 	$raw_excerpt = $text;
  2112 	$raw_excerpt = $text;
  1804 	if ( '' == $text ) {
  2113 	if ( '' == $text ) {
  1805 		$text = get_the_content('');
  2114 		$text = get_the_content('');
  1806 
  2115 
  1807 		$text = strip_shortcodes( $text );
  2116 		$text = strip_shortcodes( $text );
  1808 
  2117 
  1809 		$text = apply_filters('the_content', $text);
  2118 		$text = apply_filters('the_content', $text);
  1810 		$text = str_replace(']]>', ']]&gt;', $text);
  2119 		$text = str_replace(']]>', ']]&gt;', $text);
  1811 		$text = strip_tags($text);
       
  1812 		$excerpt_length = apply_filters('excerpt_length', 55);
  2120 		$excerpt_length = apply_filters('excerpt_length', 55);
  1813 		$excerpt_more = apply_filters('excerpt_more', ' ' . '[...]');
  2121 		$excerpt_more = apply_filters('excerpt_more', ' ' . '[...]');
  1814 		$words = explode(' ', $text, $excerpt_length + 1);
  2122 		$text = wp_trim_words( $text, $excerpt_length, $excerpt_more );
  1815 		if (count($words) > $excerpt_length) {
       
  1816 			array_pop($words);
       
  1817 			$text = implode(' ', $words);
       
  1818 			$text = $text . $excerpt_more;
       
  1819 		}
       
  1820 	}
  2123 	}
  1821 	return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
  2124 	return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
       
  2125 }
       
  2126 
       
  2127 /**
       
  2128  * Trims text to a certain number of words.
       
  2129  *
       
  2130  * This function is localized. For languages that count 'words' by the individual
       
  2131  * character (such as East Asian languages), the $num_words argument will apply
       
  2132  * to the number of individual characters.
       
  2133  *
       
  2134  * @since 3.3.0
       
  2135  *
       
  2136  * @param string $text Text to trim.
       
  2137  * @param int $num_words Number of words. Default 55.
       
  2138  * @param string $more What to append if $text needs to be trimmed. Default '&hellip;'.
       
  2139  * @return string Trimmed text.
       
  2140  */
       
  2141 function wp_trim_words( $text, $num_words = 55, $more = null ) {
       
  2142 	if ( null === $more )
       
  2143 		$more = __( '&hellip;' );
       
  2144 	$original_text = $text;
       
  2145 	$text = wp_strip_all_tags( $text );
       
  2146 	/* translators: If your word count is based on single characters (East Asian characters),
       
  2147 	   enter 'characters'. Otherwise, enter 'words'. Do not translate into your own language. */
       
  2148 	if ( 'characters' == _x( 'words', 'word count: words or characters?' ) && preg_match( '/^utf\-?8$/i', get_option( 'blog_charset' ) ) ) {
       
  2149 		$text = trim( preg_replace( "/[\n\r\t ]+/", ' ', $text ), ' ' );
       
  2150 		preg_match_all( '/./u', $text, $words_array );
       
  2151 		$words_array = array_slice( $words_array[0], 0, $num_words + 1 );
       
  2152 		$sep = '';
       
  2153 	} else {
       
  2154 		$words_array = preg_split( "/[\n\r\t ]+/", $text, $num_words + 1, PREG_SPLIT_NO_EMPTY );
       
  2155 		$sep = ' ';
       
  2156 	}
       
  2157 	if ( count( $words_array ) > $num_words ) {
       
  2158 		array_pop( $words_array );
       
  2159 		$text = implode( $sep, $words_array );
       
  2160 		$text = $text . $more;
       
  2161 	} else {
       
  2162 		$text = implode( $sep, $words_array );
       
  2163 	}
       
  2164 	return apply_filters( 'wp_trim_words', $text, $num_words, $more, $original_text );
  1822 }
  2165 }
  1823 
  2166 
  1824 /**
  2167 /**
  1825  * Converts named entities into numbered entities.
  2168  * Converts named entities into numbered entities.
  1826  *
  2169  *
  1828  *
  2171  *
  1829  * @param string $text The text within which entities will be converted.
  2172  * @param string $text The text within which entities will be converted.
  1830  * @return string Text with converted entities.
  2173  * @return string Text with converted entities.
  1831  */
  2174  */
  1832 function ent2ncr($text) {
  2175 function ent2ncr($text) {
       
  2176 
       
  2177 	// Allow a plugin to short-circuit and override the mappings.
       
  2178 	$filtered = apply_filters( 'pre_ent2ncr', null, $text );
       
  2179 	if( null !== $filtered )
       
  2180 		return $filtered;
       
  2181 
  1833 	$to_ncr = array(
  2182 	$to_ncr = array(
  1834 		'&quot;' => '&#34;',
  2183 		'&quot;' => '&#34;',
  1835 		'&amp;' => '&#38;',
  2184 		'&amp;' => '&#38;',
  1836 		'&frasl;' => '&#47;',
  2185 		'&frasl;' => '&#47;',
  1837 		'&lt;' => '&#60;',
  2186 		'&lt;' => '&#60;',
  2132 
  2481 
  2133 	return apply_filters('htmledit_pre', $output);
  2482 	return apply_filters('htmledit_pre', $output);
  2134 }
  2483 }
  2135 
  2484 
  2136 /**
  2485 /**
       
  2486  * Perform a deep string replace operation to ensure the values in $search are no longer present
       
  2487  *
       
  2488  * Repeats the replacement operation until it no longer replaces anything so as to remove "nested" values
       
  2489  * e.g. $subject = '%0%0%0DDD', $search ='%0D', $result ='' rather than the '%0%0DD' that
       
  2490  * str_replace would return
       
  2491  *
       
  2492  * @since 2.8.1
       
  2493  * @access private
       
  2494  *
       
  2495  * @param string|array $search
       
  2496  * @param string $subject
       
  2497  * @return string The processed string
       
  2498  */
       
  2499 function _deep_replace( $search, $subject ) {
       
  2500 	$found = true;
       
  2501 	$subject = (string) $subject;
       
  2502 	while ( $found ) {
       
  2503 		$found = false;
       
  2504 		foreach ( (array) $search as $val ) {
       
  2505 			while ( strpos( $subject, $val ) !== false ) {
       
  2506 				$found = true;
       
  2507 				$subject = str_replace( $val, '', $subject );
       
  2508 			}
       
  2509 		}
       
  2510 	}
       
  2511 
       
  2512 	return $subject;
       
  2513 }
       
  2514 
       
  2515 /**
       
  2516  * Escapes data for use in a MySQL query
       
  2517  *
       
  2518  * This is just a handy shortcut for $wpdb->escape(), for completeness' sake
       
  2519  *
       
  2520  * @since 2.8.0
       
  2521  * @param string $sql Unescaped SQL data
       
  2522  * @return string The cleaned $sql
       
  2523  */
       
  2524 function esc_sql( $sql ) {
       
  2525 	global $wpdb;
       
  2526 	return $wpdb->escape( $sql );
       
  2527 }
       
  2528 
       
  2529 /**
  2137  * Checks and cleans a URL.
  2530  * Checks and cleans a URL.
  2138  *
  2531  *
  2139  * A number of characters are removed from the URL. If the URL is for displaying
  2532  * A number of characters are removed from the URL. If the URL is for displaying
  2140  * (the default behaviour) amperstands are also replaced. The 'esc_url' filter
  2533  * (the default behaviour) ampersands are also replaced. The 'clean_url' filter
  2141  * is applied to the returned cleaned URL.
  2534  * is applied to the returned cleaned URL.
  2142  *
  2535  *
  2143  * @since 1.2.0
  2536  * @since 2.8.0
  2144  * @uses wp_kses_bad_protocol() To only permit protocols in the URL set
  2537  * @uses wp_kses_bad_protocol() To only permit protocols in the URL set
  2145  *		via $protocols or the common ones set in the function.
  2538  *		via $protocols or the common ones set in the function.
  2146  *
  2539  *
  2147  * @param string $url The URL to be cleaned.
  2540  * @param string $url The URL to be cleaned.
  2148  * @param array $protocols Optional. An array of acceptable protocols.
  2541  * @param array $protocols Optional. An array of acceptable protocols.
  2149  *		Defaults to 'http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet' if not set.
  2542  *		Defaults to 'http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet', 'mms', 'rtsp', 'svn' if not set.
  2150  * @param string $context Optional. How the URL will be used. Default is 'display'.
  2543  * @param string $_context Private. Use esc_url_raw() for database usage.
  2151  * @return string The cleaned $url after the 'cleaned_url' filter is applied.
  2544  * @return string The cleaned $url after the 'clean_url' filter is applied.
  2152  */
  2545  */
  2153 function clean_url( $url, $protocols = null, $context = 'display' ) {
  2546 function esc_url( $url, $protocols = null, $_context = 'display' ) {
  2154 	$original_url = $url;
  2547 	$original_url = $url;
  2155 
  2548 
  2156 	if ('' == $url) return $url;
  2549 	if ( '' == $url )
       
  2550 		return $url;
  2157 	$url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\\x80-\\xff]|i', '', $url);
  2551 	$url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\\x80-\\xff]|i', '', $url);
  2158 	$strip = array('%0d', '%0a', '%0D', '%0A');
  2552 	$strip = array('%0d', '%0a', '%0D', '%0A');
  2159 	$url = _deep_replace($strip, $url);
  2553 	$url = _deep_replace($strip, $url);
  2160 	$url = str_replace(';//', '://', $url);
  2554 	$url = str_replace(';//', '://', $url);
  2161 	/* If the URL doesn't appear to contain a scheme, we
  2555 	/* If the URL doesn't appear to contain a scheme, we
  2162 	 * presume it needs http:// appended (unless a relative
  2556 	 * presume it needs http:// appended (unless a relative
  2163 	 * link starting with / or a php file).
  2557 	 * link starting with /, # or ? or a php file).
  2164 	 */
  2558 	 */
  2165 	if ( strpos($url, ':') === false &&
  2559 	if ( strpos($url, ':') === false && ! in_array( $url[0], array( '/', '#', '?' ) ) &&
  2166 		substr( $url, 0, 1 ) != '/' && substr( $url, 0, 1 ) != '#' && !preg_match('/^[a-z0-9-]+?\.php/i', $url) )
  2560 		! preg_match('/^[a-z0-9-]+?\.php/i', $url) )
  2167 		$url = 'http://' . $url;
  2561 		$url = 'http://' . $url;
  2168 
  2562 
  2169 	// Replace ampersands and single quotes only when displaying.
  2563 	// Replace ampersands and single quotes only when displaying.
  2170 	if ( 'display' == $context ) {
  2564 	if ( 'display' == $_context ) {
  2171 		$url = preg_replace('/&([^#])(?![a-z]{2,8};)/', '&#038;$1', $url);
  2565 		$url = wp_kses_normalize_entities( $url );
       
  2566 		$url = str_replace( '&amp;', '&#038;', $url );
  2172 		$url = str_replace( "'", '&#039;', $url );
  2567 		$url = str_replace( "'", '&#039;', $url );
  2173 	}
  2568 	}
  2174 
  2569 
  2175 	if ( !is_array($protocols) )
  2570 	if ( ! is_array( $protocols ) )
  2176 		$protocols = array('http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet');
  2571 		$protocols = wp_allowed_protocols();
  2177 	if ( wp_kses_bad_protocol( $url, $protocols ) != $url )
  2572 	if ( wp_kses_bad_protocol( $url, $protocols ) != $url )
  2178 		return '';
  2573 		return '';
  2179 
  2574 
  2180 	return apply_filters('clean_url', $url, $original_url, $context);
  2575 	return apply_filters('clean_url', $url, $original_url, $_context);
  2181 }
  2576 }
  2182 
  2577 
  2183 /**
  2578 /**
  2184  * Perform a deep string replace operation to ensure the values in $search are no longer present
  2579  * Performs esc_url() for database usage.
  2185  *
       
  2186  * Repeats the replacement operation until it no longer replaces anything so as to remove "nested" values
       
  2187  * e.g. $subject = '%0%0%0DDD', $search ='%0D', $result ='' rather than the '%0%0DD' that
       
  2188  * str_replace would return
       
  2189  *
       
  2190  * @since 2.8.1
       
  2191  * @access private
       
  2192  *
       
  2193  * @param string|array $search
       
  2194  * @param string $subject
       
  2195  * @return string The processed string
       
  2196  */
       
  2197 function _deep_replace($search, $subject){
       
  2198 	$found = true;
       
  2199 	while($found) {
       
  2200 		$found = false;
       
  2201 		foreach( (array) $search as $val ) {
       
  2202 			while(strpos($subject, $val) !== false) {
       
  2203 				$found = true;
       
  2204 				$subject = str_replace($val, '', $subject);
       
  2205 			}
       
  2206 		}
       
  2207 	}
       
  2208 
       
  2209 	return $subject;
       
  2210 }
       
  2211 
       
  2212 /**
       
  2213  * Escapes data for use in a MySQL query
       
  2214  *
       
  2215  * This is just a handy shortcut for $wpdb->escape(), for completeness' sake
       
  2216  *
       
  2217  * @since 2.8.0
       
  2218  * @param string $sql Unescaped SQL data
       
  2219  * @return string The cleaned $sql
       
  2220  */
       
  2221 function esc_sql( $sql ) {
       
  2222 	global $wpdb;
       
  2223 	return $wpdb->escape( $sql );
       
  2224 }
       
  2225 
       
  2226 
       
  2227 /**
       
  2228  * Checks and cleans a URL.
       
  2229  *
       
  2230  * A number of characters are removed from the URL. If the URL is for displaying
       
  2231  * (the default behaviour) amperstands are also replaced. The 'esc_url' filter
       
  2232  * is applied to the returned cleaned URL.
       
  2233  *
  2580  *
  2234  * @since 2.8.0
  2581  * @since 2.8.0
  2235  * @uses esc_url()
  2582  * @uses esc_url()
  2236  * @uses wp_kses_bad_protocol() To only permit protocols in the URL set
       
  2237  *		via $protocols or the common ones set in the function.
       
  2238  *
       
  2239  * @param string $url The URL to be cleaned.
       
  2240  * @param array $protocols Optional. An array of acceptable protocols.
       
  2241  *		Defaults to 'http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet' if not set.
       
  2242  * @return string The cleaned $url after the 'cleaned_url' filter is applied.
       
  2243  */
       
  2244 function esc_url( $url, $protocols = null ) {
       
  2245 	return clean_url( $url, $protocols, 'display' );
       
  2246 }
       
  2247 
       
  2248 /**
       
  2249  * Performs esc_url() for database usage.
       
  2250  *
       
  2251  * @see esc_url()
       
  2252  * @see esc_url()
       
  2253  *
       
  2254  * @since 2.8.0
       
  2255  *
  2583  *
  2256  * @param string $url The URL to be cleaned.
  2584  * @param string $url The URL to be cleaned.
  2257  * @param array $protocols An array of acceptable protocols.
  2585  * @param array $protocols An array of acceptable protocols.
  2258  * @return string The cleaned URL.
  2586  * @return string The cleaned URL.
  2259  */
  2587  */
  2260 function esc_url_raw( $url, $protocols = null ) {
  2588 function esc_url_raw( $url, $protocols = null ) {
  2261 	return clean_url( $url, $protocols, 'db' );
  2589 	return esc_url( $url, $protocols, 'db' );
  2262 }
       
  2263 
       
  2264 /**
       
  2265  * Performs esc_url() for database or redirect usage.
       
  2266  *
       
  2267  * @see esc_url()
       
  2268  * @deprecated 2.8.0
       
  2269  *
       
  2270  * @since 2.3.1
       
  2271  *
       
  2272  * @param string $url The URL to be cleaned.
       
  2273  * @param array $protocols An array of acceptable protocols.
       
  2274  * @return string The cleaned URL.
       
  2275  */
       
  2276 function sanitize_url( $url, $protocols = null ) {
       
  2277 	return clean_url( $url, $protocols, 'db' );
       
  2278 }
  2590 }
  2279 
  2591 
  2280 /**
  2592 /**
  2281  * Convert entities, while preserving already-encoded entities.
  2593  * Convert entities, while preserving already-encoded entities.
  2282  *
  2594  *
  2294 }
  2606 }
  2295 
  2607 
  2296 /**
  2608 /**
  2297  * Escape single quotes, htmlspecialchar " < > &, and fix line endings.
  2609  * Escape single quotes, htmlspecialchar " < > &, and fix line endings.
  2298  *
  2610  *
  2299  * Escapes text strings for echoing in JS, both inline (for example in onclick="...")
  2611  * Escapes text strings for echoing in JS. It is intended to be used for inline JS
  2300  * and inside <script> tag. Note that the strings have to be in single quotes.
  2612  * (in a tag attribute, for example onclick="..."). Note that the strings have to
  2301  * The filter 'js_escape' is also applied here.
  2613  * be in single quotes. The filter 'js_escape' is also applied here.
  2302  *
  2614  *
  2303  * @since 2.8.0
  2615  * @since 2.8.0
  2304  *
  2616  *
  2305  * @param string $text The text to be escaped.
  2617  * @param string $text The text to be escaped.
  2306  * @return string Escaped text.
  2618  * @return string Escaped text.
  2313 	$safe_text = str_replace( "\n", '\\n', addslashes( $safe_text ) );
  2625 	$safe_text = str_replace( "\n", '\\n', addslashes( $safe_text ) );
  2314 	return apply_filters( 'js_escape', $safe_text, $text );
  2626 	return apply_filters( 'js_escape', $safe_text, $text );
  2315 }
  2627 }
  2316 
  2628 
  2317 /**
  2629 /**
  2318  * Escape single quotes, specialchar double quotes, and fix line endings.
       
  2319  *
       
  2320  * The filter 'js_escape' is also applied by esc_js()
       
  2321  *
       
  2322  * @since 2.0.4
       
  2323  *
       
  2324  * @deprecated 2.8.0
       
  2325  * @see esc_js()
       
  2326  *
       
  2327  * @param string $text The text to be escaped.
       
  2328  * @return string Escaped text.
       
  2329  */
       
  2330 function js_escape( $text ) {
       
  2331 	return esc_js( $text );
       
  2332 }
       
  2333 
       
  2334 /**
       
  2335  * Escaping for HTML blocks.
  2630  * Escaping for HTML blocks.
  2336  *
  2631  *
  2337  * @since 2.8.0
  2632  * @since 2.8.0
  2338  *
  2633  *
  2339  * @param string $text
  2634  * @param string $text
  2344 	$safe_text = _wp_specialchars( $safe_text, ENT_QUOTES );
  2639 	$safe_text = _wp_specialchars( $safe_text, ENT_QUOTES );
  2345 	return apply_filters( 'esc_html', $safe_text, $text );
  2640 	return apply_filters( 'esc_html', $safe_text, $text );
  2346 }
  2641 }
  2347 
  2642 
  2348 /**
  2643 /**
  2349  * Escaping for HTML blocks
       
  2350  * @deprecated 2.8.0
       
  2351  * @see esc_html()
       
  2352  */
       
  2353 function wp_specialchars( $string, $quote_style = ENT_NOQUOTES, $charset = false, $double_encode = false ) {
       
  2354 	if ( func_num_args() > 1 ) { // Maintain backwards compat for people passing additional args
       
  2355 		$args = func_get_args();
       
  2356 		return call_user_func_array( '_wp_specialchars', $args );
       
  2357 	} else {
       
  2358 		return esc_html( $string );
       
  2359 	}
       
  2360 }
       
  2361 
       
  2362 /**
       
  2363  * Escaping for HTML attributes.
  2644  * Escaping for HTML attributes.
  2364  *
  2645  *
  2365  * @since 2.8.0
  2646  * @since 2.8.0
  2366  *
  2647  *
  2367  * @param string $text
  2648  * @param string $text
  2372 	$safe_text = _wp_specialchars( $safe_text, ENT_QUOTES );
  2653 	$safe_text = _wp_specialchars( $safe_text, ENT_QUOTES );
  2373 	return apply_filters( 'attribute_escape', $safe_text, $text );
  2654 	return apply_filters( 'attribute_escape', $safe_text, $text );
  2374 }
  2655 }
  2375 
  2656 
  2376 /**
  2657 /**
  2377  * Escaping for HTML attributes.
  2658  * Escaping for textarea values.
  2378  *
  2659  *
  2379  * @since 2.0.6
  2660  * @since 3.1
  2380  *
       
  2381  * @deprecated 2.8.0
       
  2382  * @see esc_attr()
       
  2383  *
  2661  *
  2384  * @param string $text
  2662  * @param string $text
  2385  * @return string
  2663  * @return string
  2386  */
  2664  */
  2387 function attribute_escape( $text ) {
  2665 function esc_textarea( $text ) {
  2388 	return esc_attr( $text );
  2666 	$safe_text = htmlspecialchars( $text, ENT_QUOTES );
       
  2667 	return apply_filters( 'esc_textarea', $safe_text, $text );
  2389 }
  2668 }
  2390 
  2669 
  2391 /**
  2670 /**
  2392  * Escape a HTML tag name.
  2671  * Escape a HTML tag name.
  2393  *
  2672  *
  2395  *
  2674  *
  2396  * @param string $tag_name
  2675  * @param string $tag_name
  2397  * @return string
  2676  * @return string
  2398  */
  2677  */
  2399 function tag_escape($tag_name) {
  2678 function tag_escape($tag_name) {
  2400 	$safe_tag = strtolower( preg_replace('/[^a-zA-Z_:]/', '', $tag_name) );
  2679 	$safe_tag = strtolower( preg_replace('/[^a-zA-Z0-9_:]/', '', $tag_name) );
  2401 	return apply_filters('tag_escape', $safe_tag, $tag_name);
  2680 	return apply_filters('tag_escape', $safe_tag, $tag_name);
  2402 }
  2681 }
  2403 
  2682 
  2404 /**
  2683 /**
  2405  * Escapes text for SQL LIKE special characters % and _.
  2684  * Escapes text for SQL LIKE special characters % and _.
  2440  * @param string $value The unsanitised value.
  2719  * @param string $value The unsanitised value.
  2441  * @return string Sanitized value.
  2720  * @return string Sanitized value.
  2442  */
  2721  */
  2443 function sanitize_option($option, $value) {
  2722 function sanitize_option($option, $value) {
  2444 
  2723 
  2445 	switch ($option) {
  2724 	switch ( $option ) {
  2446 		case 'admin_email':
  2725 		case 'admin_email' :
  2447 			$value = sanitize_email($value);
  2726 		case 'new_admin_email' :
       
  2727 			$value = sanitize_email( $value );
       
  2728 			if ( ! is_email( $value ) ) {
       
  2729 				$value = get_option( $option ); // Resets option to stored value in the case of failed sanitization
       
  2730 				if ( function_exists( 'add_settings_error' ) )
       
  2731 					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.' ) );
       
  2732 			}
  2448 			break;
  2733 			break;
  2449 
  2734 
  2450 		case 'thumbnail_size_w':
  2735 		case 'thumbnail_size_w':
  2451 		case 'thumbnail_size_h':
  2736 		case 'thumbnail_size_h':
  2452 		case 'medium_size_w':
  2737 		case 'medium_size_w':
  2456 		case 'embed_size_h':
  2741 		case 'embed_size_h':
  2457 		case 'default_post_edit_rows':
  2742 		case 'default_post_edit_rows':
  2458 		case 'mailserver_port':
  2743 		case 'mailserver_port':
  2459 		case 'comment_max_links':
  2744 		case 'comment_max_links':
  2460 		case 'page_on_front':
  2745 		case 'page_on_front':
       
  2746 		case 'page_for_posts':
  2461 		case 'rss_excerpt_length':
  2747 		case 'rss_excerpt_length':
  2462 		case 'default_category':
  2748 		case 'default_category':
  2463 		case 'default_email_category':
  2749 		case 'default_email_category':
  2464 		case 'default_link_category':
  2750 		case 'default_link_category':
  2465 		case 'close_comments_days_old':
  2751 		case 'close_comments_days_old':
  2466 		case 'comments_per_page':
  2752 		case 'comments_per_page':
  2467 		case 'thread_comments_depth':
  2753 		case 'thread_comments_depth':
  2468 		case 'users_can_register':
  2754 		case 'users_can_register':
       
  2755 		case 'start_of_week':
  2469 			$value = absint( $value );
  2756 			$value = absint( $value );
  2470 			break;
  2757 			break;
  2471 
  2758 
  2472 		case 'embed_size_w':
  2759 		case 'embed_size_w':
  2473 			if ( '' !== $value )
  2760 			if ( '' !== $value )
  2475 			break;
  2762 			break;
  2476 
  2763 
  2477 		case 'posts_per_page':
  2764 		case 'posts_per_page':
  2478 		case 'posts_per_rss':
  2765 		case 'posts_per_rss':
  2479 			$value = (int) $value;
  2766 			$value = (int) $value;
  2480 			if ( empty($value) ) $value = 1;
  2767 			if ( empty($value) )
  2481 			if ( $value < -1 ) $value = abs($value);
  2768 				$value = 1;
       
  2769 			if ( $value < -1 )
       
  2770 				$value = abs($value);
  2482 			break;
  2771 			break;
  2483 
  2772 
  2484 		case 'default_ping_status':
  2773 		case 'default_ping_status':
  2485 		case 'default_comment_status':
  2774 		case 'default_comment_status':
  2486 			// Options that if not there have 0 value but need to be something like "closed"
  2775 			// Options that if not there have 0 value but need to be something like "closed"
  2516 		case 'gmt_offset':
  2805 		case 'gmt_offset':
  2517 			$value = preg_replace('/[^0-9:.-]/', '', $value); // strips slashes
  2806 			$value = preg_replace('/[^0-9:.-]/', '', $value); // strips slashes
  2518 			break;
  2807 			break;
  2519 
  2808 
  2520 		case 'siteurl':
  2809 		case 'siteurl':
       
  2810 			if ( (bool)preg_match( '#http(s?)://(.+)#i', $value) ) {
       
  2811 				$value = esc_url_raw($value);
       
  2812 			} else {
       
  2813 				$value = get_option( $option ); // Resets option to stored value in the case of failed sanitization
       
  2814 				if ( function_exists('add_settings_error') )
       
  2815 					add_settings_error('siteurl', 'invalid_siteurl', __('The WordPress address you entered did not appear to be a valid URL. Please enter a valid URL.'));
       
  2816 			}
       
  2817 			break;
       
  2818 
  2521 		case 'home':
  2819 		case 'home':
  2522 			$value = stripslashes($value);
  2820 			if ( (bool)preg_match( '#http(s?)://(.+)#i', $value) ) {
  2523 			$value = esc_url($value);
  2821 				$value = esc_url_raw($value);
       
  2822 			} else {
       
  2823 				$value = get_option( $option ); // Resets option to stored value in the case of failed sanitization
       
  2824 				if ( function_exists('add_settings_error') )
       
  2825 					add_settings_error('home', 'invalid_home', __('The Site address you entered did not appear to be a valid URL. Please enter a valid URL.'));
       
  2826 			}
  2524 			break;
  2827 			break;
  2525 		default :
  2828 
  2526 			$value = apply_filters("sanitize_option_{$option}", $value, $option);
  2829 		case 'WPLANG':
       
  2830 			$allowed = get_available_languages();
       
  2831 			if ( ! in_array( $value, $allowed ) && ! empty( $value ) )
       
  2832 				$value = get_option( $option );
  2527 			break;
  2833 			break;
  2528 	}
  2834 
       
  2835 		case 'timezone_string':
       
  2836 			$allowed_zones = timezone_identifiers_list();
       
  2837 			if ( ! in_array( $value, $allowed_zones ) && ! empty( $value ) ) {
       
  2838 				$value = get_option( $option ); // Resets option to stored value in the case of failed sanitization
       
  2839 				if ( function_exists('add_settings_error') )
       
  2840 					add_settings_error('timezone_string', 'invalid_timezone_string', __('The timezone you have entered is not valid. Please select a valid timezone.') );
       
  2841 			}
       
  2842 			break;
       
  2843 
       
  2844 		case 'permalink_structure':
       
  2845 		case 'category_base':
       
  2846 		case 'tag_base':
       
  2847 			$value = esc_url_raw( $value );
       
  2848 			$value = str_replace( 'http://', '', $value );
       
  2849 			break;
       
  2850 	}
       
  2851 
       
  2852 	$value = apply_filters("sanitize_option_{$option}", $value, $option);
  2529 
  2853 
  2530 	return $value;
  2854 	return $value;
  2531 }
  2855 }
  2532 
  2856 
  2533 /**
  2857 /**
  2614 		if ( false === $end )
  2938 		if ( false === $end )
  2615 			$end = $len;
  2939 			$end = $len;
  2616 		$fragment = substr($pattern, $start, $end - $start);
  2940 		$fragment = substr($pattern, $start, $end - $start);
  2617 
  2941 
  2618 		// Fragment has a specifier
  2942 		// Fragment has a specifier
  2619 		if ( $pattern{$start} == '%' ) {
  2943 		if ( $pattern[$start] == '%' ) {
  2620 			// Find numbered arguments or take the next one in order
  2944 			// Find numbered arguments or take the next one in order
  2621 			if ( preg_match('/^%(\d+)\$/', $fragment, $matches) ) {
  2945 			if ( preg_match('/^%(\d+)\$/', $fragment, $matches) ) {
  2622 				$arg = isset($args[$matches[1]]) ? $args[$matches[1]] : '';
  2946 				$arg = isset($args[$matches[1]]) ? $args[$matches[1]] : '';
  2623 				$fragment = str_replace("%{$matches[1]}$", '%', $fragment);
  2947 				$fragment = str_replace("%{$matches[1]}$", '%', $fragment);
  2624 			} else {
  2948 			} else {
  2663 	if ( empty($args) )
  2987 	if ( empty($args) )
  2664 		return '';
  2988 		return '';
  2665 
  2989 
  2666 	// Translate and filter the delimiter set (avoid ampersands and entities here)
  2990 	// Translate and filter the delimiter set (avoid ampersands and entities here)
  2667 	$l = apply_filters('wp_sprintf_l', array(
  2991 	$l = apply_filters('wp_sprintf_l', array(
  2668 		/* translators: used between list items, there is a space after the coma */
  2992 		/* translators: used between list items, there is a space after the comma */
  2669 		'between'          => __(', '),
  2993 		'between'          => __(', '),
  2670 		/* translators: used between list items, there is a space after the and */
  2994 		/* translators: used between list items, there is a space after the and */
  2671 		'between_last_two' => __(', and '),
  2995 		'between_last_two' => __(', and '),
  2672 		/* translators: used between only two list items, there is a space after the and */
  2996 		/* translators: used between only two list items, there is a space after the and */
  2673 		'between_only_two' => __(' and '),
  2997 		'between_only_two' => __(' and '),
  2723  * @param string $base The base URL to prefix to links.
  3047  * @param string $base The base URL to prefix to links.
  2724  * @param array $attrs The attributes which should be processed.
  3048  * @param array $attrs The attributes which should be processed.
  2725  * @return string The processed content.
  3049  * @return string The processed content.
  2726  */
  3050  */
  2727 function links_add_base_url( $content, $base, $attrs = array('src', 'href') ) {
  3051 function links_add_base_url( $content, $base, $attrs = array('src', 'href') ) {
       
  3052 	global $_links_add_base;
       
  3053 	$_links_add_base = $base;
  2728 	$attrs = implode('|', (array)$attrs);
  3054 	$attrs = implode('|', (array)$attrs);
  2729 	return preg_replace_callback("!($attrs)=(['\"])(.+?)\\2!i",
  3055 	return preg_replace_callback( "!($attrs)=(['\"])(.+?)\\2!i", '_links_add_base', $content );
  2730 			create_function('$m', 'return _links_add_base($m, "' . $base . '");'),
       
  2731 			$content);
       
  2732 }
  3056 }
  2733 
  3057 
  2734 /**
  3058 /**
  2735  * Callback to add a base url to relative links in passed content.
  3059  * Callback to add a base url to relative links in passed content.
  2736  *
  3060  *
  2737  * @since 2.7.0
  3061  * @since 2.7.0
  2738  * @access private
  3062  * @access private
  2739  *
  3063  *
  2740  * @param string $m The matched link.
  3064  * @param string $m The matched link.
  2741  * @param string $base The base URL to prefix to links.
       
  2742  * @return string The processed link.
  3065  * @return string The processed link.
  2743  */
  3066  */
  2744 function _links_add_base($m, $base) {
  3067 function _links_add_base($m) {
       
  3068 	global $_links_add_base;
  2745 	//1 = attribute name  2 = quotation mark  3 = URL
  3069 	//1 = attribute name  2 = quotation mark  3 = URL
  2746 	return $m[1] . '=' . $m[2] .
  3070 	return $m[1] . '=' . $m[2] .
  2747 		(strpos($m[3], 'http://') === false ?
  3071 		( preg_match( '#^(\w{1,20}):#', $m[3], $protocol ) && in_array( $protocol[1], wp_allowed_protocols() ) ?
  2748 			path_join($base, $m[3]) :
  3072 			$m[3] :
  2749 			$m[3])
  3073 			path_join( $_links_add_base, $m[3] ) )
  2750 		. $m[2];
  3074 		. $m[2];
  2751 }
  3075 }
  2752 
  3076 
  2753 /**
  3077 /**
  2754  * Adds a Target attribute to all links in passed content.
  3078  * Adds a Target attribute to all links in passed content.
  2755  *
  3079  *
  2756  * This function by default only applies to <a> tags, however this can be
  3080  * This function by default only applies to <a> tags, however this can be
  2757  * modified by the 3rd param.
  3081  * modified by the 3rd param.
  2758  *
  3082  *
  2759  * <b>NOTE:</b> Any current target attributed will be striped and replaced.
  3083  * <b>NOTE:</b> Any current target attributed will be stripped and replaced.
  2760  *
  3084  *
  2761  * @since 2.7.0
  3085  * @since 2.7.0
  2762  *
  3086  *
  2763  * @param string $content String to search for links in.
  3087  * @param string $content String to search for links in.
  2764  * @param string $target The Target to add to the links.
  3088  * @param string $target The Target to add to the links.
  2765  * @param array $tags An array of tags to apply to.
  3089  * @param array $tags An array of tags to apply to.
  2766  * @return string The processed content.
  3090  * @return string The processed content.
  2767  */
  3091  */
  2768 function links_add_target( $content, $target = '_blank', $tags = array('a') ) {
  3092 function links_add_target( $content, $target = '_blank', $tags = array('a') ) {
       
  3093 	global $_links_add_target;
       
  3094 	$_links_add_target = $target;
  2769 	$tags = implode('|', (array)$tags);
  3095 	$tags = implode('|', (array)$tags);
  2770 	return preg_replace_callback("!<($tags)(.+?)>!i",
  3096 	return preg_replace_callback( "!<($tags)(.+?)>!i", '_links_add_target', $content );
  2771 			create_function('$m', 'return _links_add_target($m, "' . $target . '");'),
       
  2772 			$content);
       
  2773 }
  3097 }
  2774 
  3098 
  2775 /**
  3099 /**
  2776  * Callback to add a target attribute to all links in passed content.
  3100  * Callback to add a target attribute to all links in passed content.
  2777  *
  3101  *
  2778  * @since 2.7.0
  3102  * @since 2.7.0
  2779  * @access private
  3103  * @access private
  2780  *
  3104  *
  2781  * @param string $m The matched link.
  3105  * @param string $m The matched link.
  2782  * @param string $target The Target to add to the links.
       
  2783  * @return string The processed link.
  3106  * @return string The processed link.
  2784  */
  3107  */
  2785 function _links_add_target( $m, $target ) {
  3108 function _links_add_target( $m ) {
       
  3109 	global $_links_add_target;
  2786 	$tag = $m[1];
  3110 	$tag = $m[1];
  2787 	$link = preg_replace('|(target=[\'"](.*?)[\'"])|i', '', $m[2]);
  3111 	$link = preg_replace('|(target=[\'"](.*?)[\'"])|i', '', $m[2]);
  2788 	return '<' . $tag . $link . ' target="' . $target . '">';
  3112 	return '<' . $tag . $link . ' target="' . esc_attr( $_links_add_target ) . '">';
  2789 }
  3113 }
  2790 
  3114 
  2791 // normalize EOL characters and strip duplicate whitespace
  3115 // normalize EOL characters and strip duplicate whitespace
  2792 function normalize_whitespace( $str ) {
  3116 function normalize_whitespace( $str ) {
  2793 	$str  = trim($str);
  3117 	$str  = trim($str);
  2810 	$string = strip_tags($string);
  3134 	$string = strip_tags($string);
  2811 
  3135 
  2812 	if ( $remove_breaks )
  3136 	if ( $remove_breaks )
  2813 		$string = preg_replace('/[\r\n\t ]+/', ' ', $string);
  3137 		$string = preg_replace('/[\r\n\t ]+/', ' ', $string);
  2814 
  3138 
  2815 	return trim($string);
  3139 	return trim( $string );
  2816 }
  3140 }
  2817 
  3141 
  2818 /**
  3142 /**
  2819  * Sanitize a string from user input or from the db
  3143  * Sanitize a string from user input or from the db
  2820  *
  3144  *
  2821  * check for invalid UTF-8,
  3145  * check for invalid UTF-8,
  2822  * Convert single < characters to entity,
  3146  * Convert single < characters to entity,
  2823  * strip all tags,
  3147  * strip all tags,
  2824  * remove line breaks, tabs and extra whitre space,
  3148  * remove line breaks, tabs and extra white space,
  2825  * strip octets.
  3149  * strip octets.
  2826  *
  3150  *
  2827  * @since 2.9
  3151  * @since 2.9.0
  2828  *
  3152  *
  2829  * @param string $str
  3153  * @param string $str
  2830  * @return string
  3154  * @return string
  2831  */
  3155  */
  2832 function sanitize_text_field($str) {
  3156 function sanitize_text_field($str) {
  2833 	$filtered = wp_check_invalid_utf8( $str );
  3157 	$filtered = wp_check_invalid_utf8( $str );
  2834 
  3158 
  2835 	if ( strpos($filtered, '<') !== false ) {
  3159 	if ( strpos($filtered, '<') !== false ) {
  2836 		$filtered = wp_pre_kses_less_than( $filtered );
  3160 		$filtered = wp_pre_kses_less_than( $filtered );
       
  3161 		// This will strip extra whitespace for us.
  2837 		$filtered = wp_strip_all_tags( $filtered, true );
  3162 		$filtered = wp_strip_all_tags( $filtered, true );
  2838 	} else {
  3163 	} else {
  2839 		 $filtered = trim( preg_replace('/[\r\n\t ]+/', ' ', $filtered) );
  3164 		$filtered = trim( preg_replace('/[\r\n\t ]+/', ' ', $filtered) );
  2840 	}
  3165 	}
  2841 
  3166 
  2842 	$match = array();
  3167 	$match = array();
  2843 	while ( preg_match('/%[a-f0-9]{2}/i', $filtered, $match) )
  3168 	$found = false;
       
  3169 	while ( preg_match('/%[a-f0-9]{2}/i', $filtered, $match) ) {
  2844 		$filtered = str_replace($match[0], '', $filtered);
  3170 		$filtered = str_replace($match[0], '', $filtered);
       
  3171 		$found = true;
       
  3172 	}
       
  3173 
       
  3174 	if ( $found ) {
       
  3175 		// Strip out the whitespace that may now exist after removing the octets.
       
  3176 		$filtered = trim( preg_replace('/ +/', ' ', $filtered) );
       
  3177 	}
  2845 
  3178 
  2846 	return apply_filters('sanitize_text_field', $filtered, $str);
  3179 	return apply_filters('sanitize_text_field', $filtered, $str);
  2847 }
  3180 }
  2848 
  3181 
  2849 ?>
  3182 /**
       
  3183  * i18n friendly version of basename()
       
  3184  *
       
  3185  * @since 3.1.0
       
  3186  *
       
  3187  * @param string $path A path.
       
  3188  * @param string $suffix If the filename ends in suffix this will also be cut off.
       
  3189  * @return string
       
  3190  */
       
  3191 function wp_basename( $path, $suffix = '' ) {
       
  3192 	return urldecode( basename( str_replace( '%2F', '/', urlencode( $path ) ), $suffix ) );
       
  3193 }
       
  3194 
       
  3195 /**
       
  3196  * Forever eliminate "Wordpress" from the planet (or at least the little bit we can influence).
       
  3197  *
       
  3198  * Violating our coding standards for a good function name.
       
  3199  *
       
  3200  * @since 3.0.0
       
  3201  */
       
  3202 function capital_P_dangit( $text ) {
       
  3203 	// Simple replacement for titles
       
  3204 	if ( 'the_title' === current_filter() )
       
  3205 		return str_replace( 'Wordpress', 'WordPress', $text );
       
  3206 	// Still here? Use the more judicious replacement
       
  3207 	static $dblq = false;
       
  3208 	if ( false === $dblq )
       
  3209 		$dblq = _x('&#8220;', 'opening curly quote');
       
  3210 	return str_replace(
       
  3211 		array( ' Wordpress', '&#8216;Wordpress', $dblq . 'Wordpress', '>Wordpress', '(Wordpress' ),
       
  3212 		array( ' WordPress', '&#8216;WordPress', $dblq . 'WordPress', '>WordPress', '(WordPress' ),
       
  3213 	$text );
       
  3214 
       
  3215 }
       
  3216 
       
  3217 /**
       
  3218  * Sanitize a mime type
       
  3219  *
       
  3220  * @since 3.1.3
       
  3221  *
       
  3222  * @param string $mime_type Mime type
       
  3223  * @return string Sanitized mime type
       
  3224  */
       
  3225 function sanitize_mime_type( $mime_type ) {
       
  3226 	$sani_mime_type = preg_replace( '/[^-+*.a-zA-Z0-9\/]/', '', $mime_type );
       
  3227 	return apply_filters( 'sanitize_mime_type', $sani_mime_type, $mime_type );
       
  3228 }
       
  3229 
       
  3230 /**
       
  3231  * Sanitize space or carriage return separated URLs that are used to send trackbacks.
       
  3232  *
       
  3233  * @since 3.4.0
       
  3234  *
       
  3235  * @param string $to_ping Space or carriage return separated URLs
       
  3236  * @return string URLs starting with the http or https protocol, separated by a carriage return.
       
  3237  */
       
  3238 function sanitize_trackback_urls( $to_ping ) {
       
  3239 	$urls_to_ping = preg_split( '/[\r\n\t ]/', trim( $to_ping ), -1, PREG_SPLIT_NO_EMPTY );
       
  3240 	foreach ( $urls_to_ping as $k => $url ) {
       
  3241 		if ( !preg_match( '#^https?://.#i', $url ) )
       
  3242 			unset( $urls_to_ping[$k] );
       
  3243 	}
       
  3244 	$urls_to_ping = array_map( 'esc_url_raw', $urls_to_ping );
       
  3245 	$urls_to_ping = implode( "\n", $urls_to_ping );
       
  3246 	return apply_filters( 'sanitize_trackback_urls', $urls_to_ping, $to_ping );
       
  3247 }