web/wp-includes/formatting.php
changeset 204 09a1c134465b
parent 194 32102edaa81b
equal deleted inserted replaced
203:f507feede89a 204:09a1c134465b
    98 		$dynamic_characters = array_keys( $dynamic );
    98 		$dynamic_characters = array_keys( $dynamic );
    99 		$dynamic_replacements = array_values( $dynamic );
    99 		$dynamic_replacements = array_values( $dynamic );
   100 	}
   100 	}
   101 
   101 
   102 	// Transform into regexp sub-expression used in _wptexturize_pushpop_element
   102 	// Transform into regexp sub-expression used in _wptexturize_pushpop_element
   103 	// Must do this everytime in case plugins use these filters in a context sensitive manner
   103 	// Must do this every time in case plugins use these filters in a context sensitive manner
   104 	$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) ) . ')';
   105 	$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) ) . ')';
   106 
   106 
   107 	$no_texturize_tags_stack = array();
   107 	$no_texturize_tags_stack = array();
   108 	$no_texturize_shortcodes_stack = array();
   108 	$no_texturize_shortcodes_stack = array();
   139  *
   139  *
   140  * @param string $text Text to check. First character is assumed to be $opening
   140  * @param string $text Text to check. First character is assumed to be $opening
   141  * @param array $stack Array used as stack of opened tag elements
   141  * @param array $stack Array used as stack of opened tag elements
   142  * @param string $disabled_elements Tags to match against formatted as regexp sub-expression
   142  * @param string $disabled_elements Tags to match against formatted as regexp sub-expression
   143  * @param string $opening Tag opening character, assumed to be 1 character long
   143  * @param string $opening Tag opening character, assumed to be 1 character long
   144  * @param string $opening Tag closing  character
   144  * @param string $closing Tag closing character
   145  * @return object
       
   146  */
   145  */
   147 function _wptexturize_pushpop_element($text, &$stack, $disabled_elements, $opening = '<', $closing = '>') {
   146 function _wptexturize_pushpop_element($text, &$stack, $disabled_elements, $opening = '<', $closing = '>') {
   148 	// Check if it is a closing tag -- otherwise assume opening tag
   147 	// Check if it is a closing tag -- otherwise assume opening tag
   149 	if (strncmp($opening . '/', $text, 2)) {
   148 	if (strncmp($opening . '/', $text, 2)) {
   150 		// Opening? Check $text+1 against disabled elements
   149 		// Opening? Check $text+1 against disabled elements
   219 		$pee .= $last_pee;
   218 		$pee .= $last_pee;
   220 	}
   219 	}
   221 
   220 
   222 	$pee = preg_replace('|<br />\s*<br />|', "\n\n", $pee);
   221 	$pee = preg_replace('|<br />\s*<br />|', "\n\n", $pee);
   223 	// Space things out a little
   222 	// Space things out a little
   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)';
   223 	$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|noscript|samp|legend|section|article|aside|hgroup|header|footer|nav|figure|figcaption|details|menu|summary)';
   225 	$pee = preg_replace('!(<' . $allblocks . '[^>]*>)!', "\n$1", $pee);
   224 	$pee = preg_replace('!(<' . $allblocks . '[^>]*>)!', "\n$1", $pee);
   226 	$pee = preg_replace('!(</' . $allblocks . '>)!', "$1\n\n", $pee);
   225 	$pee = preg_replace('!(</' . $allblocks . '>)!', "$1\n\n", $pee);
   227 	$pee = str_replace(array("\r\n", "\r"), "\n", $pee); // cross-platform newlines
   226 	$pee = str_replace(array("\r\n", "\r"), "\n", $pee); // cross-platform newlines
   228 	if ( strpos($pee, '<object') !== false ) {
   227 	if ( strpos($pee, '<object') !== false ) {
   229 		$pee = preg_replace('|\s*<param([^>]*)>\s*|', "<param$1>", $pee); // no pee inside object/embed
   228 		$pee = preg_replace('|\s*<param([^>]*)>\s*|', "<param$1>", $pee); // no pee inside object/embed
   262  * Newline preservation help function for wpautop
   261  * Newline preservation help function for wpautop
   263  *
   262  *
   264  * @since 3.1.0
   263  * @since 3.1.0
   265  * @access private
   264  * @access private
   266  * @param array $matches preg_replace_callback matches array
   265  * @param array $matches preg_replace_callback matches array
   267  * @returns string
   266  * @return string
   268  */
   267  */
   269 function _autop_newline_preservation_helper( $matches ) {
   268 function _autop_newline_preservation_helper( $matches ) {
   270 	return str_replace("\n", "<WPPreserveNewline />", $matches[0]);
   269 	return str_replace("\n", "<WPPreserveNewline />", $matches[0]);
   271 }
   270 }
   272 
   271 
   294 		. '<p>'                              // Opening paragraph
   293 		. '<p>'                              // Opening paragraph
   295 		. '\\s*+'                            // Optional leading whitespace
   294 		. '\\s*+'                            // Optional leading whitespace
   296 		. '('                                // 1: The shortcode
   295 		. '('                                // 1: The shortcode
   297 		.     '\\['                          // Opening bracket
   296 		.     '\\['                          // Opening bracket
   298 		.     "($tagregexp)"                 // 2: Shortcode name
   297 		.     "($tagregexp)"                 // 2: Shortcode name
   299 		.     '\\b'                          // Word boundary
   298 		.     '(?![\\w-])'                   // Not followed by word character or hyphen
   300 		                                     // Unroll the loop: Inside the opening shortcode tag
   299 		                                     // Unroll the loop: Inside the opening shortcode tag
   301 		.     '[^\\]\\/]*'                   // Not a closing bracket or forward slash
   300 		.     '[^\\]\\/]*'                   // Not a closing bracket or forward slash
   302 		.     '(?:'
   301 		.     '(?:'
   303 		.         '\\/(?!\\])'               // A forward slash not followed by a closing bracket
   302 		.         '\\/(?!\\])'               // A forward slash not followed by a closing bracket
   304 		.         '[^\\]\\/]*'               // Not a closing bracket or forward slash
   303 		.         '[^\\]\\/]*'               // Not a closing bracket or forward slash
   768 		chr(225).chr(187).chr(152) => 'O', chr(225).chr(187).chr(153) => 'o',
   767 		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',
   768 		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',
   769 		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',
   770 		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',
   771 		chr(225).chr(187).chr(180) => 'Y', chr(225).chr(187).chr(181) => 'y',
       
   772 		// Vowels with diacritic (Chinese, Hanyu Pinyin)
       
   773 		chr(201).chr(145) => 'a',
       
   774 		// macron
       
   775 		chr(199).chr(149) => 'U', chr(199).chr(150) => 'u',
       
   776 		// acute accent
       
   777 		chr(199).chr(151) => 'U', chr(199).chr(152) => 'u',
       
   778 		// caron
       
   779 		chr(199).chr(141) => 'A', chr(199).chr(142) => 'a',
       
   780 		chr(199).chr(143) => 'I', chr(199).chr(144) => 'i',
       
   781 		chr(199).chr(145) => 'O', chr(199).chr(146) => 'o',
       
   782 		chr(199).chr(147) => 'U', chr(199).chr(148) => 'u',
       
   783 		chr(199).chr(153) => 'U', chr(199).chr(154) => 'u',
       
   784 		// grave accent
       
   785 		chr(199).chr(155) => 'U', chr(199).chr(156) => 'u',
   773 		);
   786 		);
   774 
   787 
   775 		$string = strtr($string, $chars);
   788 		$string = strtr($string, $chars);
   776 	} else {
   789 	} else {
   777 		// Assume ISO-8859-1 if not UTF-8
   790 		// Assume ISO-8859-1 if not UTF-8
   984 			// curly quotes
   997 			// curly quotes
   985 			'%e2%80%98', '%e2%80%99', '%e2%80%9c', '%e2%80%9d',
   998 			'%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',
   999 			'%e2%80%9a', '%e2%80%9b', '%e2%80%9e', '%e2%80%9f',
   987 			// copy, reg, deg, hellip and trade
  1000 			// copy, reg, deg, hellip and trade
   988 			'%c2%a9', '%c2%ae', '%c2%b0', '%e2%80%a6', '%e2%84%a2',
  1001 			'%c2%a9', '%c2%ae', '%c2%b0', '%e2%80%a6', '%e2%84%a2',
       
  1002 			// grave accent, acute accent, macron, caron
       
  1003 			'%cc%80', '%cc%81', '%cc%84', '%cc%8c',
   989 		), '', $title );
  1004 		), '', $title );
   990 
  1005 
   991 		// Convert times to x
  1006 		// Convert times to x
   992 		$title = str_replace( '%c3%97', 'x', $title );
  1007 		$title = str_replace( '%c3%97', 'x', $title );
   993 	}
  1008 	}
  1007  * RAND().
  1022  * RAND().
  1008  *
  1023  *
  1009  * @since 2.5.1
  1024  * @since 2.5.1
  1010  *
  1025  *
  1011  * @param string $orderby Order by string to be checked.
  1026  * @param string $orderby Order by string to be checked.
  1012  * @return string|false Returns the order by clause if it is a match, false otherwise.
  1027  * @return string|bool Returns the order by clause if it is a match, false otherwise.
  1013  */
  1028  */
  1014 function sanitize_sql_orderby( $orderby ){
  1029 function sanitize_sql_orderby( $orderby ){
  1015 	preg_match('/^\s*([a-z0-9_]+(\s+(ASC|DESC))?(\s*,\s*|\s*$))+|^\s*RAND\(\s*\)\s*$/i', $orderby, $obmatches);
  1030 	preg_match('/^\s*([a-z0-9_]+(\s+(ASC|DESC))?(\s*,\s*|\s*$))+|^\s*RAND\(\s*\)\s*$/i', $orderby, $obmatches);
  1016 	if ( !$obmatches )
  1031 	if ( !$obmatches )
  1017 		return false;
  1032 		return false;
  1154 function force_balance_tags( $text ) {
  1169 function force_balance_tags( $text ) {
  1155 	$tagstack = array();
  1170 	$tagstack = array();
  1156 	$stacksize = 0;
  1171 	$stacksize = 0;
  1157 	$tagqueue = '';
  1172 	$tagqueue = '';
  1158 	$newtext = '';
  1173 	$newtext = '';
  1159 	$single_tags = array( 'br', 'hr', 'img', 'input' ); // Known single-entity/self-closing tags
  1174 	// Known single-entity/self-closing tags
  1160 	$nestable_tags = array( 'blockquote', 'div', 'span', 'q' ); // Tags that can be immediately nested within themselves
  1175 	$single_tags = array( 'area', 'base', 'basefont', 'br', 'col', 'command', 'embed', 'frame', 'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param', 'source' );
       
  1176 	// Tags that can be immediately nested within themselves
       
  1177 	$nestable_tags = array( 'blockquote', 'div', 'object', 'q', 'span' );
  1161 
  1178 
  1162 	// WP bug fix for comments - in case you REALLY meant to type '< !--'
  1179 	// WP bug fix for comments - in case you REALLY meant to type '< !--'
  1163 	$text = str_replace('< !--', '<    !--', $text);
  1180 	$text = str_replace('< !--', '<    !--', $text);
  1164 	// WP bug fix for LOVE <3 (and other situations with '<' before a number)
  1181 	// WP bug fix for LOVE <3 (and other situations with '<' before a number)
  1165 	$text = preg_replace('#<([0-9]{1})#', '&lt;$1', $text);
  1182 	$text = preg_replace('#<([0-9]{1})#', '&lt;$1', $text);
  1202 		} else { // Begin Tag
  1219 		} else { // Begin Tag
  1203 			$tag = strtolower($regex[1]);
  1220 			$tag = strtolower($regex[1]);
  1204 
  1221 
  1205 			// Tag Cleaning
  1222 			// Tag Cleaning
  1206 
  1223 
  1207 			// If self-closing or '', don't do anything.
  1224 			// If it's an empty tag "< >", do nothing
  1208 			if ( substr($regex[2],-1) == '/' || $tag == '' ) {
  1225 			if ( '' == $tag ) {
  1209 				// do nothing
  1226 				// do nothing
       
  1227 			}
       
  1228 			// ElseIf it presents itself as a self-closing tag...
       
  1229 			elseif ( substr( $regex[2], -1 ) == '/' ) {
       
  1230 				// ...but it isn't a known single-entity self-closing tag, then don't let it be treated as such and
       
  1231 				// immediately close it with a closing tag (the tag will encapsulate no text as a result)
       
  1232 				if ( ! in_array( $tag, $single_tags ) )
       
  1233 					$regex[2] = trim( substr( $regex[2], 0, -1 ) ) . "></$tag";
  1210 			}
  1234 			}
  1211 			// ElseIf it's a known single-entity tag but it doesn't close itself, do so
  1235 			// ElseIf it's a known single-entity tag but it doesn't close itself, do so
  1212 			elseif ( in_array($tag, $single_tags) ) {
  1236 			elseif ( in_array($tag, $single_tags) ) {
  1213 				$regex[2] .= '/';
  1237 				$regex[2] .= '/';
  1214 			} else {	// Push the tag onto the stack
  1238 			}
       
  1239 			// Else it's not a single-entity tag
       
  1240 			else {
  1215 				// If the top of the stack is the same as the tag we want to push, close previous tag
  1241 				// If the top of the stack is the same as the tag we want to push, close previous tag
  1216 				if ( $stacksize > 0 && !in_array($tag, $nestable_tags) && $tagstack[$stacksize - 1] == $tag ) {
  1242 				if ( $stacksize > 0 && !in_array($tag, $nestable_tags) && $tagstack[$stacksize - 1] == $tag ) {
  1217 					$tagqueue = '</' . array_pop ($tagstack) . '>';
  1243 					$tagqueue = '</' . array_pop( $tagstack ) . '>';
  1218 					$stacksize--;
  1244 					$stacksize--;
  1219 				}
  1245 				}
  1220 				$stacksize = array_push ($tagstack, $tag);
  1246 				$stacksize = array_push( $tagstack, $tag );
  1221 			}
  1247 			}
  1222 
  1248 
  1223 			// Attributes
  1249 			// Attributes
  1224 			$attributes = $regex[2];
  1250 			$attributes = $regex[2];
  1225 			if( !empty($attributes) )
  1251 			if( ! empty( $attributes ) && $attributes[0] != '>' )
  1226 				$attributes = ' '.$attributes;
  1252 				$attributes = ' ' . $attributes;
  1227 
  1253 
  1228 			$tag = '<' . $tag . $attributes . '>';
  1254 			$tag = '<' . $tag . $attributes . '>';
  1229 			//If already queuing a close tag, then put this tag on, too
  1255 			//If already queuing a close tag, then put this tag on, too
  1230 			if ( !empty($tagqueue) ) {
  1256 			if ( !empty($tagqueue) ) {
  1231 				$tagqueue .= $tag;
  1257 				$tagqueue .= $tag;
  1379  * If an array is passed, the array_map() function causes a callback to pass the
  1405  * If an array is passed, the array_map() function causes a callback to pass the
  1380  * value back to the function. The slashes from this value will removed.
  1406  * value back to the function. The slashes from this value will removed.
  1381  *
  1407  *
  1382  * @since 2.0.0
  1408  * @since 2.0.0
  1383  *
  1409  *
  1384  * @param array|string $value The array or string to be stripped.
  1410  * @param mixed $value The value to be stripped.
  1385  * @return array|string Stripped array (or string in the callback).
  1411  * @return mixed Stripped value.
  1386  */
  1412  */
  1387 function stripslashes_deep($value) {
  1413 function stripslashes_deep($value) {
  1388 	if ( is_array($value) ) {
  1414 	if ( is_array($value) ) {
  1389 		$value = array_map('stripslashes_deep', $value);
  1415 		$value = array_map('stripslashes_deep', $value);
  1390 	} elseif ( is_object($value) ) {
  1416 	} elseif ( is_object($value) ) {
  1391 		$vars = get_object_vars( $value );
  1417 		$vars = get_object_vars( $value );
  1392 		foreach ($vars as $key=>$data) {
  1418 		foreach ($vars as $key=>$data) {
  1393 			$value->{$key} = stripslashes_deep( $data );
  1419 			$value->{$key} = stripslashes_deep( $data );
  1394 		}
  1420 		}
  1395 	} else {
  1421 	} elseif ( is_string( $value ) ) {
  1396 		$value = stripslashes($value);
  1422 		$value = stripslashes($value);
  1397 	}
  1423 	}
  1398 
  1424 
  1399 	return $value;
  1425 	return $value;
  1400 }
  1426 }
  1621  * </code>
  1647  * </code>
  1622  *
  1648  *
  1623  * @since 3.4.0
  1649  * @since 3.4.0
  1624  * @access private
  1650  * @access private
  1625  *
  1651  *
  1626  * @param string $string The string to split
  1652  * @param string $string The string to split.
  1627  * @param    int $goal   The desired chunk length.
  1653  * @param int $goal The desired chunk length.
  1628  * @return array Numeric array of chunks.
  1654  * @return array Numeric array of chunks.
  1629  */
  1655  */
  1630 function _split_str_by_whitespace( $string, $goal ) {
  1656 function _split_str_by_whitespace( $string, $goal ) {
  1631 	$chunks = array();
  1657 	$chunks = array();
  1632 
  1658 
  1820 
  1846 
  1821 /**
  1847 /**
  1822  * Convert to ASCII from email subjects.
  1848  * Convert to ASCII from email subjects.
  1823  *
  1849  *
  1824  * @since 1.2.0
  1850  * @since 1.2.0
  1825  * @usedby wp_mail() handles charsets in email subjects
       
  1826  *
  1851  *
  1827  * @param string $string Subject line
  1852  * @param string $string Subject line
  1828  * @return string Converted string to ASCII
  1853  * @return string Converted string to ASCII
  1829  */
  1854  */
  1830 function wp_iso_descrambler($string) {
  1855 function wp_iso_descrambler($string) {
  1837 		return $subject;
  1862 		return $subject;
  1838 	}
  1863 	}
  1839 }
  1864 }
  1840 
  1865 
  1841 /**
  1866 /**
  1842  * Helper function to convert hex encoded chars to ascii
  1867  * Helper function to convert hex encoded chars to ASCII
  1843  *
  1868  *
  1844  * @since 3.1.0
  1869  * @since 3.1.0
  1845  * @access private
  1870  * @access private
  1846  * @param array $match the preg_replace_callback matches array
  1871  * @param array $match The preg_replace_callback matches array
       
  1872  * @return array Converted chars
  1847  */
  1873  */
  1848 function _wp_iso_convert( $match ) {
  1874 function _wp_iso_convert( $match ) {
  1849 	return chr( hexdec( strtolower( $match[1] ) ) );
  1875 	return chr( hexdec( strtolower( $match[1] ) ) );
  1850 }
  1876 }
  1851 
  1877 
  1864  * @param string $format The format string for the returned date (default is Y-m-d H:i:s)
  1890  * @param string $format The format string for the returned date (default is Y-m-d H:i:s)
  1865  * @return string GMT version of the date provided.
  1891  * @return string GMT version of the date provided.
  1866  */
  1892  */
  1867 function get_gmt_from_date($string, $format = 'Y-m-d H:i:s') {
  1893 function get_gmt_from_date($string, $format = 'Y-m-d H:i:s') {
  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);
  1894 	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);
       
  1895 	if ( ! $matches )
       
  1896 		return date( $format, 0 );
       
  1897 
  1869 	$tz = get_option('timezone_string');
  1898 	$tz = get_option('timezone_string');
  1870 	if ( $tz ) {
  1899 	if ( $tz ) {
  1871 		date_default_timezone_set( $tz );
  1900 		date_default_timezone_set( $tz );
  1872 		$datetime = new DateTime( $string );
  1901 		$datetime = date_create( $string );
       
  1902 		if ( ! $datetime )
       
  1903 			return date( $format, 0 );
       
  1904 
  1873 		$datetime->setTimezone( new DateTimeZone('UTC') );
  1905 		$datetime->setTimezone( new DateTimeZone('UTC') );
  1874 		$offset = $datetime->getOffset();
  1906 		$offset = $datetime->getOffset();
  1875 		$datetime->modify( '+' . $offset / 3600 . ' hours');
  1907 		$datetime->modify( '+' . $offset / HOUR_IN_SECONDS . ' hours');
  1876 		$string_gmt = gmdate($format, $datetime->format('U'));
  1908 		$string_gmt = gmdate($format, $datetime->format('U'));
  1877 
  1909 
  1878 		date_default_timezone_set('UTC');
  1910 		date_default_timezone_set('UTC');
  1879 	} else {
  1911 	} else {
  1880 		$string_time = gmmktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
  1912 		$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);
  1913 		$string_gmt = gmdate($format, $string_time - get_option('gmt_offset') * HOUR_IN_SECONDS);
  1882 	}
  1914 	}
  1883 	return $string_gmt;
  1915 	return $string_gmt;
  1884 }
  1916 }
  1885 
  1917 
  1886 /**
  1918 /**
  1896  * @return string Formatted date relative to the GMT offset.
  1928  * @return string Formatted date relative to the GMT offset.
  1897  */
  1929  */
  1898 function get_date_from_gmt($string, $format = 'Y-m-d H:i:s') {
  1930 function get_date_from_gmt($string, $format = 'Y-m-d H:i:s') {
  1899 	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);
  1931 	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);
  1900 	$string_time = gmmktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
  1932 	$string_time = gmmktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
  1901 	$string_localtime = gmdate($format, $string_time + get_option('gmt_offset')*3600);
  1933 	$string_localtime = gmdate($format, $string_time + get_option('gmt_offset') * HOUR_IN_SECONDS);
  1902 	return $string_localtime;
  1934 	return $string_localtime;
  1903 }
  1935 }
  1904 
  1936 
  1905 /**
  1937 /**
  1906  * Computes an offset in seconds from an iso8601 timezone.
  1938  * Computes an offset in seconds from an iso8601 timezone.
  1916 		$offset = 0;
  1948 		$offset = 0;
  1917 	} else {
  1949 	} else {
  1918 		$sign    = (substr($timezone, 0, 1) == '+') ? 1 : -1;
  1950 		$sign    = (substr($timezone, 0, 1) == '+') ? 1 : -1;
  1919 		$hours   = intval(substr($timezone, 1, 2));
  1951 		$hours   = intval(substr($timezone, 1, 2));
  1920 		$minutes = intval(substr($timezone, 3, 4)) / 60;
  1952 		$minutes = intval(substr($timezone, 3, 4)) / 60;
  1921 		$offset  = $sign * 3600 * ($hours + $minutes);
  1953 		$offset  = $sign * HOUR_IN_SECONDS * ($hours + $minutes);
  1922 	}
  1954 	}
  1923 	return $offset;
  1955 	return $offset;
  1924 }
  1956 }
  1925 
  1957 
  1926 /**
  1958 /**
  1940 		preg_match('#([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(Z|[\+|\-][0-9]{2,4}){0,1}#', $date_string, $date_bits);
  1972 		preg_match('#([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(Z|[\+|\-][0-9]{2,4}){0,1}#', $date_string, $date_bits);
  1941 
  1973 
  1942 		if (!empty($date_bits[7])) { // we have a timezone, so let's compute an offset
  1974 		if (!empty($date_bits[7])) { // we have a timezone, so let's compute an offset
  1943 			$offset = iso8601_timezone_to_offset($date_bits[7]);
  1975 			$offset = iso8601_timezone_to_offset($date_bits[7]);
  1944 		} else { // we don't have a timezone, so we assume user local timezone (not server's!)
  1976 		} else { // we don't have a timezone, so we assume user local timezone (not server's!)
  1945 			$offset = 3600 * get_option('gmt_offset');
  1977 			$offset = HOUR_IN_SECONDS * get_option('gmt_offset');
  1946 		}
  1978 		}
  1947 
  1979 
  1948 		$timestamp = gmmktime($date_bits[4], $date_bits[5], $date_bits[6], $date_bits[2], $date_bits[3], $date_bits[1]);
  1980 		$timestamp = gmmktime($date_bits[4], $date_bits[5], $date_bits[6], $date_bits[2], $date_bits[3], $date_bits[1]);
  1949 		$timestamp -= $offset;
  1981 		$timestamp -= $offset;
  1950 
  1982 
  2065  * @param int $from Unix timestamp from which the difference begins.
  2097  * @param int $from Unix timestamp from which the difference begins.
  2066  * @param int $to Optional. Unix timestamp to end the time difference. Default becomes time() if not set.
  2098  * @param int $to Optional. Unix timestamp to end the time difference. Default becomes time() if not set.
  2067  * @return string Human readable time difference.
  2099  * @return string Human readable time difference.
  2068  */
  2100  */
  2069 function human_time_diff( $from, $to = '' ) {
  2101 function human_time_diff( $from, $to = '' ) {
  2070 	if ( empty($to) )
  2102 	if ( empty( $to ) )
  2071 		$to = time();
  2103 		$to = time();
  2072 	$diff = (int) abs($to - $from);
  2104 	$diff = (int) abs( $to - $from );
  2073 	if ($diff <= 3600) {
  2105 	if ( $diff <= HOUR_IN_SECONDS ) {
  2074 		$mins = round($diff / 60);
  2106 		$mins = round( $diff / MINUTE_IN_SECONDS );
  2075 		if ($mins <= 1) {
  2107 		if ( $mins <= 1 ) {
  2076 			$mins = 1;
  2108 			$mins = 1;
  2077 		}
  2109 		}
  2078 		/* translators: min=minute */
  2110 		/* translators: min=minute */
  2079 		$since = sprintf(_n('%s min', '%s mins', $mins), $mins);
  2111 		$since = sprintf( _n( '%s min', '%s mins', $mins ), $mins );
  2080 	} else if (($diff <= 86400) && ($diff > 3600)) {
  2112 	} elseif ( ( $diff <= DAY_IN_SECONDS ) && ( $diff > HOUR_IN_SECONDS ) ) {
  2081 		$hours = round($diff / 3600);
  2113 		$hours = round( $diff / HOUR_IN_SECONDS );
  2082 		if ($hours <= 1) {
  2114 		if ( $hours <= 1 ) {
  2083 			$hours = 1;
  2115 			$hours = 1;
  2084 		}
  2116 		}
  2085 		$since = sprintf(_n('%s hour', '%s hours', $hours), $hours);
  2117 		$since = sprintf( _n( '%s hour', '%s hours', $hours ), $hours );
  2086 	} elseif ($diff >= 86400) {
  2118 	} elseif ( $diff >= DAY_IN_SECONDS ) {
  2087 		$days = round($diff / 86400);
  2119 		$days = round( $diff / DAY_IN_SECONDS );
  2088 		if ($days <= 1) {
  2120 		if ( $days <= 1 ) {
  2089 			$days = 1;
  2121 			$days = 1;
  2090 		}
  2122 		}
  2091 		$since = sprintf(_n('%s day', '%s days', $days), $days);
  2123 		$since = sprintf( _n( '%s day', '%s days', $days ), $days );
  2092 	}
  2124 	}
  2093 	return $since;
  2125 	return $since;
  2094 }
  2126 }
  2095 
  2127 
  2096 /**
  2128 /**
  2736 		case 'thumbnail_size_h':
  2768 		case 'thumbnail_size_h':
  2737 		case 'medium_size_w':
  2769 		case 'medium_size_w':
  2738 		case 'medium_size_h':
  2770 		case 'medium_size_h':
  2739 		case 'large_size_w':
  2771 		case 'large_size_w':
  2740 		case 'large_size_h':
  2772 		case 'large_size_h':
  2741 		case 'embed_size_h':
       
  2742 		case 'default_post_edit_rows':
       
  2743 		case 'mailserver_port':
  2773 		case 'mailserver_port':
  2744 		case 'comment_max_links':
  2774 		case 'comment_max_links':
  2745 		case 'page_on_front':
  2775 		case 'page_on_front':
  2746 		case 'page_for_posts':
  2776 		case 'page_for_posts':
  2747 		case 'rss_excerpt_length':
  2777 		case 'rss_excerpt_length':
  2754 		case 'users_can_register':
  2784 		case 'users_can_register':
  2755 		case 'start_of_week':
  2785 		case 'start_of_week':
  2756 			$value = absint( $value );
  2786 			$value = absint( $value );
  2757 			break;
  2787 			break;
  2758 
  2788 
  2759 		case 'embed_size_w':
       
  2760 			if ( '' !== $value )
       
  2761 				$value = absint( $value );
       
  2762 			break;
       
  2763 
       
  2764 		case 'posts_per_page':
  2789 		case 'posts_per_page':
  2765 		case 'posts_per_rss':
  2790 		case 'posts_per_rss':
  2766 			$value = (int) $value;
  2791 			$value = (int) $value;
  2767 			if ( empty($value) )
  2792 			if ( empty($value) )
  2768 				$value = 1;
  2793 				$value = 1;
  2777 				$value = 'closed';
  2802 				$value = 'closed';
  2778 			break;
  2803 			break;
  2779 
  2804 
  2780 		case 'blogdescription':
  2805 		case 'blogdescription':
  2781 		case 'blogname':
  2806 		case 'blogname':
  2782 			$value = addslashes($value);
  2807 			$value = wp_kses_post( $value );
  2783 			$value = wp_filter_post_kses( $value ); // calls stripslashes then addslashes
       
  2784 			$value = stripslashes($value);
       
  2785 			$value = esc_html( $value );
  2808 			$value = esc_html( $value );
  2786 			break;
  2809 			break;
  2787 
  2810 
  2788 		case 'blog_charset':
  2811 		case 'blog_charset':
  2789 			$value = preg_replace('/[^a-zA-Z0-9_-]/', '', $value); // strips slashes
  2812 			$value = preg_replace('/[^a-zA-Z0-9_-]/', '', $value); // strips slashes
       
  2813 			break;
       
  2814 
       
  2815 		case 'blog_public':
       
  2816 			// This is the value if the settings checkbox is not checked on POST. Don't rely on this.
       
  2817 			if ( null === $value )
       
  2818 				$value = 1;
       
  2819 			else
       
  2820 				$value = intval( $value );
  2790 			break;
  2821 			break;
  2791 
  2822 
  2792 		case 'date_format':
  2823 		case 'date_format':
  2793 		case 'time_format':
  2824 		case 'time_format':
  2794 		case 'mailserver_url':
  2825 		case 'mailserver_url':
  2795 		case 'mailserver_login':
  2826 		case 'mailserver_login':
  2796 		case 'mailserver_pass':
  2827 		case 'mailserver_pass':
       
  2828 		case 'upload_path':
       
  2829 			$value = strip_tags( $value );
       
  2830 			$value = wp_kses_data( $value );
       
  2831 			break;
       
  2832 
  2797 		case 'ping_sites':
  2833 		case 'ping_sites':
  2798 		case 'upload_path':
  2834 			$value = explode( "\n", $value );
  2799 			$value = strip_tags($value);
  2835 			$value = array_filter( array_map( 'trim', $value ) );
  2800 			$value = addslashes($value);
  2836 			$value = array_filter( array_map( 'esc_url_raw', $value ) );
  2801 			$value = wp_filter_kses($value); // calls stripslashes then addslashes
  2837 			$value = implode( "\n", $value );
  2802 			$value = stripslashes($value);
       
  2803 			break;
  2838 			break;
  2804 
  2839 
  2805 		case 'gmt_offset':
  2840 		case 'gmt_offset':
  2806 			$value = preg_replace('/[^0-9:.-]/', '', $value); // strips slashes
  2841 			$value = preg_replace('/[^0-9:.-]/', '', $value); // strips slashes
  2807 			break;
  2842 			break;
  2828 
  2863 
  2829 		case 'WPLANG':
  2864 		case 'WPLANG':
  2830 			$allowed = get_available_languages();
  2865 			$allowed = get_available_languages();
  2831 			if ( ! in_array( $value, $allowed ) && ! empty( $value ) )
  2866 			if ( ! in_array( $value, $allowed ) && ! empty( $value ) )
  2832 				$value = get_option( $option );
  2867 				$value = get_option( $option );
       
  2868 			break;
       
  2869 
       
  2870 		case 'illegal_names':
       
  2871 			if ( ! is_array( $value ) )
       
  2872 				$value = explode( "\n", $value );
       
  2873 
       
  2874 			$value = array_values( array_filter( array_map( 'trim', $value ) ) );
       
  2875 
       
  2876 			if ( ! $value )
       
  2877 				$value = '';
       
  2878 			break;
       
  2879 
       
  2880 		case 'limited_email_domains':
       
  2881 		case 'banned_email_domains':
       
  2882 			if ( ! is_array( $value ) )
       
  2883 				$value = explode( "\n", $value );
       
  2884 
       
  2885 			$domains = array_values( array_filter( array_map( 'trim', $value ) ) );
       
  2886 			$value = array();
       
  2887 
       
  2888 			foreach ( $domains as $domain ) {
       
  2889 				if ( ! preg_match( '/(--|\.\.)/', $domain ) && preg_match( '|^([a-zA-Z0-9-\.])+$|', $domain ) )
       
  2890 					$value[] = $domain;
       
  2891 			}
       
  2892 			if ( ! $value )
       
  2893 				$value = '';
  2833 			break;
  2894 			break;
  2834 
  2895 
  2835 		case 'timezone_string':
  2896 		case 'timezone_string':
  2836 			$allowed_zones = timezone_identifiers_list();
  2897 			$allowed_zones = timezone_identifiers_list();
  2837 			if ( ! in_array( $value, $allowed_zones ) && ! empty( $value ) ) {
  2898 			if ( ! in_array( $value, $allowed_zones ) && ! empty( $value ) ) {
  3187  * @param string $path A path.
  3248  * @param string $path A path.
  3188  * @param string $suffix If the filename ends in suffix this will also be cut off.
  3249  * @param string $suffix If the filename ends in suffix this will also be cut off.
  3189  * @return string
  3250  * @return string
  3190  */
  3251  */
  3191 function wp_basename( $path, $suffix = '' ) {
  3252 function wp_basename( $path, $suffix = '' ) {
  3192 	return urldecode( basename( str_replace( '%2F', '/', urlencode( $path ) ), $suffix ) );
  3253 	return urldecode( basename( str_replace( array( '%2F', '%5C' ), '/', urlencode( $path ) ), $suffix ) );
  3193 }
  3254 }
  3194 
  3255 
  3195 /**
  3256 /**
  3196  * Forever eliminate "Wordpress" from the planet (or at least the little bit we can influence).
  3257  * Forever eliminate "Wordpress" from the planet (or at least the little bit we can influence).
  3197  *
  3258  *
  3204 	if ( 'the_title' === current_filter() )
  3265 	if ( 'the_title' === current_filter() )
  3205 		return str_replace( 'Wordpress', 'WordPress', $text );
  3266 		return str_replace( 'Wordpress', 'WordPress', $text );
  3206 	// Still here? Use the more judicious replacement
  3267 	// Still here? Use the more judicious replacement
  3207 	static $dblq = false;
  3268 	static $dblq = false;
  3208 	if ( false === $dblq )
  3269 	if ( false === $dblq )
  3209 		$dblq = _x('&#8220;', 'opening curly quote');
  3270 		$dblq = _x( '&#8220;', 'opening curly double quote' );
  3210 	return str_replace(
  3271 	return str_replace(
  3211 		array( ' Wordpress', '&#8216;Wordpress', $dblq . 'Wordpress', '>Wordpress', '(Wordpress' ),
  3272 		array( ' Wordpress', '&#8216;Wordpress', $dblq . 'Wordpress', '>Wordpress', '(Wordpress' ),
  3212 		array( ' WordPress', '&#8216;WordPress', $dblq . 'WordPress', '>WordPress', '(WordPress' ),
  3273 		array( ' WordPress', '&#8216;WordPress', $dblq . 'WordPress', '>WordPress', '(WordPress' ),
  3213 	$text );
  3274 	$text );
  3214 
  3275