web/wp-includes/functions.php
changeset 136 bde1974c263b
child 194 32102edaa81b
equal deleted inserted replaced
135:53cff4b4a802 136:bde1974c263b
       
     1 <?php
       
     2 /**
       
     3  * Main WordPress API
       
     4  *
       
     5  * @package WordPress
       
     6  */
       
     7 
       
     8 /**
       
     9  * Converts MySQL DATETIME field to user specified date format.
       
    10  *
       
    11  * If $dateformatstring has 'G' value, then gmmktime() function will be used to
       
    12  * make the time. If $dateformatstring is set to 'U', then mktime() function
       
    13  * will be used to make the time.
       
    14  *
       
    15  * The $translate will only be used, if it is set to true and it is by default
       
    16  * and if the $wp_locale object has the month and weekday set.
       
    17  *
       
    18  * @since 0.71
       
    19  *
       
    20  * @param string $dateformatstring Either 'G', 'U', or php date format.
       
    21  * @param string $mysqlstring Time from mysql DATETIME field.
       
    22  * @param bool $translate Optional. Default is true. Will switch format to locale.
       
    23  * @return string Date formated by $dateformatstring or locale (if available).
       
    24  */
       
    25 function mysql2date( $dateformatstring, $mysqlstring, $translate = true ) {
       
    26 	global $wp_locale;
       
    27 	$m = $mysqlstring;
       
    28 	if ( empty( $m ) )
       
    29 		return false;
       
    30 
       
    31 	if( 'G' == $dateformatstring ) {
       
    32 		return strtotime( $m . ' +0000' );
       
    33 	}
       
    34 
       
    35 	$i = strtotime( $m );
       
    36 
       
    37 	if( 'U' == $dateformatstring )
       
    38 		return $i;
       
    39 
       
    40 	if ( $translate)
       
    41 	    return date_i18n( $dateformatstring, $i );
       
    42 	else
       
    43 	    return date( $dateformatstring, $i );
       
    44 }
       
    45 
       
    46 /**
       
    47  * Retrieve the current time based on specified type.
       
    48  *
       
    49  * The 'mysql' type will return the time in the format for MySQL DATETIME field.
       
    50  * The 'timestamp' type will return the current timestamp.
       
    51  *
       
    52  * If $gmt is set to either '1' or 'true', then both types will use GMT time.
       
    53  * if $gmt is false, the output is adjusted with the GMT offset in the WordPress option.
       
    54  *
       
    55  * @since 1.0.0
       
    56  *
       
    57  * @param string $type Either 'mysql' or 'timestamp'.
       
    58  * @param int|bool $gmt Optional. Whether to use GMT timezone. Default is false.
       
    59  * @return int|string String if $type is 'gmt', int if $type is 'timestamp'.
       
    60  */
       
    61 function current_time( $type, $gmt = 0 ) {
       
    62 	switch ( $type ) {
       
    63 		case 'mysql':
       
    64 			return ( $gmt ) ? gmdate( 'Y-m-d H:i:s' ) : gmdate( 'Y-m-d H:i:s', ( time() + ( get_option( 'gmt_offset' ) * 3600 ) ) );
       
    65 			break;
       
    66 		case 'timestamp':
       
    67 			return ( $gmt ) ? time() : time() + ( get_option( 'gmt_offset' ) * 3600 );
       
    68 			break;
       
    69 	}
       
    70 }
       
    71 
       
    72 /**
       
    73  * Retrieve the date in localized format, based on timestamp.
       
    74  *
       
    75  * If the locale specifies the locale month and weekday, then the locale will
       
    76  * take over the format for the date. If it isn't, then the date format string
       
    77  * will be used instead.
       
    78  *
       
    79  * @since 0.71
       
    80  *
       
    81  * @param string $dateformatstring Format to display the date.
       
    82  * @param int $unixtimestamp Optional. Unix timestamp.
       
    83  * @param bool $gmt Optional, default is false. Whether to convert to GMT for time.
       
    84  * @return string The date, translated if locale specifies it.
       
    85  */
       
    86 function date_i18n( $dateformatstring, $unixtimestamp = false, $gmt = false ) {
       
    87 	global $wp_locale;
       
    88 	$i = $unixtimestamp;
       
    89 	// Sanity check for PHP 5.1.0-
       
    90 	if ( false === $i || intval($i) < 0 ) {
       
    91 		if ( ! $gmt )
       
    92 			$i = current_time( 'timestamp' );
       
    93 		else
       
    94 			$i = time();
       
    95 		// we should not let date() interfere with our
       
    96 		// specially computed timestamp
       
    97 		$gmt = true;
       
    98 	}
       
    99 
       
   100 	// store original value for language with untypical grammars
       
   101 	// see http://core.trac.wordpress.org/ticket/9396
       
   102 	$req_format = $dateformatstring;
       
   103 
       
   104 	$datefunc = $gmt? 'gmdate' : 'date';
       
   105 
       
   106 	if ( ( !empty( $wp_locale->month ) ) && ( !empty( $wp_locale->weekday ) ) ) {
       
   107 		$datemonth = $wp_locale->get_month( $datefunc( 'm', $i ) );
       
   108 		$datemonth_abbrev = $wp_locale->get_month_abbrev( $datemonth );
       
   109 		$dateweekday = $wp_locale->get_weekday( $datefunc( 'w', $i ) );
       
   110 		$dateweekday_abbrev = $wp_locale->get_weekday_abbrev( $dateweekday );
       
   111 		$datemeridiem = $wp_locale->get_meridiem( $datefunc( 'a', $i ) );
       
   112 		$datemeridiem_capital = $wp_locale->get_meridiem( $datefunc( 'A', $i ) );
       
   113 		$dateformatstring = ' '.$dateformatstring;
       
   114 		$dateformatstring = preg_replace( "/([^\\\])D/", "\\1" . backslashit( $dateweekday_abbrev ), $dateformatstring );
       
   115 		$dateformatstring = preg_replace( "/([^\\\])F/", "\\1" . backslashit( $datemonth ), $dateformatstring );
       
   116 		$dateformatstring = preg_replace( "/([^\\\])l/", "\\1" . backslashit( $dateweekday ), $dateformatstring );
       
   117 		$dateformatstring = preg_replace( "/([^\\\])M/", "\\1" . backslashit( $datemonth_abbrev ), $dateformatstring );
       
   118 		$dateformatstring = preg_replace( "/([^\\\])a/", "\\1" . backslashit( $datemeridiem ), $dateformatstring );
       
   119 		$dateformatstring = preg_replace( "/([^\\\])A/", "\\1" . backslashit( $datemeridiem_capital ), $dateformatstring );
       
   120 
       
   121 		$dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) -1 );
       
   122 	}
       
   123 	$j = @$datefunc( $dateformatstring, $i );
       
   124 	// allow plugins to redo this entirely for languages with untypical grammars
       
   125 	$j = apply_filters('date_i18n', $j, $req_format, $i, $gmt);
       
   126 	return $j;
       
   127 }
       
   128 
       
   129 /**
       
   130  * Convert number to format based on the locale.
       
   131  *
       
   132  * @since 2.3.0
       
   133  *
       
   134  * @param mixed $number The number to convert based on locale.
       
   135  * @param int $decimals Precision of the number of decimal places.
       
   136  * @return string Converted number in string format.
       
   137  */
       
   138 function number_format_i18n( $number, $decimals = null ) {
       
   139 	global $wp_locale;
       
   140 	// let the user override the precision only
       
   141 	$decimals = ( is_null( $decimals ) ) ? $wp_locale->number_format['decimals'] : intval( $decimals );
       
   142 
       
   143 	$num = number_format( $number, $decimals, $wp_locale->number_format['decimal_point'], $wp_locale->number_format['thousands_sep'] );
       
   144 
       
   145 	// let the user translate digits from latin to localized language
       
   146 	return apply_filters( 'number_format_i18n', $num );
       
   147 }
       
   148 
       
   149 /**
       
   150  * Convert number of bytes largest unit bytes will fit into.
       
   151  *
       
   152  * It is easier to read 1kB than 1024 bytes and 1MB than 1048576 bytes. Converts
       
   153  * number of bytes to human readable number by taking the number of that unit
       
   154  * that the bytes will go into it. Supports TB value.
       
   155  *
       
   156  * Please note that integers in PHP are limited to 32 bits, unless they are on
       
   157  * 64 bit architecture, then they have 64 bit size. If you need to place the
       
   158  * larger size then what PHP integer type will hold, then use a string. It will
       
   159  * be converted to a double, which should always have 64 bit length.
       
   160  *
       
   161  * Technically the correct unit names for powers of 1024 are KiB, MiB etc.
       
   162  * @link http://en.wikipedia.org/wiki/Byte
       
   163  *
       
   164  * @since 2.3.0
       
   165  *
       
   166  * @param int|string $bytes Number of bytes. Note max integer size for integers.
       
   167  * @param int $decimals Precision of number of decimal places.
       
   168  * @return bool|string False on failure. Number string on success.
       
   169  */
       
   170 function size_format( $bytes, $decimals = null ) {
       
   171 	$quant = array(
       
   172 		// ========================= Origin ====
       
   173 		'TB' => 1099511627776,  // pow( 1024, 4)
       
   174 		'GB' => 1073741824,     // pow( 1024, 3)
       
   175 		'MB' => 1048576,        // pow( 1024, 2)
       
   176 		'kB' => 1024,           // pow( 1024, 1)
       
   177 		'B ' => 1,              // pow( 1024, 0)
       
   178 	);
       
   179 
       
   180 	foreach ( $quant as $unit => $mag )
       
   181 		if ( doubleval($bytes) >= $mag )
       
   182 			return number_format_i18n( $bytes / $mag, $decimals ) . ' ' . $unit;
       
   183 
       
   184 	return false;
       
   185 }
       
   186 
       
   187 /**
       
   188  * Get the week start and end from the datetime or date string from mysql.
       
   189  *
       
   190  * @since 0.71
       
   191  *
       
   192  * @param string $mysqlstring Date or datetime field type from mysql.
       
   193  * @param int $start_of_week Optional. Start of the week as an integer.
       
   194  * @return array Keys are 'start' and 'end'.
       
   195  */
       
   196 function get_weekstartend( $mysqlstring, $start_of_week = '' ) {
       
   197 	$my = substr( $mysqlstring, 0, 4 ); // Mysql string Year
       
   198 	$mm = substr( $mysqlstring, 8, 2 ); // Mysql string Month
       
   199 	$md = substr( $mysqlstring, 5, 2 ); // Mysql string day
       
   200 	$day = mktime( 0, 0, 0, $md, $mm, $my ); // The timestamp for mysqlstring day.
       
   201 	$weekday = date( 'w', $day ); // The day of the week from the timestamp
       
   202 	$i = 86400; // One day
       
   203 	if( !is_numeric($start_of_week) )
       
   204 		$start_of_week = get_option( 'start_of_week' );
       
   205 
       
   206 	if ( $weekday < $start_of_week )
       
   207 		$weekday = 7 - $start_of_week - $weekday;
       
   208 
       
   209 	while ( $weekday > $start_of_week ) {
       
   210 		$weekday = date( 'w', $day );
       
   211 		if ( $weekday < $start_of_week )
       
   212 			$weekday = 7 - $start_of_week - $weekday;
       
   213 
       
   214 		$day -= 86400;
       
   215 		$i = 0;
       
   216 	}
       
   217 	$week['start'] = $day + 86400 - $i;
       
   218 	$week['end'] = $week['start'] + 604799;
       
   219 	return $week;
       
   220 }
       
   221 
       
   222 /**
       
   223  * Unserialize value only if it was serialized.
       
   224  *
       
   225  * @since 2.0.0
       
   226  *
       
   227  * @param string $original Maybe unserialized original, if is needed.
       
   228  * @return mixed Unserialized data can be any type.
       
   229  */
       
   230 function maybe_unserialize( $original ) {
       
   231 	if ( is_serialized( $original ) ) // don't attempt to unserialize data that wasn't serialized going in
       
   232 		return @unserialize( $original );
       
   233 	return $original;
       
   234 }
       
   235 
       
   236 /**
       
   237  * Check value to find if it was serialized.
       
   238  *
       
   239  * If $data is not an string, then returned value will always be false.
       
   240  * Serialized data is always a string.
       
   241  *
       
   242  * @since 2.0.5
       
   243  *
       
   244  * @param mixed $data Value to check to see if was serialized.
       
   245  * @return bool False if not serialized and true if it was.
       
   246  */
       
   247 function is_serialized( $data ) {
       
   248 	// if it isn't a string, it isn't serialized
       
   249 	if ( !is_string( $data ) )
       
   250 		return false;
       
   251 	$data = trim( $data );
       
   252 	if ( 'N;' == $data )
       
   253 		return true;
       
   254 	if ( !preg_match( '/^([adObis]):/', $data, $badions ) )
       
   255 		return false;
       
   256 	switch ( $badions[1] ) {
       
   257 		case 'a' :
       
   258 		case 'O' :
       
   259 		case 's' :
       
   260 			if ( preg_match( "/^{$badions[1]}:[0-9]+:.*[;}]\$/s", $data ) )
       
   261 				return true;
       
   262 			break;
       
   263 		case 'b' :
       
   264 		case 'i' :
       
   265 		case 'd' :
       
   266 			if ( preg_match( "/^{$badions[1]}:[0-9.E-]+;\$/", $data ) )
       
   267 				return true;
       
   268 			break;
       
   269 	}
       
   270 	return false;
       
   271 }
       
   272 
       
   273 /**
       
   274  * Check whether serialized data is of string type.
       
   275  *
       
   276  * @since 2.0.5
       
   277  *
       
   278  * @param mixed $data Serialized data
       
   279  * @return bool False if not a serialized string, true if it is.
       
   280  */
       
   281 function is_serialized_string( $data ) {
       
   282 	// if it isn't a string, it isn't a serialized string
       
   283 	if ( !is_string( $data ) )
       
   284 		return false;
       
   285 	$data = trim( $data );
       
   286 	if ( preg_match( '/^s:[0-9]+:.*;$/s', $data ) ) // this should fetch all serialized strings
       
   287 		return true;
       
   288 	return false;
       
   289 }
       
   290 
       
   291 /**
       
   292  * Retrieve option value based on setting name.
       
   293  *
       
   294  * If the option does not exist or does not have a value, then the return value
       
   295  * will be false. This is useful to check whether you need to install an option
       
   296  * and is commonly used during installation of plugin options and to test
       
   297  * whether upgrading is required.
       
   298  *
       
   299  * You can "short-circuit" the retrieval of the option from the database for
       
   300  * your plugin or core options that aren't protected. You can do so by hooking
       
   301  * into the 'pre_option_$option' with the $option being replaced by the option
       
   302  * name. You should not try to override special options, but you will not be
       
   303  * prevented from doing so.
       
   304  *
       
   305  * There is a second filter called 'option_$option' with the $option being
       
   306  * replaced with the option name. This gives the value as the only parameter.
       
   307  *
       
   308  * If the option was serialized, when the option was added and, or updated, then
       
   309  * it will be unserialized, when it is returned.
       
   310  *
       
   311  * @since 1.5.0
       
   312  * @package WordPress
       
   313  * @subpackage Option
       
   314  * @uses apply_filters() Calls 'pre_option_$optionname' false to allow
       
   315  *		overwriting the option value in a plugin.
       
   316  * @uses apply_filters() Calls 'option_$optionname' with the option name value.
       
   317  *
       
   318  * @param string $setting Name of option to retrieve. Should already be SQL-escaped
       
   319  * @return mixed Value set for the option.
       
   320  */
       
   321 function get_option( $setting, $default = false ) {
       
   322 	global $wpdb;
       
   323 
       
   324 	// Allow plugins to short-circuit options.
       
   325 	$pre = apply_filters( 'pre_option_' . $setting, false );
       
   326 	if ( false !== $pre )
       
   327 		return $pre;
       
   328 
       
   329 	// prevent non-existent options from triggering multiple queries
       
   330 	$notoptions = wp_cache_get( 'notoptions', 'options' );
       
   331 	if ( isset( $notoptions[$setting] ) )
       
   332 		return $default;
       
   333 
       
   334 	$alloptions = wp_load_alloptions();
       
   335 
       
   336 	if ( isset( $alloptions[$setting] ) ) {
       
   337 		$value = $alloptions[$setting];
       
   338 	} else {
       
   339 		$value = wp_cache_get( $setting, 'options' );
       
   340 
       
   341 		if ( false === $value ) {
       
   342 			if ( defined( 'WP_INSTALLING' ) )
       
   343 				$suppress = $wpdb->suppress_errors();
       
   344 			// expected_slashed ($setting)
       
   345 			$row = $wpdb->get_row( "SELECT option_value FROM $wpdb->options WHERE option_name = '$setting' LIMIT 1" );
       
   346 			if ( defined( 'WP_INSTALLING' ) )
       
   347 				$wpdb->suppress_errors($suppress);
       
   348 
       
   349 			if ( is_object( $row) ) { // Has to be get_row instead of get_var because of funkiness with 0, false, null values
       
   350 				$value = $row->option_value;
       
   351 				wp_cache_add( $setting, $value, 'options' );
       
   352 			} else { // option does not exist, so we must cache its non-existence
       
   353 				$notoptions[$setting] = true;
       
   354 				wp_cache_set( 'notoptions', $notoptions, 'options' );
       
   355 				return $default;
       
   356 			}
       
   357 		}
       
   358 	}
       
   359 
       
   360 	// If home is not set use siteurl.
       
   361 	if ( 'home' == $setting && '' == $value )
       
   362 		return get_option( 'siteurl' );
       
   363 
       
   364 	if ( in_array( $setting, array('siteurl', 'home', 'category_base', 'tag_base') ) )
       
   365 		$value = untrailingslashit( $value );
       
   366 
       
   367 	return apply_filters( 'option_' . $setting, maybe_unserialize( $value ) );
       
   368 }
       
   369 
       
   370 /**
       
   371  * Protect WordPress special option from being modified.
       
   372  *
       
   373  * Will die if $option is in protected list. Protected options are 'alloptions'
       
   374  * and 'notoptions' options.
       
   375  *
       
   376  * @since 2.2.0
       
   377  * @package WordPress
       
   378  * @subpackage Option
       
   379  *
       
   380  * @param string $option Option name.
       
   381  */
       
   382 function wp_protect_special_option( $option ) {
       
   383 	$protected = array( 'alloptions', 'notoptions' );
       
   384 	if ( in_array( $option, $protected ) )
       
   385 		die( sprintf( __( '%s is a protected WP option and may not be modified' ), esc_html( $option ) ) );
       
   386 }
       
   387 
       
   388 /**
       
   389  * Print option value after sanitizing for forms.
       
   390  *
       
   391  * @uses attr Sanitizes value.
       
   392  * @since 1.5.0
       
   393  * @package WordPress
       
   394  * @subpackage Option
       
   395  *
       
   396  * @param string $option Option name.
       
   397  */
       
   398 function form_option( $option ) {
       
   399 	echo esc_attr(get_option( $option ) );
       
   400 }
       
   401 
       
   402 /**
       
   403  * Retrieve all autoload options or all options, if no autoloaded ones exist.
       
   404  *
       
   405  * This is different from wp_load_alloptions() in that this function does not
       
   406  * cache its results and will retrieve all options from the database every time
       
   407  *
       
   408  * it is called.
       
   409  *
       
   410  * @since 1.0.0
       
   411  * @package WordPress
       
   412  * @subpackage Option
       
   413  * @uses apply_filters() Calls 'pre_option_$optionname' hook with option value as parameter.
       
   414  * @uses apply_filters() Calls 'all_options' on options list.
       
   415  *
       
   416  * @return array List of all options.
       
   417  */
       
   418 function get_alloptions() {
       
   419 	global $wpdb;
       
   420 	$show = $wpdb->hide_errors();
       
   421 	if ( !$options = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options WHERE autoload = 'yes'" ) )
       
   422 		$options = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options" );
       
   423 	$wpdb->show_errors($show);
       
   424 
       
   425 	foreach ( (array) $options as $option ) {
       
   426 		// "When trying to design a foolproof system,
       
   427 		//  never underestimate the ingenuity of the fools :)" -- Dougal
       
   428 		if ( in_array( $option->option_name, array( 'siteurl', 'home', 'category_base', 'tag_base' ) ) )
       
   429 			$option->option_value = untrailingslashit( $option->option_value );
       
   430 		$value = maybe_unserialize( $option->option_value );
       
   431 		$all_options->{$option->option_name} = apply_filters( 'pre_option_' . $option->option_name, $value );
       
   432 	}
       
   433 	return apply_filters( 'all_options', $all_options );
       
   434 }
       
   435 
       
   436 /**
       
   437  * Loads and caches all autoloaded options, if available or all options.
       
   438  *
       
   439  * This is different from get_alloptions(), in that this function will cache the
       
   440  * options and will return the cached options when called again.
       
   441  *
       
   442  * @since 2.2.0
       
   443  * @package WordPress
       
   444  * @subpackage Option
       
   445  *
       
   446  * @return array List all options.
       
   447  */
       
   448 function wp_load_alloptions() {
       
   449 	global $wpdb;
       
   450 
       
   451 	$alloptions = wp_cache_get( 'alloptions', 'options' );
       
   452 
       
   453 	if ( !$alloptions ) {
       
   454 		$suppress = $wpdb->suppress_errors();
       
   455 		if ( !$alloptions_db = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options WHERE autoload = 'yes'" ) )
       
   456 			$alloptions_db = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options" );
       
   457 		$wpdb->suppress_errors($suppress);
       
   458 		$alloptions = array();
       
   459 		foreach ( (array) $alloptions_db as $o )
       
   460 			$alloptions[$o->option_name] = $o->option_value;
       
   461 		wp_cache_add( 'alloptions', $alloptions, 'options' );
       
   462 	}
       
   463 	return $alloptions;
       
   464 }
       
   465 
       
   466 /**
       
   467  * Update the value of an option that was already added.
       
   468  *
       
   469  * You do not need to serialize values, if the value needs to be serialize, then
       
   470  * it will be serialized before it is inserted into the database. Remember,
       
   471  * resources can not be serialized or added as an option.
       
   472  *
       
   473  * If the option does not exist, then the option will be added with the option
       
   474  * value, but you will not be able to set whether it is autoloaded. If you want
       
   475  * to set whether an option autoloaded, then you need to use the add_option().
       
   476  *
       
   477  * Before the option is updated, then the filter named
       
   478  * 'pre_update_option_$option_name', with the $option_name as the $option_name
       
   479  * parameter value, will be called. The hook should accept two parameters, the
       
   480  * first is the new value and the second is the old value.  Whatever is
       
   481  * returned will be used as the new value.
       
   482  *
       
   483  * After the value has been updated the action named 'update_option_$option_name'
       
   484  * will be called.  This action receives two parameters the first being the old
       
   485  * value and the second the new value.
       
   486  *
       
   487  * @since 1.0.0
       
   488  * @package WordPress
       
   489  * @subpackage Option
       
   490  *
       
   491  * @param string $option_name Option name. Expected to not be SQL-escaped
       
   492  * @param mixed $newvalue Option value.
       
   493  * @return bool False if value was not updated and true if value was updated.
       
   494  */
       
   495 function update_option( $option_name, $newvalue ) {
       
   496 	global $wpdb;
       
   497 
       
   498 	wp_protect_special_option( $option_name );
       
   499 
       
   500 	$safe_option_name = esc_sql( $option_name );
       
   501 	$newvalue = sanitize_option( $option_name, $newvalue );
       
   502 
       
   503 	$oldvalue = get_option( $safe_option_name );
       
   504 
       
   505 	$newvalue = apply_filters( 'pre_update_option_' . $option_name, $newvalue, $oldvalue );
       
   506 
       
   507 	// If the new and old values are the same, no need to update.
       
   508 	if ( $newvalue === $oldvalue )
       
   509 		return false;
       
   510 
       
   511 	if ( false === $oldvalue ) {
       
   512 		add_option( $option_name, $newvalue );
       
   513 		return true;
       
   514 	}
       
   515 
       
   516 	$notoptions = wp_cache_get( 'notoptions', 'options' );
       
   517 	if ( is_array( $notoptions ) && isset( $notoptions[$option_name] ) ) {
       
   518 		unset( $notoptions[$option_name] );
       
   519 		wp_cache_set( 'notoptions', $notoptions, 'options' );
       
   520 	}
       
   521 
       
   522 	$_newvalue = $newvalue;
       
   523 	$newvalue = maybe_serialize( $newvalue );
       
   524 
       
   525 	do_action( 'update_option', $option_name, $oldvalue, $newvalue );
       
   526 	$alloptions = wp_load_alloptions();
       
   527 	if ( isset( $alloptions[$option_name] ) ) {
       
   528 		$alloptions[$option_name] = $newvalue;
       
   529 		wp_cache_set( 'alloptions', $alloptions, 'options' );
       
   530 	} else {
       
   531 		wp_cache_set( $option_name, $newvalue, 'options' );
       
   532 	}
       
   533 
       
   534 	$wpdb->update($wpdb->options, array('option_value' => $newvalue), array('option_name' => $option_name) );
       
   535 
       
   536 	if ( $wpdb->rows_affected == 1 ) {
       
   537 		do_action( "update_option_{$option_name}", $oldvalue, $_newvalue );
       
   538 		do_action( 'updated_option', $option_name, $oldvalue, $_newvalue );
       
   539 		return true;
       
   540 	}
       
   541 	return false;
       
   542 }
       
   543 
       
   544 /**
       
   545  * Add a new option.
       
   546  *
       
   547  * You do not need to serialize values, if the value needs to be serialize, then
       
   548  * it will be serialized before it is inserted into the database. Remember,
       
   549  * resources can not be serialized or added as an option.
       
   550  *
       
   551  * You can create options without values and then add values later. Does not
       
   552  * check whether the option has already been added, but does check that you
       
   553  * aren't adding a protected WordPress option. Care should be taken to not name
       
   554  * options, the same as the ones which are protected and to not add options
       
   555  * that were already added.
       
   556  *
       
   557  * The filter named 'add_option_$optionname', with the $optionname being
       
   558  * replaced with the option's name, will be called. The hook should accept two
       
   559  * parameters, the first is the option name, and the second is the value.
       
   560  *
       
   561  * @package WordPress
       
   562  * @subpackage Option
       
   563  * @since 1.0.0
       
   564  * @link http://alex.vort-x.net/blog/ Thanks Alex Stapleton
       
   565  *
       
   566  * @param string $name Option name to add. Expects to NOT be SQL escaped.
       
   567  * @param mixed $value Optional. Option value, can be anything.
       
   568  * @param mixed $deprecated Optional. Description. Not used anymore.
       
   569  * @param bool $autoload Optional. Default is enabled. Whether to load the option when WordPress starts up.
       
   570  * @return null returns when finished.
       
   571  */
       
   572 function add_option( $name, $value = '', $deprecated = '', $autoload = 'yes' ) {
       
   573 	global $wpdb;
       
   574 
       
   575 	wp_protect_special_option( $name );
       
   576 	$safe_name = esc_sql( $name );
       
   577 	$value = sanitize_option( $name, $value );
       
   578 
       
   579 	// Make sure the option doesn't already exist. We can check the 'notoptions' cache before we ask for a db query
       
   580 	$notoptions = wp_cache_get( 'notoptions', 'options' );
       
   581 	if ( !is_array( $notoptions ) || !isset( $notoptions[$name] ) )
       
   582 		if ( false !== get_option( $safe_name ) )
       
   583 			return;
       
   584 
       
   585 	$value = maybe_serialize( $value );
       
   586 	$autoload = ( 'no' === $autoload ) ? 'no' : 'yes';
       
   587 	do_action( 'add_option', $name, $value );
       
   588 	if ( 'yes' == $autoload ) {
       
   589 		$alloptions = wp_load_alloptions();
       
   590 		$alloptions[$name] = $value;
       
   591 		wp_cache_set( 'alloptions', $alloptions, 'options' );
       
   592 	} else {
       
   593 		wp_cache_set( $name, $value, 'options' );
       
   594 	}
       
   595 
       
   596 	// This option exists now
       
   597 	$notoptions = wp_cache_get( 'notoptions', 'options' ); // yes, again... we need it to be fresh
       
   598 	if ( is_array( $notoptions ) && isset( $notoptions[$name] ) ) {
       
   599 		unset( $notoptions[$name] );
       
   600 		wp_cache_set( 'notoptions', $notoptions, 'options' );
       
   601 	}
       
   602 
       
   603 	$wpdb->query( $wpdb->prepare( "INSERT INTO `$wpdb->options` (`option_name`, `option_value`, `autoload`) VALUES (%s, %s, %s) ON DUPLICATE KEY UPDATE `option_name` = VALUES(`option_name`), `option_value` = VALUES(`option_value`), `autoload` = VALUES(`autoload`)", $name, $value, $autoload ) );
       
   604 
       
   605 	do_action( "add_option_{$name}", $name, $value );
       
   606 	do_action( 'added_option', $name, $value );
       
   607 	
       
   608 	return;
       
   609 }
       
   610 
       
   611 /**
       
   612  * Removes option by name and prevents removal of protected WordPress options.
       
   613  *
       
   614  * @package WordPress
       
   615  * @subpackage Option
       
   616  * @since 1.2.0
       
   617  *
       
   618  * @param string $name Option name to remove.
       
   619  * @return bool True, if succeed. False, if failure.
       
   620  */
       
   621 function delete_option( $name ) {
       
   622 	global $wpdb;
       
   623 
       
   624 	wp_protect_special_option( $name );
       
   625 
       
   626 	// Get the ID, if no ID then return
       
   627 	// expected_slashed ($name)
       
   628 	$option = $wpdb->get_row( "SELECT autoload FROM $wpdb->options WHERE option_name = '$name'" );
       
   629 	if ( is_null($option) )
       
   630 		return false;
       
   631 	do_action( 'delete_option', $name );
       
   632 	// expected_slashed ($name)
       
   633 	$wpdb->query( "DELETE FROM $wpdb->options WHERE option_name = '$name'" );
       
   634 	if ( 'yes' == $option->autoload ) {
       
   635 		$alloptions = wp_load_alloptions();
       
   636 		if ( isset( $alloptions[$name] ) ) {
       
   637 			unset( $alloptions[$name] );
       
   638 			wp_cache_set( 'alloptions', $alloptions, 'options' );
       
   639 		}
       
   640 	} else {
       
   641 		wp_cache_delete( $name, 'options' );
       
   642 	}
       
   643 	do_action( 'deleted_option', $name );
       
   644 	return true;
       
   645 }
       
   646 
       
   647 /**
       
   648  * Delete a transient
       
   649  *
       
   650  * @since 2.8.0
       
   651  * @package WordPress
       
   652  * @subpackage Transient
       
   653  *
       
   654  * @param string $transient Transient name. Expected to not be SQL-escaped
       
   655  * @return bool true if successful, false otherwise
       
   656  */
       
   657 function delete_transient($transient) {
       
   658 	global $_wp_using_ext_object_cache, $wpdb;
       
   659 
       
   660 	if ( $_wp_using_ext_object_cache ) {
       
   661 		return wp_cache_delete($transient, 'transient');
       
   662 	} else {
       
   663 		$transient = '_transient_' . esc_sql($transient);
       
   664 		return delete_option($transient);
       
   665 	}
       
   666 }
       
   667 
       
   668 /**
       
   669  * Get the value of a transient
       
   670  *
       
   671  * If the transient does not exist or does not have a value, then the return value
       
   672  * will be false.
       
   673  *
       
   674  * @since 2.8.0
       
   675  * @package WordPress
       
   676  * @subpackage Transient
       
   677  *
       
   678  * @param string $transient Transient name. Expected to not be SQL-escaped
       
   679  * @return mixed Value of transient
       
   680  */
       
   681 function get_transient($transient) {
       
   682 	global $_wp_using_ext_object_cache, $wpdb;
       
   683 
       
   684 	$pre = apply_filters( 'pre_transient_' . $transient, false );
       
   685 	if ( false !== $pre )
       
   686 		return $pre;
       
   687 
       
   688 	if ( $_wp_using_ext_object_cache ) {
       
   689 		$value = wp_cache_get($transient, 'transient');
       
   690 	} else {
       
   691 		$transient_option = '_transient_' . esc_sql($transient);
       
   692 		// If option is not in alloptions, it is not autoloaded and thus has a timeout
       
   693 		$alloptions = wp_load_alloptions();
       
   694 		if ( !isset( $alloptions[$transient_option] ) ) {
       
   695 			$transient_timeout = '_transient_timeout_' . esc_sql($transient);
       
   696 			if ( get_option($transient_timeout) < time() ) {
       
   697 				delete_option($transient_option);
       
   698 				delete_option($transient_timeout);
       
   699 				return false;
       
   700 			}
       
   701 		}
       
   702 
       
   703 		$value = get_option($transient_option);
       
   704 	}
       
   705 
       
   706 	return apply_filters('transient_' . $transient, $value);
       
   707 }
       
   708 
       
   709 /**
       
   710  * Set/update the value of a transient
       
   711  *
       
   712  * You do not need to serialize values, if the value needs to be serialize, then
       
   713  * it will be serialized before it is set.
       
   714  *
       
   715  * @since 2.8.0
       
   716  * @package WordPress
       
   717  * @subpackage Transient
       
   718  *
       
   719  * @param string $transient Transient name. Expected to not be SQL-escaped
       
   720  * @param mixed $value Transient value.
       
   721  * @param int $expiration Time until expiration in seconds, default 0
       
   722  * @return bool False if value was not set and true if value was set.
       
   723  */
       
   724 function set_transient($transient, $value, $expiration = 0) {
       
   725 	global $_wp_using_ext_object_cache, $wpdb;
       
   726 
       
   727 	if ( $_wp_using_ext_object_cache ) {
       
   728 		return wp_cache_set($transient, $value, 'transient', $expiration);
       
   729 	} else {
       
   730 		$transient_timeout = '_transient_timeout_' . $transient;
       
   731 		$transient = '_transient_' . $transient;
       
   732 		$safe_transient = esc_sql($transient);
       
   733 		if ( false === get_option( $safe_transient ) ) {
       
   734 			$autoload = 'yes';
       
   735 			if ( 0 != $expiration ) {
       
   736 				$autoload = 'no';
       
   737 				add_option($transient_timeout, time() + $expiration, '', 'no');
       
   738 			}
       
   739 			return add_option($transient, $value, '', $autoload);
       
   740 		} else {
       
   741 			if ( 0 != $expiration )
       
   742 				update_option($transient_timeout, time() + $expiration);
       
   743 			return update_option($transient, $value);
       
   744 		}
       
   745 	}
       
   746 }
       
   747 
       
   748 /**
       
   749  * Saves and restores user interface settings stored in a cookie.
       
   750  *
       
   751  * Checks if the current user-settings cookie is updated and stores it. When no
       
   752  * cookie exists (different browser used), adds the last saved cookie restoring
       
   753  * the settings.
       
   754  *
       
   755  * @package WordPress
       
   756  * @subpackage Option
       
   757  * @since 2.7.0
       
   758  */
       
   759 function wp_user_settings() {
       
   760 
       
   761 	if ( ! is_admin() )
       
   762 		return;
       
   763 
       
   764 	if ( defined('DOING_AJAX') )
       
   765 		return;
       
   766 
       
   767 	if ( ! $user = wp_get_current_user() )
       
   768 		return;
       
   769 
       
   770 	$settings = get_user_option( 'user-settings', $user->ID, false );
       
   771 
       
   772 	if ( isset( $_COOKIE['wp-settings-' . $user->ID] ) ) {
       
   773 		$cookie = preg_replace( '/[^A-Za-z0-9=&_]/', '', $_COOKIE['wp-settings-' . $user->ID] );
       
   774 
       
   775 		if ( ! empty( $cookie ) && strpos( $cookie, '=' ) ) {
       
   776 			if ( $cookie == $settings )
       
   777 				return;
       
   778 
       
   779 			$last_time = (int) get_user_option( 'user-settings-time', $user->ID, false );
       
   780 			$saved = isset( $_COOKIE['wp-settings-time-' . $user->ID]) ? preg_replace( '/[^0-9]/', '', $_COOKIE['wp-settings-time-' . $user->ID] ) : 0;
       
   781 
       
   782 			if ( $saved > $last_time ) {
       
   783 				update_user_option( $user->ID, 'user-settings', $cookie, false );
       
   784 				update_user_option( $user->ID, 'user-settings-time', time() - 5, false );
       
   785 				return;
       
   786 			}
       
   787 		}
       
   788 	}
       
   789 
       
   790 	setcookie( 'wp-settings-' . $user->ID, $settings, time() + 31536000, SITECOOKIEPATH );
       
   791 	setcookie( 'wp-settings-time-' . $user->ID, time(), time() + 31536000, SITECOOKIEPATH );
       
   792 	$_COOKIE['wp-settings-' . $user->ID] = $settings;
       
   793 }
       
   794 
       
   795 /**
       
   796  * Retrieve user interface setting value based on setting name.
       
   797  *
       
   798  * @package WordPress
       
   799  * @subpackage Option
       
   800  * @since 2.7.0
       
   801  *
       
   802  * @param string $name The name of the setting.
       
   803  * @param string $default Optional default value to return when $name is not set.
       
   804  * @return mixed the last saved user setting or the default value/false if it doesn't exist.
       
   805  */
       
   806 function get_user_setting( $name, $default = false ) {
       
   807 
       
   808 	$all = get_all_user_settings();
       
   809 
       
   810 	return isset($all[$name]) ? $all[$name] : $default;
       
   811 }
       
   812 
       
   813 /**
       
   814  * Add or update user interface setting.
       
   815  *
       
   816  * Both $name and $value can contain only ASCII letters, numbers and underscores.
       
   817  * This function has to be used before any output has started as it calls setcookie().
       
   818  *
       
   819  * @package WordPress
       
   820  * @subpackage Option
       
   821  * @since 2.8.0
       
   822  *
       
   823  * @param string $name The name of the setting.
       
   824  * @param string $value The value for the setting.
       
   825  * @return bool true if set successfully/false if not.
       
   826  */
       
   827 function set_user_setting( $name, $value ) {
       
   828 
       
   829 	if ( headers_sent() )
       
   830 		return false;
       
   831 
       
   832 	$all = get_all_user_settings();
       
   833 	$name = preg_replace( '/[^A-Za-z0-9_]+/', '', $name );
       
   834 
       
   835 	if ( empty($name) )
       
   836 		return false;
       
   837 
       
   838 	$all[$name] = $value;
       
   839 
       
   840 	return wp_set_all_user_settings($all);
       
   841 }
       
   842 
       
   843 /**
       
   844  * Delete user interface settings.
       
   845  *
       
   846  * Deleting settings would reset them to the defaults.
       
   847  * This function has to be used before any output has started as it calls setcookie().
       
   848  *
       
   849  * @package WordPress
       
   850  * @subpackage Option
       
   851  * @since 2.7.0
       
   852  *
       
   853  * @param mixed $names The name or array of names of the setting to be deleted.
       
   854  * @return bool true if deleted successfully/false if not.
       
   855  */
       
   856 function delete_user_setting( $names ) {
       
   857 
       
   858 	if ( headers_sent() )
       
   859 		return false;
       
   860 
       
   861 	$all = get_all_user_settings();
       
   862 	$names = (array) $names;
       
   863 
       
   864 	foreach ( $names as $name ) {
       
   865 		if ( isset($all[$name]) ) {
       
   866 			unset($all[$name]);
       
   867 			$deleted = true;
       
   868 		}
       
   869 	}
       
   870 
       
   871 	if ( isset($deleted) )
       
   872 		return wp_set_all_user_settings($all);
       
   873 
       
   874 	return false;
       
   875 }
       
   876 
       
   877 /**
       
   878  * Retrieve all user interface settings.
       
   879  *
       
   880  * @package WordPress
       
   881  * @subpackage Option
       
   882  * @since 2.7.0
       
   883  *
       
   884  * @return array the last saved user settings or empty array.
       
   885  */
       
   886 function get_all_user_settings() {
       
   887 	global $_updated_user_settings;
       
   888 
       
   889 	if ( ! $user = wp_get_current_user() )
       
   890 		return array();
       
   891 
       
   892 	if ( isset($_updated_user_settings) && is_array($_updated_user_settings) )
       
   893 		return $_updated_user_settings;
       
   894 
       
   895 	$all = array();
       
   896 	if ( isset($_COOKIE['wp-settings-' . $user->ID]) ) {
       
   897 		$cookie = preg_replace( '/[^A-Za-z0-9=&_]/', '', $_COOKIE['wp-settings-' . $user->ID] );
       
   898 
       
   899 		if ( $cookie && strpos($cookie, '=') ) // the '=' cannot be 1st char
       
   900 			parse_str($cookie, $all);
       
   901 
       
   902 	} else {
       
   903 		$option = get_user_option('user-settings', $user->ID);
       
   904 		if ( $option && is_string($option) )
       
   905 			parse_str( $option, $all );
       
   906 	}
       
   907 
       
   908 	return $all;
       
   909 }
       
   910 
       
   911 /**
       
   912  * Private. Set all user interface settings.
       
   913  *
       
   914  * @package WordPress
       
   915  * @subpackage Option
       
   916  * @since 2.8.0
       
   917  *
       
   918  */
       
   919 function wp_set_all_user_settings($all) {
       
   920 	global $_updated_user_settings;
       
   921 
       
   922 	if ( ! $user = wp_get_current_user() )
       
   923 		return false;
       
   924 
       
   925 	$_updated_user_settings = $all;
       
   926 	$settings = '';
       
   927 	foreach ( $all as $k => $v ) {
       
   928 		$v = preg_replace( '/[^A-Za-z0-9_]+/', '', $v );
       
   929 		$settings .= $k . '=' . $v . '&';
       
   930 	}
       
   931 
       
   932 	$settings = rtrim($settings, '&');
       
   933 
       
   934 	update_user_option( $user->ID, 'user-settings', $settings, false );
       
   935 	update_user_option( $user->ID, 'user-settings-time', time(), false );
       
   936 
       
   937 	return true;
       
   938 }
       
   939 
       
   940 /**
       
   941  * Delete the user settings of the current user.
       
   942  *
       
   943  * @package WordPress
       
   944  * @subpackage Option
       
   945  * @since 2.7.0
       
   946  */
       
   947 function delete_all_user_settings() {
       
   948 	if ( ! $user = wp_get_current_user() )
       
   949 		return;
       
   950 
       
   951 	update_user_option( $user->ID, 'user-settings', '', false );
       
   952 	setcookie('wp-settings-' . $user->ID, ' ', time() - 31536000, SITECOOKIEPATH);
       
   953 }
       
   954 
       
   955 /**
       
   956  * Serialize data, if needed.
       
   957  *
       
   958  * @since 2.0.5
       
   959  *
       
   960  * @param mixed $data Data that might be serialized.
       
   961  * @return mixed A scalar data
       
   962  */
       
   963 function maybe_serialize( $data ) {
       
   964 	if ( is_array( $data ) || is_object( $data ) )
       
   965 		return serialize( $data );
       
   966 
       
   967 	if ( is_serialized( $data ) )
       
   968 		return serialize( $data );
       
   969 
       
   970 	return $data;
       
   971 }
       
   972 
       
   973 /**
       
   974  * Retrieve post title from XMLRPC XML.
       
   975  *
       
   976  * If the title element is not part of the XML, then the default post title from
       
   977  * the $post_default_title will be used instead.
       
   978  *
       
   979  * @package WordPress
       
   980  * @subpackage XMLRPC
       
   981  * @since 0.71
       
   982  *
       
   983  * @global string $post_default_title Default XMLRPC post title.
       
   984  *
       
   985  * @param string $content XMLRPC XML Request content
       
   986  * @return string Post title
       
   987  */
       
   988 function xmlrpc_getposttitle( $content ) {
       
   989 	global $post_default_title;
       
   990 	if ( preg_match( '/<title>(.+?)<\/title>/is', $content, $matchtitle ) ) {
       
   991 		$post_title = $matchtitle[1];
       
   992 	} else {
       
   993 		$post_title = $post_default_title;
       
   994 	}
       
   995 	return $post_title;
       
   996 }
       
   997 
       
   998 /**
       
   999  * Retrieve the post category or categories from XMLRPC XML.
       
  1000  *
       
  1001  * If the category element is not found, then the default post category will be
       
  1002  * used. The return type then would be what $post_default_category. If the
       
  1003  * category is found, then it will always be an array.
       
  1004  *
       
  1005  * @package WordPress
       
  1006  * @subpackage XMLRPC
       
  1007  * @since 0.71
       
  1008  *
       
  1009  * @global string $post_default_category Default XMLRPC post category.
       
  1010  *
       
  1011  * @param string $content XMLRPC XML Request content
       
  1012  * @return string|array List of categories or category name.
       
  1013  */
       
  1014 function xmlrpc_getpostcategory( $content ) {
       
  1015 	global $post_default_category;
       
  1016 	if ( preg_match( '/<category>(.+?)<\/category>/is', $content, $matchcat ) ) {
       
  1017 		$post_category = trim( $matchcat[1], ',' );
       
  1018 		$post_category = explode( ',', $post_category );
       
  1019 	} else {
       
  1020 		$post_category = $post_default_category;
       
  1021 	}
       
  1022 	return $post_category;
       
  1023 }
       
  1024 
       
  1025 /**
       
  1026  * XMLRPC XML content without title and category elements.
       
  1027  *
       
  1028  * @package WordPress
       
  1029  * @subpackage XMLRPC
       
  1030  * @since 0.71
       
  1031  *
       
  1032  * @param string $content XMLRPC XML Request content
       
  1033  * @return string XMLRPC XML Request content without title and category elements.
       
  1034  */
       
  1035 function xmlrpc_removepostdata( $content ) {
       
  1036 	$content = preg_replace( '/<title>(.+?)<\/title>/si', '', $content );
       
  1037 	$content = preg_replace( '/<category>(.+?)<\/category>/si', '', $content );
       
  1038 	$content = trim( $content );
       
  1039 	return $content;
       
  1040 }
       
  1041 
       
  1042 /**
       
  1043  * Open the file handle for debugging.
       
  1044  *
       
  1045  * This function is used for XMLRPC feature, but it is general purpose enough
       
  1046  * to be used in anywhere.
       
  1047  *
       
  1048  * @see fopen() for mode options.
       
  1049  * @package WordPress
       
  1050  * @subpackage Debug
       
  1051  * @since 0.71
       
  1052  * @uses $debug Used for whether debugging is enabled.
       
  1053  *
       
  1054  * @param string $filename File path to debug file.
       
  1055  * @param string $mode Same as fopen() mode parameter.
       
  1056  * @return bool|resource File handle. False on failure.
       
  1057  */
       
  1058 function debug_fopen( $filename, $mode ) {
       
  1059 	global $debug;
       
  1060 	if ( 1 == $debug ) {
       
  1061 		$fp = fopen( $filename, $mode );
       
  1062 		return $fp;
       
  1063 	} else {
       
  1064 		return false;
       
  1065 	}
       
  1066 }
       
  1067 
       
  1068 /**
       
  1069  * Write contents to the file used for debugging.
       
  1070  *
       
  1071  * Technically, this can be used to write to any file handle when the global
       
  1072  * $debug is set to 1 or true.
       
  1073  *
       
  1074  * @package WordPress
       
  1075  * @subpackage Debug
       
  1076  * @since 0.71
       
  1077  * @uses $debug Used for whether debugging is enabled.
       
  1078  *
       
  1079  * @param resource $fp File handle for debugging file.
       
  1080  * @param string $string Content to write to debug file.
       
  1081  */
       
  1082 function debug_fwrite( $fp, $string ) {
       
  1083 	global $debug;
       
  1084 	if ( 1 == $debug )
       
  1085 		fwrite( $fp, $string );
       
  1086 }
       
  1087 
       
  1088 /**
       
  1089  * Close the debugging file handle.
       
  1090  *
       
  1091  * Technically, this can be used to close any file handle when the global $debug
       
  1092  * is set to 1 or true.
       
  1093  *
       
  1094  * @package WordPress
       
  1095  * @subpackage Debug
       
  1096  * @since 0.71
       
  1097  * @uses $debug Used for whether debugging is enabled.
       
  1098  *
       
  1099  * @param resource $fp Debug File handle.
       
  1100  */
       
  1101 function debug_fclose( $fp ) {
       
  1102 	global $debug;
       
  1103 	if ( 1 == $debug )
       
  1104 		fclose( $fp );
       
  1105 }
       
  1106 
       
  1107 /**
       
  1108  * Check content for video and audio links to add as enclosures.
       
  1109  *
       
  1110  * Will not add enclosures that have already been added and will
       
  1111  * remove enclosures that are no longer in the post. This is called as
       
  1112  * pingbacks and trackbacks.
       
  1113  *
       
  1114  * @package WordPress
       
  1115  * @since 1.5.0
       
  1116  *
       
  1117  * @uses $wpdb
       
  1118  *
       
  1119  * @param string $content Post Content
       
  1120  * @param int $post_ID Post ID
       
  1121  */
       
  1122 function do_enclose( $content, $post_ID ) {
       
  1123 	global $wpdb;
       
  1124 	include_once( ABSPATH . WPINC . '/class-IXR.php' );
       
  1125 
       
  1126 	$log = debug_fopen( ABSPATH . 'enclosures.log', 'a' );
       
  1127 	$post_links = array();
       
  1128 	debug_fwrite( $log, 'BEGIN ' . date( 'YmdHis', time() ) . "\n" );
       
  1129 
       
  1130 	$pung = get_enclosed( $post_ID );
       
  1131 
       
  1132 	$ltrs = '\w';
       
  1133 	$gunk = '/#~:.?+=&%@!\-';
       
  1134 	$punc = '.:?\-';
       
  1135 	$any = $ltrs . $gunk . $punc;
       
  1136 
       
  1137 	preg_match_all( "{\b http : [$any] +? (?= [$punc] * [^$any] | $)}x", $content, $post_links_temp );
       
  1138 
       
  1139 	debug_fwrite( $log, 'Post contents:' );
       
  1140 	debug_fwrite( $log, $content . "\n" );
       
  1141 
       
  1142 	foreach ( $pung as $link_test ) {
       
  1143 		if ( !in_array( $link_test, $post_links_temp[0] ) ) { // link no longer in post
       
  1144 			$mid = $wpdb->get_col( $wpdb->prepare("SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE (%s)", $post_ID, $link_test . '%') );
       
  1145 			do_action( 'delete_postmeta', $mid );
       
  1146 			$wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->postmeta WHERE post_id IN(%s)", implode( ',', $mid ) ) );
       
  1147 			do_action( 'deleted_postmeta', $mid );
       
  1148 		}
       
  1149 	}
       
  1150 
       
  1151 	foreach ( (array) $post_links_temp[0] as $link_test ) {
       
  1152 		if ( !in_array( $link_test, $pung ) ) { // If we haven't pung it already
       
  1153 			$test = parse_url( $link_test );
       
  1154 			if ( isset( $test['query'] ) )
       
  1155 				$post_links[] = $link_test;
       
  1156 			elseif ( $test['path'] != '/' && $test['path'] != '' )
       
  1157 				$post_links[] = $link_test;
       
  1158 		}
       
  1159 	}
       
  1160 
       
  1161 	foreach ( (array) $post_links as $url ) {
       
  1162 		if ( $url != '' && !$wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE (%s)", $post_ID, $url . '%' ) ) ) {
       
  1163 			if ( $headers = wp_get_http_headers( $url) ) {
       
  1164 				$len = (int) $headers['content-length'];
       
  1165 				$type = $headers['content-type'];
       
  1166 				$allowed_types = array( 'video', 'audio' );
       
  1167 				if ( in_array( substr( $type, 0, strpos( $type, "/" ) ), $allowed_types ) ) {
       
  1168 					$meta_value = "$url\n$len\n$type\n";
       
  1169 					$wpdb->insert($wpdb->postmeta, array('post_id' => $post_ID, 'meta_key' => 'enclosure', 'meta_value' => $meta_value) );
       
  1170 					do_action( 'added_postmeta', $wpdb->insert_id, $post_ID, 'enclosure', $meta_value );
       
  1171 				}
       
  1172 			}
       
  1173 		}
       
  1174 	}
       
  1175 }
       
  1176 
       
  1177 /**
       
  1178  * Perform a HTTP HEAD or GET request.
       
  1179  *
       
  1180  * If $file_path is a writable filename, this will do a GET request and write
       
  1181  * the file to that path.
       
  1182  *
       
  1183  * @since 2.5.0
       
  1184  *
       
  1185  * @param string $url URL to fetch.
       
  1186  * @param string|bool $file_path Optional. File path to write request to.
       
  1187  * @param bool $deprecated Deprecated. Not used.
       
  1188  * @return bool|string False on failure and string of headers if HEAD request.
       
  1189  */
       
  1190 function wp_get_http( $url, $file_path = false, $deprecated = false ) {
       
  1191 	@set_time_limit( 60 );
       
  1192 
       
  1193 	$options = array();
       
  1194 	$options['redirection'] = 5;
       
  1195 
       
  1196 	if ( false == $file_path )
       
  1197 		$options['method'] = 'HEAD';
       
  1198 	else
       
  1199 		$options['method'] = 'GET';
       
  1200 
       
  1201 	$response = wp_remote_request($url, $options);
       
  1202 
       
  1203 	if ( is_wp_error( $response ) )
       
  1204 		return false;
       
  1205 
       
  1206 	$headers = wp_remote_retrieve_headers( $response );
       
  1207 	$headers['response'] = $response['response']['code'];
       
  1208 
       
  1209 	if ( false == $file_path )
       
  1210 		return $headers;
       
  1211 
       
  1212 	// GET request - write it to the supplied filename
       
  1213 	$out_fp = fopen($file_path, 'w');
       
  1214 	if ( !$out_fp )
       
  1215 		return $headers;
       
  1216 
       
  1217 	fwrite( $out_fp,  $response['body']);
       
  1218 	fclose($out_fp);
       
  1219 
       
  1220 	return $headers;
       
  1221 }
       
  1222 
       
  1223 /**
       
  1224  * Retrieve HTTP Headers from URL.
       
  1225  *
       
  1226  * @since 1.5.1
       
  1227  *
       
  1228  * @param string $url
       
  1229  * @param bool $deprecated Not Used.
       
  1230  * @return bool|string False on failure, headers on success.
       
  1231  */
       
  1232 function wp_get_http_headers( $url, $deprecated = false ) {
       
  1233 	$response = wp_remote_head( $url );
       
  1234 
       
  1235 	if ( is_wp_error( $response ) )
       
  1236 		return false;
       
  1237 
       
  1238 	return wp_remote_retrieve_headers( $response );
       
  1239 }
       
  1240 
       
  1241 /**
       
  1242  * Whether today is a new day.
       
  1243  *
       
  1244  * @since 0.71
       
  1245  * @uses $day Today
       
  1246  * @uses $previousday Previous day
       
  1247  *
       
  1248  * @return int 1 when new day, 0 if not a new day.
       
  1249  */
       
  1250 function is_new_day() {
       
  1251 	global $day, $previousday;
       
  1252 	if ( $day != $previousday )
       
  1253 		return 1;
       
  1254 	else
       
  1255 		return 0;
       
  1256 }
       
  1257 
       
  1258 /**
       
  1259  * Build URL query based on an associative and, or indexed array.
       
  1260  *
       
  1261  * This is a convenient function for easily building url queries. It sets the
       
  1262  * separator to '&' and uses _http_build_query() function.
       
  1263  *
       
  1264  * @see _http_build_query() Used to build the query
       
  1265  * @link http://us2.php.net/manual/en/function.http-build-query.php more on what
       
  1266  *		http_build_query() does.
       
  1267  *
       
  1268  * @since 2.3.0
       
  1269  *
       
  1270  * @param array $data URL-encode key/value pairs.
       
  1271  * @return string URL encoded string
       
  1272  */
       
  1273 function build_query( $data ) {
       
  1274 	return _http_build_query( $data, null, '&', '', false );
       
  1275 }
       
  1276 
       
  1277 /**
       
  1278  * Retrieve a modified URL query string.
       
  1279  *
       
  1280  * You can rebuild the URL and append a new query variable to the URL query by
       
  1281  * using this function. You can also retrieve the full URL with query data.
       
  1282  *
       
  1283  * Adding a single key & value or an associative array. Setting a key value to
       
  1284  * emptystring removes the key. Omitting oldquery_or_uri uses the $_SERVER
       
  1285  * value.
       
  1286  *
       
  1287  * @since 1.5.0
       
  1288  *
       
  1289  * @param mixed $param1 Either newkey or an associative_array
       
  1290  * @param mixed $param2 Either newvalue or oldquery or uri
       
  1291  * @param mixed $param3 Optional. Old query or uri
       
  1292  * @return string New URL query string.
       
  1293  */
       
  1294 function add_query_arg() {
       
  1295 	$ret = '';
       
  1296 	if ( is_array( func_get_arg(0) ) ) {
       
  1297 		if ( @func_num_args() < 2 || false === @func_get_arg( 1 ) )
       
  1298 			$uri = $_SERVER['REQUEST_URI'];
       
  1299 		else
       
  1300 			$uri = @func_get_arg( 1 );
       
  1301 	} else {
       
  1302 		if ( @func_num_args() < 3 || false === @func_get_arg( 2 ) )
       
  1303 			$uri = $_SERVER['REQUEST_URI'];
       
  1304 		else
       
  1305 			$uri = @func_get_arg( 2 );
       
  1306 	}
       
  1307 
       
  1308 	if ( $frag = strstr( $uri, '#' ) )
       
  1309 		$uri = substr( $uri, 0, -strlen( $frag ) );
       
  1310 	else
       
  1311 		$frag = '';
       
  1312 
       
  1313 	if ( preg_match( '|^https?://|i', $uri, $matches ) ) {
       
  1314 		$protocol = $matches[0];
       
  1315 		$uri = substr( $uri, strlen( $protocol ) );
       
  1316 	} else {
       
  1317 		$protocol = '';
       
  1318 	}
       
  1319 
       
  1320 	if ( strpos( $uri, '?' ) !== false ) {
       
  1321 		$parts = explode( '?', $uri, 2 );
       
  1322 		if ( 1 == count( $parts ) ) {
       
  1323 			$base = '?';
       
  1324 			$query = $parts[0];
       
  1325 		} else {
       
  1326 			$base = $parts[0] . '?';
       
  1327 			$query = $parts[1];
       
  1328 		}
       
  1329 	} elseif ( !empty( $protocol ) || strpos( $uri, '=' ) === false ) {
       
  1330 		$base = $uri . '?';
       
  1331 		$query = '';
       
  1332 	} else {
       
  1333 		$base = '';
       
  1334 		$query = $uri;
       
  1335 	}
       
  1336 
       
  1337 	wp_parse_str( $query, $qs );
       
  1338 	$qs = urlencode_deep( $qs ); // this re-URL-encodes things that were already in the query string
       
  1339 	if ( is_array( func_get_arg( 0 ) ) ) {
       
  1340 		$kayvees = func_get_arg( 0 );
       
  1341 		$qs = array_merge( $qs, $kayvees );
       
  1342 	} else {
       
  1343 		$qs[func_get_arg( 0 )] = func_get_arg( 1 );
       
  1344 	}
       
  1345 
       
  1346 	foreach ( (array) $qs as $k => $v ) {
       
  1347 		if ( $v === false )
       
  1348 			unset( $qs[$k] );
       
  1349 	}
       
  1350 
       
  1351 	$ret = build_query( $qs );
       
  1352 	$ret = trim( $ret, '?' );
       
  1353 	$ret = preg_replace( '#=(&|$)#', '$1', $ret );
       
  1354 	$ret = $protocol . $base . $ret . $frag;
       
  1355 	$ret = rtrim( $ret, '?' );
       
  1356 	return $ret;
       
  1357 }
       
  1358 
       
  1359 /**
       
  1360  * Removes an item or list from the query string.
       
  1361  *
       
  1362  * @since 1.5.0
       
  1363  *
       
  1364  * @param string|array $key Query key or keys to remove.
       
  1365  * @param bool $query When false uses the $_SERVER value.
       
  1366  * @return string New URL query string.
       
  1367  */
       
  1368 function remove_query_arg( $key, $query=false ) {
       
  1369 	if ( is_array( $key ) ) { // removing multiple keys
       
  1370 		foreach ( $key as $k )
       
  1371 			$query = add_query_arg( $k, false, $query );
       
  1372 		return $query;
       
  1373 	}
       
  1374 	return add_query_arg( $key, false, $query );
       
  1375 }
       
  1376 
       
  1377 /**
       
  1378  * Walks the array while sanitizing the contents.
       
  1379  *
       
  1380  * @uses $wpdb Used to sanitize values
       
  1381  * @since 0.71
       
  1382  *
       
  1383  * @param array $array Array to used to walk while sanitizing contents.
       
  1384  * @return array Sanitized $array.
       
  1385  */
       
  1386 function add_magic_quotes( $array ) {
       
  1387 	global $wpdb;
       
  1388 
       
  1389 	foreach ( (array) $array as $k => $v ) {
       
  1390 		if ( is_array( $v ) ) {
       
  1391 			$array[$k] = add_magic_quotes( $v );
       
  1392 		} else {
       
  1393 			$array[$k] = esc_sql( $v );
       
  1394 		}
       
  1395 	}
       
  1396 	return $array;
       
  1397 }
       
  1398 
       
  1399 /**
       
  1400  * HTTP request for URI to retrieve content.
       
  1401  *
       
  1402  * @since 1.5.1
       
  1403  * @uses wp_remote_get()
       
  1404  *
       
  1405  * @param string $uri URI/URL of web page to retrieve.
       
  1406  * @return bool|string HTTP content. False on failure.
       
  1407  */
       
  1408 function wp_remote_fopen( $uri ) {
       
  1409 	$parsed_url = @parse_url( $uri );
       
  1410 
       
  1411 	if ( !$parsed_url || !is_array( $parsed_url ) )
       
  1412 		return false;
       
  1413 
       
  1414 	$options = array();
       
  1415 	$options['timeout'] = 10;
       
  1416 
       
  1417 	$response = wp_remote_get( $uri, $options );
       
  1418 
       
  1419 	if ( is_wp_error( $response ) )
       
  1420 		return false;
       
  1421 
       
  1422 	return $response['body'];
       
  1423 }
       
  1424 
       
  1425 /**
       
  1426  * Setup the WordPress query.
       
  1427  *
       
  1428  * @since 2.0.0
       
  1429  *
       
  1430  * @param string $query_vars Default WP_Query arguments.
       
  1431  */
       
  1432 function wp( $query_vars = '' ) {
       
  1433 	global $wp, $wp_query, $wp_the_query;
       
  1434 	$wp->main( $query_vars );
       
  1435 
       
  1436 	if( !isset($wp_the_query) )
       
  1437 		$wp_the_query = $wp_query;
       
  1438 }
       
  1439 
       
  1440 /**
       
  1441  * Retrieve the description for the HTTP status.
       
  1442  *
       
  1443  * @since 2.3.0
       
  1444  *
       
  1445  * @param int $code HTTP status code.
       
  1446  * @return string Empty string if not found, or description if found.
       
  1447  */
       
  1448 function get_status_header_desc( $code ) {
       
  1449 	global $wp_header_to_desc;
       
  1450 
       
  1451 	$code = absint( $code );
       
  1452 
       
  1453 	if ( !isset( $wp_header_to_desc ) ) {
       
  1454 		$wp_header_to_desc = array(
       
  1455 			100 => 'Continue',
       
  1456 			101 => 'Switching Protocols',
       
  1457 			102 => 'Processing',
       
  1458 
       
  1459 			200 => 'OK',
       
  1460 			201 => 'Created',
       
  1461 			202 => 'Accepted',
       
  1462 			203 => 'Non-Authoritative Information',
       
  1463 			204 => 'No Content',
       
  1464 			205 => 'Reset Content',
       
  1465 			206 => 'Partial Content',
       
  1466 			207 => 'Multi-Status',
       
  1467 			226 => 'IM Used',
       
  1468 
       
  1469 			300 => 'Multiple Choices',
       
  1470 			301 => 'Moved Permanently',
       
  1471 			302 => 'Found',
       
  1472 			303 => 'See Other',
       
  1473 			304 => 'Not Modified',
       
  1474 			305 => 'Use Proxy',
       
  1475 			306 => 'Reserved',
       
  1476 			307 => 'Temporary Redirect',
       
  1477 
       
  1478 			400 => 'Bad Request',
       
  1479 			401 => 'Unauthorized',
       
  1480 			402 => 'Payment Required',
       
  1481 			403 => 'Forbidden',
       
  1482 			404 => 'Not Found',
       
  1483 			405 => 'Method Not Allowed',
       
  1484 			406 => 'Not Acceptable',
       
  1485 			407 => 'Proxy Authentication Required',
       
  1486 			408 => 'Request Timeout',
       
  1487 			409 => 'Conflict',
       
  1488 			410 => 'Gone',
       
  1489 			411 => 'Length Required',
       
  1490 			412 => 'Precondition Failed',
       
  1491 			413 => 'Request Entity Too Large',
       
  1492 			414 => 'Request-URI Too Long',
       
  1493 			415 => 'Unsupported Media Type',
       
  1494 			416 => 'Requested Range Not Satisfiable',
       
  1495 			417 => 'Expectation Failed',
       
  1496 			422 => 'Unprocessable Entity',
       
  1497 			423 => 'Locked',
       
  1498 			424 => 'Failed Dependency',
       
  1499 			426 => 'Upgrade Required',
       
  1500 
       
  1501 			500 => 'Internal Server Error',
       
  1502 			501 => 'Not Implemented',
       
  1503 			502 => 'Bad Gateway',
       
  1504 			503 => 'Service Unavailable',
       
  1505 			504 => 'Gateway Timeout',
       
  1506 			505 => 'HTTP Version Not Supported',
       
  1507 			506 => 'Variant Also Negotiates',
       
  1508 			507 => 'Insufficient Storage',
       
  1509 			510 => 'Not Extended'
       
  1510 		);
       
  1511 	}
       
  1512 
       
  1513 	if ( isset( $wp_header_to_desc[$code] ) )
       
  1514 		return $wp_header_to_desc[$code];
       
  1515 	else
       
  1516 		return '';
       
  1517 }
       
  1518 
       
  1519 /**
       
  1520  * Set HTTP status header.
       
  1521  *
       
  1522  * @since 2.0.0
       
  1523  * @uses apply_filters() Calls 'status_header' on status header string, HTTP
       
  1524  *		HTTP code, HTTP code description, and protocol string as separate
       
  1525  *		parameters.
       
  1526  *
       
  1527  * @param int $header HTTP status code
       
  1528  * @return null Does not return anything.
       
  1529  */
       
  1530 function status_header( $header ) {
       
  1531 	$text = get_status_header_desc( $header );
       
  1532 
       
  1533 	if ( empty( $text ) )
       
  1534 		return false;
       
  1535 
       
  1536 	$protocol = $_SERVER["SERVER_PROTOCOL"];
       
  1537 	if ( 'HTTP/1.1' != $protocol && 'HTTP/1.0' != $protocol )
       
  1538 		$protocol = 'HTTP/1.0';
       
  1539 	$status_header = "$protocol $header $text";
       
  1540 	if ( function_exists( 'apply_filters' ) )
       
  1541 		$status_header = apply_filters( 'status_header', $status_header, $header, $text, $protocol );
       
  1542 
       
  1543 	return @header( $status_header, true, $header );
       
  1544 }
       
  1545 
       
  1546 /**
       
  1547  * Gets the header information to prevent caching.
       
  1548  *
       
  1549  * The several different headers cover the different ways cache prevention is handled
       
  1550  * by different browsers
       
  1551  *
       
  1552  * @since 2.8
       
  1553  *
       
  1554  * @uses apply_filters()
       
  1555  * @return array The associative array of header names and field values.
       
  1556  */
       
  1557 function wp_get_nocache_headers() {
       
  1558 	$headers = array(
       
  1559 		'Expires' => 'Wed, 11 Jan 1984 05:00:00 GMT',
       
  1560 		'Last-Modified' => gmdate( 'D, d M Y H:i:s' ) . ' GMT',
       
  1561 		'Cache-Control' => 'no-cache, must-revalidate, max-age=0',
       
  1562 		'Pragma' => 'no-cache',
       
  1563 	);
       
  1564 
       
  1565 	if ( function_exists('apply_filters') ) {
       
  1566 		$headers = apply_filters('nocache_headers', $headers);
       
  1567 	}
       
  1568 	return $headers;
       
  1569 }
       
  1570 
       
  1571 /**
       
  1572  * Sets the headers to prevent caching for the different browsers.
       
  1573  *
       
  1574  * Different browsers support different nocache headers, so several headers must
       
  1575  * be sent so that all of them get the point that no caching should occur.
       
  1576  *
       
  1577  * @since 2.0.0
       
  1578  * @uses wp_get_nocache_headers()
       
  1579  */
       
  1580 function nocache_headers() {
       
  1581 	$headers = wp_get_nocache_headers();
       
  1582 	foreach( (array) $headers as $name => $field_value )
       
  1583 		@header("{$name}: {$field_value}");
       
  1584 }
       
  1585 
       
  1586 /**
       
  1587  * Set the headers for caching for 10 days with JavaScript content type.
       
  1588  *
       
  1589  * @since 2.1.0
       
  1590  */
       
  1591 function cache_javascript_headers() {
       
  1592 	$expiresOffset = 864000; // 10 days
       
  1593 	header( "Content-Type: text/javascript; charset=" . get_bloginfo( 'charset' ) );
       
  1594 	header( "Vary: Accept-Encoding" ); // Handle proxies
       
  1595 	header( "Expires: " . gmdate( "D, d M Y H:i:s", time() + $expiresOffset ) . " GMT" );
       
  1596 }
       
  1597 
       
  1598 /**
       
  1599  * Retrieve the number of database queries during the WordPress execution.
       
  1600  *
       
  1601  * @since 2.0.0
       
  1602  *
       
  1603  * @return int Number of database queries
       
  1604  */
       
  1605 function get_num_queries() {
       
  1606 	global $wpdb;
       
  1607 	return $wpdb->num_queries;
       
  1608 }
       
  1609 
       
  1610 /**
       
  1611  * Whether input is yes or no. Must be 'y' to be true.
       
  1612  *
       
  1613  * @since 1.0.0
       
  1614  *
       
  1615  * @param string $yn Character string containing either 'y' or 'n'
       
  1616  * @return bool True if yes, false on anything else
       
  1617  */
       
  1618 function bool_from_yn( $yn ) {
       
  1619 	return ( strtolower( $yn ) == 'y' );
       
  1620 }
       
  1621 
       
  1622 /**
       
  1623  * Loads the feed template from the use of an action hook.
       
  1624  *
       
  1625  * If the feed action does not have a hook, then the function will die with a
       
  1626  * message telling the visitor that the feed is not valid.
       
  1627  *
       
  1628  * It is better to only have one hook for each feed.
       
  1629  *
       
  1630  * @since 2.1.0
       
  1631  * @uses $wp_query Used to tell if the use a comment feed.
       
  1632  * @uses do_action() Calls 'do_feed_$feed' hook, if a hook exists for the feed.
       
  1633  */
       
  1634 function do_feed() {
       
  1635 	global $wp_query;
       
  1636 
       
  1637 	$feed = get_query_var( 'feed' );
       
  1638 
       
  1639 	// Remove the pad, if present.
       
  1640 	$feed = preg_replace( '/^_+/', '', $feed );
       
  1641 
       
  1642 	if ( $feed == '' || $feed == 'feed' )
       
  1643 		$feed = get_default_feed();
       
  1644 
       
  1645 	$hook = 'do_feed_' . $feed;
       
  1646 	if ( !has_action($hook) ) {
       
  1647 		$message = sprintf( __( 'ERROR: %s is not a valid feed template' ), esc_html($feed));
       
  1648 		wp_die($message);
       
  1649 	}
       
  1650 
       
  1651 	do_action( $hook, $wp_query->is_comment_feed );
       
  1652 }
       
  1653 
       
  1654 /**
       
  1655  * Load the RDF RSS 0.91 Feed template.
       
  1656  *
       
  1657  * @since 2.1.0
       
  1658  */
       
  1659 function do_feed_rdf() {
       
  1660 	load_template( ABSPATH . WPINC . '/feed-rdf.php' );
       
  1661 }
       
  1662 
       
  1663 /**
       
  1664  * Load the RSS 1.0 Feed Template
       
  1665  *
       
  1666  * @since 2.1.0
       
  1667  */
       
  1668 function do_feed_rss() {
       
  1669 	load_template( ABSPATH . WPINC . '/feed-rss.php' );
       
  1670 }
       
  1671 
       
  1672 /**
       
  1673  * Load either the RSS2 comment feed or the RSS2 posts feed.
       
  1674  *
       
  1675  * @since 2.1.0
       
  1676  *
       
  1677  * @param bool $for_comments True for the comment feed, false for normal feed.
       
  1678  */
       
  1679 function do_feed_rss2( $for_comments ) {
       
  1680 	if ( $for_comments )
       
  1681 		load_template( ABSPATH . WPINC . '/feed-rss2-comments.php' );
       
  1682 	else
       
  1683 		load_template( ABSPATH . WPINC . '/feed-rss2.php' );
       
  1684 }
       
  1685 
       
  1686 /**
       
  1687  * Load either Atom comment feed or Atom posts feed.
       
  1688  *
       
  1689  * @since 2.1.0
       
  1690  *
       
  1691  * @param bool $for_comments True for the comment feed, false for normal feed.
       
  1692  */
       
  1693 function do_feed_atom( $for_comments ) {
       
  1694 	if ($for_comments)
       
  1695 		load_template( ABSPATH . WPINC . '/feed-atom-comments.php');
       
  1696 	else
       
  1697 		load_template( ABSPATH . WPINC . '/feed-atom.php' );
       
  1698 }
       
  1699 
       
  1700 /**
       
  1701  * Display the robot.txt file content.
       
  1702  *
       
  1703  * The echo content should be with usage of the permalinks or for creating the
       
  1704  * robot.txt file.
       
  1705  *
       
  1706  * @since 2.1.0
       
  1707  * @uses do_action() Calls 'do_robotstxt' hook for displaying robot.txt rules.
       
  1708  */
       
  1709 function do_robots() {
       
  1710 	header( 'Content-Type: text/plain; charset=utf-8' );
       
  1711 
       
  1712 	do_action( 'do_robotstxt' );
       
  1713 
       
  1714 	if ( '0' == get_option( 'blog_public' ) ) {
       
  1715 		echo "User-agent: *\n";
       
  1716 		echo "Disallow: /\n";
       
  1717 	} else {
       
  1718 		echo "User-agent: *\n";
       
  1719 		echo "Disallow:\n";
       
  1720 	}
       
  1721 }
       
  1722 
       
  1723 /**
       
  1724  * Test whether blog is already installed.
       
  1725  *
       
  1726  * The cache will be checked first. If you have a cache plugin, which saves the
       
  1727  * cache values, then this will work. If you use the default WordPress cache,
       
  1728  * and the database goes away, then you might have problems.
       
  1729  *
       
  1730  * Checks for the option siteurl for whether WordPress is installed.
       
  1731  *
       
  1732  * @since 2.1.0
       
  1733  * @uses $wpdb
       
  1734  *
       
  1735  * @return bool Whether blog is already installed.
       
  1736  */
       
  1737 function is_blog_installed() {
       
  1738 	global $wpdb;
       
  1739 
       
  1740 	// Check cache first. If options table goes away and we have true cached, oh well.
       
  1741 	if ( wp_cache_get( 'is_blog_installed' ) )
       
  1742 		return true;
       
  1743 
       
  1744 	$suppress = $wpdb->suppress_errors();
       
  1745 	$alloptions = wp_load_alloptions();
       
  1746 	// If siteurl is not set to autoload, check it specifically
       
  1747 	if ( !isset( $alloptions['siteurl'] ) )
       
  1748 		$installed = $wpdb->get_var( "SELECT option_value FROM $wpdb->options WHERE option_name = 'siteurl'" );
       
  1749 	else
       
  1750 		$installed = $alloptions['siteurl'];
       
  1751 	$wpdb->suppress_errors( $suppress );
       
  1752 
       
  1753 	$installed = !empty( $installed );
       
  1754 	wp_cache_set( 'is_blog_installed', $installed );
       
  1755 
       
  1756 	if ( $installed )
       
  1757 		return true;
       
  1758 
       
  1759 	$suppress = $wpdb->suppress_errors();
       
  1760 	$tables = $wpdb->get_col('SHOW TABLES');
       
  1761 	$wpdb->suppress_errors( $suppress );
       
  1762 
       
  1763 	// Loop over the WP tables.  If none exist, then scratch install is allowed.
       
  1764 	// If one or more exist, suggest table repair since we got here because the options
       
  1765 	// table could not be accessed.
       
  1766 	foreach ($wpdb->tables as $table) {
       
  1767 		// If one of the WP tables exist, then we are in an insane state.
       
  1768 		if ( in_array($wpdb->prefix . $table, $tables) ) {
       
  1769 			// If visiting repair.php, return true and let it take over.
       
  1770 			if ( defined('WP_REPAIRING') )
       
  1771 				return true;
       
  1772 			// Die with a DB error.
       
  1773 			$wpdb->error = __('One or more database tables are unavailable.  The database may need to be <a href="maint/repair.php?referrer=is_blog_installed">repaired</a>.');
       
  1774 			dead_db();
       
  1775 		}
       
  1776 	}
       
  1777 
       
  1778 	wp_cache_set( 'is_blog_installed', false );
       
  1779 
       
  1780 	return false;
       
  1781 }
       
  1782 
       
  1783 /**
       
  1784  * Retrieve URL with nonce added to URL query.
       
  1785  *
       
  1786  * @package WordPress
       
  1787  * @subpackage Security
       
  1788  * @since 2.0.4
       
  1789  *
       
  1790  * @param string $actionurl URL to add nonce action
       
  1791  * @param string $action Optional. Nonce action name
       
  1792  * @return string URL with nonce action added.
       
  1793  */
       
  1794 function wp_nonce_url( $actionurl, $action = -1 ) {
       
  1795 	$actionurl = str_replace( '&amp;', '&', $actionurl );
       
  1796 	return esc_html( add_query_arg( '_wpnonce', wp_create_nonce( $action ), $actionurl ) );
       
  1797 }
       
  1798 
       
  1799 /**
       
  1800  * Retrieve or display nonce hidden field for forms.
       
  1801  *
       
  1802  * The nonce field is used to validate that the contents of the form came from
       
  1803  * the location on the current site and not somewhere else. The nonce does not
       
  1804  * offer absolute protection, but should protect against most cases. It is very
       
  1805  * important to use nonce field in forms.
       
  1806  *
       
  1807  * If you set $echo to true and set $referer to true, then you will need to
       
  1808  * retrieve the {@link wp_referer_field() wp referer field}. If you have the
       
  1809  * $referer set to true and are echoing the nonce field, it will also echo the
       
  1810  * referer field.
       
  1811  *
       
  1812  * The $action and $name are optional, but if you want to have better security,
       
  1813  * it is strongly suggested to set those two parameters. It is easier to just
       
  1814  * call the function without any parameters, because validation of the nonce
       
  1815  * doesn't require any parameters, but since crackers know what the default is
       
  1816  * it won't be difficult for them to find a way around your nonce and cause
       
  1817  * damage.
       
  1818  *
       
  1819  * The input name will be whatever $name value you gave. The input value will be
       
  1820  * the nonce creation value.
       
  1821  *
       
  1822  * @package WordPress
       
  1823  * @subpackage Security
       
  1824  * @since 2.0.4
       
  1825  *
       
  1826  * @param string $action Optional. Action name.
       
  1827  * @param string $name Optional. Nonce name.
       
  1828  * @param bool $referer Optional, default true. Whether to set the referer field for validation.
       
  1829  * @param bool $echo Optional, default true. Whether to display or return hidden form field.
       
  1830  * @return string Nonce field.
       
  1831  */
       
  1832 function wp_nonce_field( $action = -1, $name = "_wpnonce", $referer = true , $echo = true ) {
       
  1833 	$name = esc_attr( $name );
       
  1834 	$nonce_field = '<input type="hidden" id="' . $name . '" name="' . $name . '" value="' . wp_create_nonce( $action ) . '" />';
       
  1835 	if ( $echo )
       
  1836 		echo $nonce_field;
       
  1837 
       
  1838 	if ( $referer )
       
  1839 		wp_referer_field( $echo, 'previous' );
       
  1840 
       
  1841 	return $nonce_field;
       
  1842 }
       
  1843 
       
  1844 /**
       
  1845  * Retrieve or display referer hidden field for forms.
       
  1846  *
       
  1847  * The referer link is the current Request URI from the server super global. The
       
  1848  * input name is '_wp_http_referer', in case you wanted to check manually.
       
  1849  *
       
  1850  * @package WordPress
       
  1851  * @subpackage Security
       
  1852  * @since 2.0.4
       
  1853  *
       
  1854  * @param bool $echo Whether to echo or return the referer field.
       
  1855  * @return string Referer field.
       
  1856  */
       
  1857 function wp_referer_field( $echo = true) {
       
  1858 	$ref = esc_attr( $_SERVER['REQUEST_URI'] );
       
  1859 	$referer_field = '<input type="hidden" name="_wp_http_referer" value="'. $ref . '" />';
       
  1860 
       
  1861 	if ( $echo )
       
  1862 		echo $referer_field;
       
  1863 	return $referer_field;
       
  1864 }
       
  1865 
       
  1866 /**
       
  1867  * Retrieve or display original referer hidden field for forms.
       
  1868  *
       
  1869  * The input name is '_wp_original_http_referer' and will be either the same
       
  1870  * value of {@link wp_referer_field()}, if that was posted already or it will
       
  1871  * be the current page, if it doesn't exist.
       
  1872  *
       
  1873  * @package WordPress
       
  1874  * @subpackage Security
       
  1875  * @since 2.0.4
       
  1876  *
       
  1877  * @param bool $echo Whether to echo the original http referer
       
  1878  * @param string $jump_back_to Optional, default is 'current'. Can be 'previous' or page you want to jump back to.
       
  1879  * @return string Original referer field.
       
  1880  */
       
  1881 function wp_original_referer_field( $echo = true, $jump_back_to = 'current' ) {
       
  1882 	$jump_back_to = ( 'previous' == $jump_back_to ) ? wp_get_referer() : $_SERVER['REQUEST_URI'];
       
  1883 	$ref = ( wp_get_original_referer() ) ? wp_get_original_referer() : $jump_back_to;
       
  1884 	$orig_referer_field = '<input type="hidden" name="_wp_original_http_referer" value="' . esc_attr( stripslashes( $ref ) ) . '" />';
       
  1885 	if ( $echo )
       
  1886 		echo $orig_referer_field;
       
  1887 	return $orig_referer_field;
       
  1888 }
       
  1889 
       
  1890 /**
       
  1891  * Retrieve referer from '_wp_http_referer', HTTP referer, or current page respectively.
       
  1892  *
       
  1893  * @package WordPress
       
  1894  * @subpackage Security
       
  1895  * @since 2.0.4
       
  1896  *
       
  1897  * @return string|bool False on failure. Referer URL on success.
       
  1898  */
       
  1899 function wp_get_referer() {
       
  1900 	$ref = '';
       
  1901 	if ( ! empty( $_REQUEST['_wp_http_referer'] ) )
       
  1902 		$ref = $_REQUEST['_wp_http_referer'];
       
  1903 	else if ( ! empty( $_SERVER['HTTP_REFERER'] ) )
       
  1904 		$ref = $_SERVER['HTTP_REFERER'];
       
  1905 
       
  1906 	if ( $ref !== $_SERVER['REQUEST_URI'] )
       
  1907 		return $ref;
       
  1908 	return false;
       
  1909 }
       
  1910 
       
  1911 /**
       
  1912  * Retrieve original referer that was posted, if it exists.
       
  1913  *
       
  1914  * @package WordPress
       
  1915  * @subpackage Security
       
  1916  * @since 2.0.4
       
  1917  *
       
  1918  * @return string|bool False if no original referer or original referer if set.
       
  1919  */
       
  1920 function wp_get_original_referer() {
       
  1921 	if ( !empty( $_REQUEST['_wp_original_http_referer'] ) )
       
  1922 		return $_REQUEST['_wp_original_http_referer'];
       
  1923 	return false;
       
  1924 }
       
  1925 
       
  1926 /**
       
  1927  * Recursive directory creation based on full path.
       
  1928  *
       
  1929  * Will attempt to set permissions on folders.
       
  1930  *
       
  1931  * @since 2.0.1
       
  1932  *
       
  1933  * @param string $target Full path to attempt to create.
       
  1934  * @return bool Whether the path was created or not. True if path already exists.
       
  1935  */
       
  1936 function wp_mkdir_p( $target ) {
       
  1937 	// from php.net/mkdir user contributed notes
       
  1938 	$target = str_replace( '//', '/', $target );
       
  1939 	if ( file_exists( $target ) )
       
  1940 		return @is_dir( $target );
       
  1941 
       
  1942 	// Attempting to create the directory may clutter up our display.
       
  1943 	if ( @mkdir( $target ) ) {
       
  1944 		$stat = @stat( dirname( $target ) );
       
  1945 		$dir_perms = $stat['mode'] & 0007777;  // Get the permission bits.
       
  1946 		@chmod( $target, $dir_perms );
       
  1947 		return true;
       
  1948 	} elseif ( is_dir( dirname( $target ) ) ) {
       
  1949 			return false;
       
  1950 	}
       
  1951 
       
  1952 	// If the above failed, attempt to create the parent node, then try again.
       
  1953 	if ( ( $target != '/' ) && ( wp_mkdir_p( dirname( $target ) ) ) )
       
  1954 		return wp_mkdir_p( $target );
       
  1955 
       
  1956 	return false;
       
  1957 }
       
  1958 
       
  1959 /**
       
  1960  * Test if a give filesystem path is absolute ('/foo/bar', 'c:\windows').
       
  1961  *
       
  1962  * @since 2.5.0
       
  1963  *
       
  1964  * @param string $path File path
       
  1965  * @return bool True if path is absolute, false is not absolute.
       
  1966  */
       
  1967 function path_is_absolute( $path ) {
       
  1968 	// this is definitive if true but fails if $path does not exist or contains a symbolic link
       
  1969 	if ( realpath($path) == $path )
       
  1970 		return true;
       
  1971 
       
  1972 	if ( strlen($path) == 0 || $path{0} == '.' )
       
  1973 		return false;
       
  1974 
       
  1975 	// windows allows absolute paths like this
       
  1976 	if ( preg_match('#^[a-zA-Z]:\\\\#', $path) )
       
  1977 		return true;
       
  1978 
       
  1979 	// a path starting with / or \ is absolute; anything else is relative
       
  1980 	return (bool) preg_match('#^[/\\\\]#', $path);
       
  1981 }
       
  1982 
       
  1983 /**
       
  1984  * Join two filesystem paths together (e.g. 'give me $path relative to $base').
       
  1985  *
       
  1986  * If the $path is absolute, then it the full path is returned.
       
  1987  *
       
  1988  * @since 2.5.0
       
  1989  *
       
  1990  * @param string $base
       
  1991  * @param string $path
       
  1992  * @return string The path with the base or absolute path.
       
  1993  */
       
  1994 function path_join( $base, $path ) {
       
  1995 	if ( path_is_absolute($path) )
       
  1996 		return $path;
       
  1997 
       
  1998 	return rtrim($base, '/') . '/' . ltrim($path, '/');
       
  1999 }
       
  2000 
       
  2001 /**
       
  2002  * Get an array containing the current upload directory's path and url.
       
  2003  *
       
  2004  * Checks the 'upload_path' option, which should be from the web root folder,
       
  2005  * and if it isn't empty it will be used. If it is empty, then the path will be
       
  2006  * 'WP_CONTENT_DIR/uploads'. If the 'UPLOADS' constant is defined, then it will
       
  2007  * override the 'upload_path' option and 'WP_CONTENT_DIR/uploads' path.
       
  2008  *
       
  2009  * The upload URL path is set either by the 'upload_url_path' option or by using
       
  2010  * the 'WP_CONTENT_URL' constant and appending '/uploads' to the path.
       
  2011  *
       
  2012  * If the 'uploads_use_yearmonth_folders' is set to true (checkbox if checked in
       
  2013  * the administration settings panel), then the time will be used. The format
       
  2014  * will be year first and then month.
       
  2015  *
       
  2016  * If the path couldn't be created, then an error will be returned with the key
       
  2017  * 'error' containing the error message. The error suggests that the parent
       
  2018  * directory is not writable by the server.
       
  2019  *
       
  2020  * On success, the returned array will have many indices:
       
  2021  * 'path' - base directory and sub directory or full path to upload directory.
       
  2022  * 'url' - base url and sub directory or absolute URL to upload directory.
       
  2023  * 'subdir' - sub directory if uploads use year/month folders option is on.
       
  2024  * 'basedir' - path without subdir.
       
  2025  * 'baseurl' - URL path without subdir.
       
  2026  * 'error' - set to false.
       
  2027  *
       
  2028  * @since 2.0.0
       
  2029  * @uses apply_filters() Calls 'upload_dir' on returned array.
       
  2030  *
       
  2031  * @param string $time Optional. Time formatted in 'yyyy/mm'.
       
  2032  * @return array See above for description.
       
  2033  */
       
  2034 function wp_upload_dir( $time = null ) {
       
  2035 	$siteurl = get_option( 'siteurl' );
       
  2036 	$upload_path = get_option( 'upload_path' );
       
  2037 	$upload_path = trim($upload_path);
       
  2038 	if ( empty($upload_path) ) {
       
  2039 		$dir = WP_CONTENT_DIR . '/uploads';
       
  2040 	} else {
       
  2041 		$dir = $upload_path;
       
  2042 		if ( 'wp-content/uploads' == $upload_path ) {
       
  2043 			$dir = WP_CONTENT_DIR . '/uploads';
       
  2044 		} elseif ( 0 !== strpos($dir, ABSPATH) ) {
       
  2045 			// $dir is absolute, $upload_path is (maybe) relative to ABSPATH
       
  2046 			$dir = path_join( ABSPATH, $dir );
       
  2047 		}
       
  2048 	}
       
  2049 
       
  2050 	if ( !$url = get_option( 'upload_url_path' ) ) {
       
  2051 		if ( empty($upload_path) || ( 'wp-content/uploads' == $upload_path ) || ( $upload_path == $dir ) )
       
  2052 			$url = WP_CONTENT_URL . '/uploads';
       
  2053 		else
       
  2054 			$url = trailingslashit( $siteurl ) . $upload_path;
       
  2055 	}
       
  2056 
       
  2057 	if ( defined('UPLOADS') ) {
       
  2058 		$dir = ABSPATH . UPLOADS;
       
  2059 		$url = trailingslashit( $siteurl ) . UPLOADS;
       
  2060 	}
       
  2061 
       
  2062 	$bdir = $dir;
       
  2063 	$burl = $url;
       
  2064 
       
  2065 	$subdir = '';
       
  2066 	if ( get_option( 'uploads_use_yearmonth_folders' ) ) {
       
  2067 		// Generate the yearly and monthly dirs
       
  2068 		if ( !$time )
       
  2069 			$time = current_time( 'mysql' );
       
  2070 		$y = substr( $time, 0, 4 );
       
  2071 		$m = substr( $time, 5, 2 );
       
  2072 		$subdir = "/$y/$m";
       
  2073 	}
       
  2074 
       
  2075 	$dir .= $subdir;
       
  2076 	$url .= $subdir;
       
  2077 
       
  2078 	$uploads = apply_filters( 'upload_dir', array( 'path' => $dir, 'url' => $url, 'subdir' => $subdir, 'basedir' => $bdir, 'baseurl' => $burl, 'error' => false ) );
       
  2079 
       
  2080 	// Make sure we have an uploads dir
       
  2081 	if ( ! wp_mkdir_p( $uploads['path'] ) ) {
       
  2082 		$message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), $uploads['path'] );
       
  2083 		return array( 'error' => $message );
       
  2084 	}
       
  2085 
       
  2086 	return $uploads;
       
  2087 }
       
  2088 
       
  2089 /**
       
  2090  * Get a filename that is sanitized and unique for the given directory.
       
  2091  *
       
  2092  * If the filename is not unique, then a number will be added to the filename
       
  2093  * before the extension, and will continue adding numbers until the filename is
       
  2094  * unique.
       
  2095  *
       
  2096  * The callback must accept two parameters, the first one is the directory and
       
  2097  * the second is the filename. The callback must be a function.
       
  2098  *
       
  2099  * @since 2.5
       
  2100  *
       
  2101  * @param string $dir
       
  2102  * @param string $filename
       
  2103  * @param string $unique_filename_callback Function name, must be a function.
       
  2104  * @return string New filename, if given wasn't unique.
       
  2105  */
       
  2106 function wp_unique_filename( $dir, $filename, $unique_filename_callback = null ) {
       
  2107 	// sanitize the file name before we begin processing
       
  2108 	$filename = sanitize_file_name($filename);
       
  2109 
       
  2110 	// separate the filename into a name and extension
       
  2111 	$info = pathinfo($filename);
       
  2112 	$ext = !empty($info['extension']) ? '.' . $info['extension'] : '';
       
  2113 	$name = basename($filename, $ext);
       
  2114 
       
  2115 	// edge case: if file is named '.ext', treat as an empty name
       
  2116 	if( $name === $ext )
       
  2117 		$name = '';
       
  2118 
       
  2119 	// Increment the file number until we have a unique file to save in $dir. Use $override['unique_filename_callback'] if supplied.
       
  2120 	if ( $unique_filename_callback && function_exists( $unique_filename_callback ) ) {
       
  2121 		$filename = $unique_filename_callback( $dir, $name );
       
  2122 	} else {
       
  2123 		$number = '';
       
  2124 
       
  2125 		// change '.ext' to lower case
       
  2126 		if ( $ext && strtolower($ext) != $ext ) {
       
  2127 			$ext2 = strtolower($ext);
       
  2128 			$filename2 = preg_replace( '|' . preg_quote($ext) . '$|', $ext2, $filename );
       
  2129 
       
  2130 			// check for both lower and upper case extension or image sub-sizes may be overwritten
       
  2131 			while ( file_exists($dir . "/$filename") || file_exists($dir . "/$filename2") ) {
       
  2132 				$new_number = $number + 1;
       
  2133 				$filename = str_replace( "$number$ext", "$new_number$ext", $filename );
       
  2134 				$filename2 = str_replace( "$number$ext2", "$new_number$ext2", $filename2 );
       
  2135 				$number = $new_number;
       
  2136 			}
       
  2137 			return $filename2;
       
  2138 		}
       
  2139 
       
  2140 		while ( file_exists( $dir . "/$filename" ) ) {
       
  2141 			if ( '' == "$number$ext" )
       
  2142 				$filename = $filename . ++$number . $ext;
       
  2143 			else
       
  2144 				$filename = str_replace( "$number$ext", ++$number . $ext, $filename );
       
  2145 		}
       
  2146 	}
       
  2147 
       
  2148 	return $filename;
       
  2149 }
       
  2150 
       
  2151 /**
       
  2152  * Create a file in the upload folder with given content.
       
  2153  *
       
  2154  * If there is an error, then the key 'error' will exist with the error message.
       
  2155  * If success, then the key 'file' will have the unique file path, the 'url' key
       
  2156  * will have the link to the new file. and the 'error' key will be set to false.
       
  2157  *
       
  2158  * This function will not move an uploaded file to the upload folder. It will
       
  2159  * create a new file with the content in $bits parameter. If you move the upload
       
  2160  * file, read the content of the uploaded file, and then you can give the
       
  2161  * filename and content to this function, which will add it to the upload
       
  2162  * folder.
       
  2163  *
       
  2164  * The permissions will be set on the new file automatically by this function.
       
  2165  *
       
  2166  * @since 2.0.0
       
  2167  *
       
  2168  * @param string $name
       
  2169  * @param null $deprecated Not used. Set to null.
       
  2170  * @param mixed $bits File content
       
  2171  * @param string $time Optional. Time formatted in 'yyyy/mm'.
       
  2172  * @return array
       
  2173  */
       
  2174 function wp_upload_bits( $name, $deprecated, $bits, $time = null ) {
       
  2175 	if ( empty( $name ) )
       
  2176 		return array( 'error' => __( 'Empty filename' ) );
       
  2177 
       
  2178 	$wp_filetype = wp_check_filetype( $name );
       
  2179 	if ( !$wp_filetype['ext'] )
       
  2180 		return array( 'error' => __( 'Invalid file type' ) );
       
  2181 
       
  2182 	$upload = wp_upload_dir( $time );
       
  2183 
       
  2184 	if ( $upload['error'] !== false )
       
  2185 		return $upload;
       
  2186 
       
  2187 	$filename = wp_unique_filename( $upload['path'], $name );
       
  2188 
       
  2189 	$new_file = $upload['path'] . "/$filename";
       
  2190 	if ( ! wp_mkdir_p( dirname( $new_file ) ) ) {
       
  2191 		$message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), dirname( $new_file ) );
       
  2192 		return array( 'error' => $message );
       
  2193 	}
       
  2194 
       
  2195 	$ifp = @ fopen( $new_file, 'wb' );
       
  2196 	if ( ! $ifp )
       
  2197 		return array( 'error' => sprintf( __( 'Could not write file %s' ), $new_file ) );
       
  2198 
       
  2199 	@fwrite( $ifp, $bits );
       
  2200 	fclose( $ifp );
       
  2201 	// Set correct file permissions
       
  2202 	$stat = @ stat( dirname( $new_file ) );
       
  2203 	$perms = $stat['mode'] & 0007777;
       
  2204 	$perms = $perms & 0000666;
       
  2205 	@ chmod( $new_file, $perms );
       
  2206 
       
  2207 	// Compute the URL
       
  2208 	$url = $upload['url'] . "/$filename";
       
  2209 
       
  2210 	return array( 'file' => $new_file, 'url' => $url, 'error' => false );
       
  2211 }
       
  2212 
       
  2213 /**
       
  2214  * Retrieve the file type based on the extension name.
       
  2215  *
       
  2216  * @package WordPress
       
  2217  * @since 2.5.0
       
  2218  * @uses apply_filters() Calls 'ext2type' hook on default supported types.
       
  2219  *
       
  2220  * @param string $ext The extension to search.
       
  2221  * @return string|null The file type, example: audio, video, document, spreadsheet, etc. Null if not found.
       
  2222  */
       
  2223 function wp_ext2type( $ext ) {
       
  2224 	$ext2type = apply_filters('ext2type', array(
       
  2225 		'audio' => array('aac','ac3','aif','aiff','mp1','mp2','mp3','m3a','m4a','m4b','ogg','ram','wav','wma'),
       
  2226 		'video' => array('asf','avi','divx','dv','mov','mpg','mpeg','mp4','mpv','ogm','qt','rm','vob','wmv', 'm4v'),
       
  2227 		'document' => array('doc','docx','pages','odt','rtf','pdf'),
       
  2228 		'spreadsheet' => array('xls','xlsx','numbers','ods'),
       
  2229 		'interactive' => array('ppt','pptx','key','odp','swf'),
       
  2230 		'text' => array('txt'),
       
  2231 		'archive' => array('tar','bz2','gz','cab','dmg','rar','sea','sit','sqx','zip'),
       
  2232 		'code' => array('css','html','php','js'),
       
  2233 	));
       
  2234 	foreach ( $ext2type as $type => $exts )
       
  2235 		if ( in_array($ext, $exts) )
       
  2236 			return $type;
       
  2237 }
       
  2238 
       
  2239 /**
       
  2240  * Retrieve the file type from the file name.
       
  2241  *
       
  2242  * You can optionally define the mime array, if needed.
       
  2243  *
       
  2244  * @since 2.0.4
       
  2245  *
       
  2246  * @param string $filename File name or path.
       
  2247  * @param array $mimes Optional. Key is the file extension with value as the mime type.
       
  2248  * @return array Values with extension first and mime type.
       
  2249  */
       
  2250 function wp_check_filetype( $filename, $mimes = null ) {
       
  2251 	if ( empty($mimes) )
       
  2252 		$mimes = get_allowed_mime_types();
       
  2253 	$type = false;
       
  2254 	$ext = false;
       
  2255 
       
  2256 	foreach ( $mimes as $ext_preg => $mime_match ) {
       
  2257 		$ext_preg = '!\.(' . $ext_preg . ')$!i';
       
  2258 		if ( preg_match( $ext_preg, $filename, $ext_matches ) ) {
       
  2259 			$type = $mime_match;
       
  2260 			$ext = $ext_matches[1];
       
  2261 			break;
       
  2262 		}
       
  2263 	}
       
  2264 
       
  2265 	return compact( 'ext', 'type' );
       
  2266 }
       
  2267 
       
  2268 /**
       
  2269  * Retrieve list of allowed mime types and file extensions.
       
  2270  *
       
  2271  * @since 2.8.6
       
  2272  *
       
  2273  * @return array Array of mime types keyed by the file extension regex corresponding to those types.
       
  2274  */
       
  2275 function get_allowed_mime_types() {
       
  2276 	static $mimes = false;
       
  2277 
       
  2278 	if ( !$mimes ) {
       
  2279 		// Accepted MIME types are set here as PCRE unless provided.
       
  2280 		$mimes = apply_filters( 'upload_mimes', array(
       
  2281 		'jpg|jpeg|jpe' => 'image/jpeg',
       
  2282 		'gif' => 'image/gif',
       
  2283 		'png' => 'image/png',
       
  2284 		'bmp' => 'image/bmp',
       
  2285 		'tif|tiff' => 'image/tiff',
       
  2286 		'ico' => 'image/x-icon',
       
  2287 		'asf|asx|wax|wmv|wmx' => 'video/asf',
       
  2288 		'avi' => 'video/avi',
       
  2289 		'divx' => 'video/divx',
       
  2290 		'flv' => 'video/x-flv',
       
  2291 		'mov|qt' => 'video/quicktime',
       
  2292 		'mpeg|mpg|mpe' => 'video/mpeg',
       
  2293 		'txt|c|cc|h' => 'text/plain',
       
  2294 		'rtx' => 'text/richtext',
       
  2295 		'css' => 'text/css',
       
  2296 		'htm|html' => 'text/html',
       
  2297 		'mp3|m4a' => 'audio/mpeg',
       
  2298 		'mp4|m4v' => 'video/mp4',
       
  2299 		'ra|ram' => 'audio/x-realaudio',
       
  2300 		'wav' => 'audio/wav',
       
  2301 		'ogg' => 'audio/ogg',
       
  2302 		'mid|midi' => 'audio/midi',
       
  2303 		'wma' => 'audio/wma',
       
  2304 		'rtf' => 'application/rtf',
       
  2305 		'js' => 'application/javascript',
       
  2306 		'pdf' => 'application/pdf',
       
  2307 		'doc|docx' => 'application/msword',
       
  2308 		'pot|pps|ppt|pptx' => 'application/vnd.ms-powerpoint',
       
  2309 		'wri' => 'application/vnd.ms-write',
       
  2310 		'xla|xls|xlsx|xlt|xlw' => 'application/vnd.ms-excel',
       
  2311 		'mdb' => 'application/vnd.ms-access',
       
  2312 		'mpp' => 'application/vnd.ms-project',
       
  2313 		'swf' => 'application/x-shockwave-flash',
       
  2314 		'class' => 'application/java',
       
  2315 		'tar' => 'application/x-tar',
       
  2316 		'zip' => 'application/zip',
       
  2317 		'gz|gzip' => 'application/x-gzip',
       
  2318 		'exe' => 'application/x-msdownload',
       
  2319 		// openoffice formats
       
  2320 		'odt' => 'application/vnd.oasis.opendocument.text',
       
  2321 		'odp' => 'application/vnd.oasis.opendocument.presentation',
       
  2322 		'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
       
  2323 		'odg' => 'application/vnd.oasis.opendocument.graphics',
       
  2324 		'odc' => 'application/vnd.oasis.opendocument.chart',
       
  2325 		'odb' => 'application/vnd.oasis.opendocument.database',
       
  2326 		'odf' => 'application/vnd.oasis.opendocument.formula',
       
  2327 		) );
       
  2328 	}
       
  2329 
       
  2330 	return $mimes;
       
  2331 }
       
  2332 
       
  2333 /**
       
  2334  * Retrieve nonce action "Are you sure" message.
       
  2335  *
       
  2336  * The action is split by verb and noun. The action format is as follows:
       
  2337  * verb-action_extra. The verb is before the first dash and has the format of
       
  2338  * letters and no spaces and numbers. The noun is after the dash and before the
       
  2339  * underscore, if an underscore exists. The noun is also only letters.
       
  2340  *
       
  2341  * The filter will be called for any action, which is not defined by WordPress.
       
  2342  * You may use the filter for your plugin to explain nonce actions to the user,
       
  2343  * when they get the "Are you sure?" message. The filter is in the format of
       
  2344  * 'explain_nonce_$verb-$noun' with the $verb replaced by the found verb and the
       
  2345  * $noun replaced by the found noun. The two parameters that are given to the
       
  2346  * hook are the localized "Are you sure you want to do this?" message with the
       
  2347  * extra text (the text after the underscore).
       
  2348  *
       
  2349  * @package WordPress
       
  2350  * @subpackage Security
       
  2351  * @since 2.0.4
       
  2352  *
       
  2353  * @param string $action Nonce action.
       
  2354  * @return string Are you sure message.
       
  2355  */
       
  2356 function wp_explain_nonce( $action ) {
       
  2357 	if ( $action !== -1 && preg_match( '/([a-z]+)-([a-z]+)(_(.+))?/', $action, $matches ) ) {
       
  2358 		$verb = $matches[1];
       
  2359 		$noun = $matches[2];
       
  2360 
       
  2361 		$trans = array();
       
  2362 		$trans['update']['attachment'] = array( __( 'Your attempt to edit this attachment: &#8220;%s&#8221; has failed.' ), 'get_the_title' );
       
  2363 
       
  2364 		$trans['add']['category']      = array( __( 'Your attempt to add this category has failed.' ), false );
       
  2365 		$trans['delete']['category']   = array( __( 'Your attempt to delete this category: &#8220;%s&#8221; has failed.' ), 'get_cat_name' );
       
  2366 		$trans['update']['category']   = array( __( 'Your attempt to edit this category: &#8220;%s&#8221; has failed.' ), 'get_cat_name' );
       
  2367 
       
  2368 		$trans['delete']['comment']    = array( __( 'Your attempt to delete this comment: &#8220;%s&#8221; has failed.' ), 'use_id' );
       
  2369 		$trans['unapprove']['comment'] = array( __( 'Your attempt to unapprove this comment: &#8220;%s&#8221; has failed.' ), 'use_id' );
       
  2370 		$trans['approve']['comment']   = array( __( 'Your attempt to approve this comment: &#8220;%s&#8221; has failed.' ), 'use_id' );
       
  2371 		$trans['update']['comment']    = array( __( 'Your attempt to edit this comment: &#8220;%s&#8221; has failed.' ), 'use_id' );
       
  2372 		$trans['bulk']['comments']     = array( __( 'Your attempt to bulk modify comments has failed.' ), false );
       
  2373 		$trans['moderate']['comments'] = array( __( 'Your attempt to moderate comments has failed.' ), false );
       
  2374 
       
  2375 		$trans['add']['bookmark']      = array( __( 'Your attempt to add this link has failed.' ), false );
       
  2376 		$trans['delete']['bookmark']   = array( __( 'Your attempt to delete this link: &#8220;%s&#8221; has failed.' ), 'use_id' );
       
  2377 		$trans['update']['bookmark']   = array( __( 'Your attempt to edit this link: &#8220;%s&#8221; has failed.' ), 'use_id' );
       
  2378 		$trans['bulk']['bookmarks']    = array( __( 'Your attempt to bulk modify links has failed.' ), false );
       
  2379 
       
  2380 		$trans['add']['page']          = array( __( 'Your attempt to add this page has failed.' ), false );
       
  2381 		$trans['delete']['page']       = array( __( 'Your attempt to delete this page: &#8220;%s&#8221; has failed.' ), 'get_the_title' );
       
  2382 		$trans['update']['page']       = array( __( 'Your attempt to edit this page: &#8220;%s&#8221; has failed.' ), 'get_the_title' );
       
  2383 
       
  2384 		$trans['edit']['plugin']       = array( __( 'Your attempt to edit this plugin file: &#8220;%s&#8221; has failed.' ), 'use_id' );
       
  2385 		$trans['activate']['plugin']   = array( __( 'Your attempt to activate this plugin: &#8220;%s&#8221; has failed.' ), 'use_id' );
       
  2386 		$trans['deactivate']['plugin'] = array( __( 'Your attempt to deactivate this plugin: &#8220;%s&#8221; has failed.' ), 'use_id' );
       
  2387 		$trans['upgrade']['plugin']    = array( __( 'Your attempt to upgrade this plugin: &#8220;%s&#8221; has failed.' ), 'use_id' );
       
  2388 
       
  2389 		$trans['add']['post']          = array( __( 'Your attempt to add this post has failed.' ), false );
       
  2390 		$trans['delete']['post']       = array( __( 'Your attempt to delete this post: &#8220;%s&#8221; has failed.' ), 'get_the_title' );
       
  2391 		$trans['update']['post']       = array( __( 'Your attempt to edit this post: &#8220;%s&#8221; has failed.' ), 'get_the_title' );
       
  2392 
       
  2393 		$trans['add']['user']          = array( __( 'Your attempt to add this user has failed.' ), false );
       
  2394 		$trans['delete']['users']      = array( __( 'Your attempt to delete users has failed.' ), false );
       
  2395 		$trans['bulk']['users']        = array( __( 'Your attempt to bulk modify users has failed.' ), false );
       
  2396 		$trans['update']['user']       = array( __( 'Your attempt to edit this user: &#8220;%s&#8221; has failed.' ), 'get_the_author_meta', 'display_name' );
       
  2397 		$trans['update']['profile']    = array( __( 'Your attempt to modify the profile for: &#8220;%s&#8221; has failed.' ), 'get_the_author_meta', 'display_name' );
       
  2398 
       
  2399 		$trans['update']['options']    = array( __( 'Your attempt to edit your settings has failed.' ), false );
       
  2400 		$trans['update']['permalink']  = array( __( 'Your attempt to change your permalink structure to: %s has failed.' ), 'use_id' );
       
  2401 		$trans['edit']['file']         = array( __( 'Your attempt to edit this file: &#8220;%s&#8221; has failed.' ), 'use_id' );
       
  2402 		$trans['edit']['theme']        = array( __( 'Your attempt to edit this theme file: &#8220;%s&#8221; has failed.' ), 'use_id' );
       
  2403 		$trans['switch']['theme']      = array( __( 'Your attempt to switch to this theme: &#8220;%s&#8221; has failed.' ), 'use_id' );
       
  2404 
       
  2405 		$trans['log']['out']           = array( sprintf( __( 'You are attempting to log out of %s' ), get_bloginfo( 'sitename' ) ), false );
       
  2406 
       
  2407 		if ( isset( $trans[$verb][$noun] ) ) {
       
  2408 			if ( !empty( $trans[$verb][$noun][1] ) ) {
       
  2409 				$lookup = $trans[$verb][$noun][1];
       
  2410 				if ( isset($trans[$verb][$noun][2]) )
       
  2411 					$lookup_value = $trans[$verb][$noun][2];
       
  2412 				$object = $matches[4];
       
  2413 				if ( 'use_id' != $lookup ) {
       
  2414 					if ( isset( $lookup_value ) )
       
  2415 						$object = call_user_func( $lookup, $lookup_value, $object );
       
  2416 					else
       
  2417 						$object = call_user_func( $lookup, $object );
       
  2418 				}
       
  2419 				return sprintf( $trans[$verb][$noun][0], esc_html($object) );
       
  2420 			} else {
       
  2421 				return $trans[$verb][$noun][0];
       
  2422 			}
       
  2423 		}
       
  2424 
       
  2425 		return apply_filters( 'explain_nonce_' . $verb . '-' . $noun, __( 'Are you sure you want to do this?' ), isset($matches[4]) ? $matches[4] : '' );
       
  2426 	} else {
       
  2427 		return apply_filters( 'explain_nonce_' . $action, __( 'Are you sure you want to do this?' ) );
       
  2428 	}
       
  2429 }
       
  2430 
       
  2431 /**
       
  2432  * Display "Are You Sure" message to confirm the action being taken.
       
  2433  *
       
  2434  * If the action has the nonce explain message, then it will be displayed along
       
  2435  * with the "Are you sure?" message.
       
  2436  *
       
  2437  * @package WordPress
       
  2438  * @subpackage Security
       
  2439  * @since 2.0.4
       
  2440  *
       
  2441  * @param string $action The nonce action.
       
  2442  */
       
  2443 function wp_nonce_ays( $action ) {
       
  2444 	$title = __( 'WordPress Failure Notice' );
       
  2445 	$html = esc_html( wp_explain_nonce( $action ) );
       
  2446 	if ( 'log-out' == $action )
       
  2447 		$html .= "</p><p>" . sprintf( __( "Do you really want to <a href='%s'>log out</a>?"), wp_logout_url() );
       
  2448 	elseif ( wp_get_referer() )
       
  2449 		$html .= "</p><p><a href='" . esc_url( remove_query_arg( 'updated', wp_get_referer() ) ) . "'>" . __( 'Please try again.' ) . "</a>";
       
  2450 
       
  2451 	wp_die( $html, $title, array('response' => 403) );
       
  2452 }
       
  2453 
       
  2454 /**
       
  2455  * Kill WordPress execution and display HTML message with error message.
       
  2456  *
       
  2457  * Call this function complements the die() PHP function. The difference is that
       
  2458  * HTML will be displayed to the user. It is recommended to use this function
       
  2459  * only, when the execution should not continue any further. It is not
       
  2460  * recommended to call this function very often and try to handle as many errors
       
  2461  * as possible siliently.
       
  2462  *
       
  2463  * @since 2.0.4
       
  2464  *
       
  2465  * @param string $message Error message.
       
  2466  * @param string $title Error title.
       
  2467  * @param string|array $args Optional arguements to control behaviour.
       
  2468  */
       
  2469 function wp_die( $message, $title = '', $args = array() ) {
       
  2470 	global $wp_locale;
       
  2471 
       
  2472 	$defaults = array( 'response' => 500 );
       
  2473 	$r = wp_parse_args($args, $defaults);
       
  2474 
       
  2475 	$have_gettext = function_exists('__');
       
  2476 
       
  2477 	if ( function_exists( 'is_wp_error' ) && is_wp_error( $message ) ) {
       
  2478 		if ( empty( $title ) ) {
       
  2479 			$error_data = $message->get_error_data();
       
  2480 			if ( is_array( $error_data ) && isset( $error_data['title'] ) )
       
  2481 				$title = $error_data['title'];
       
  2482 		}
       
  2483 		$errors = $message->get_error_messages();
       
  2484 		switch ( count( $errors ) ) :
       
  2485 		case 0 :
       
  2486 			$message = '';
       
  2487 			break;
       
  2488 		case 1 :
       
  2489 			$message = "<p>{$errors[0]}</p>";
       
  2490 			break;
       
  2491 		default :
       
  2492 			$message = "<ul>\n\t\t<li>" . join( "</li>\n\t\t<li>", $errors ) . "</li>\n\t</ul>";
       
  2493 			break;
       
  2494 		endswitch;
       
  2495 	} elseif ( is_string( $message ) ) {
       
  2496 		$message = "<p>$message</p>";
       
  2497 	}
       
  2498 
       
  2499 	if ( isset( $r['back_link'] ) && $r['back_link'] ) {
       
  2500 		$back_text = $have_gettext? __('&laquo; Back') : '&laquo; Back';
       
  2501 		$message .= "\n<p><a href='javascript:history.back()'>$back_text</p>";
       
  2502 	}
       
  2503 
       
  2504 	if ( defined( 'WP_SITEURL' ) && '' != WP_SITEURL )
       
  2505 		$admin_dir = WP_SITEURL . '/wp-admin/';
       
  2506 	elseif ( function_exists( 'get_bloginfo' ) && '' != get_bloginfo( 'wpurl' ) )
       
  2507 		$admin_dir = get_bloginfo( 'wpurl' ) . '/wp-admin/';
       
  2508 	elseif ( strpos( $_SERVER['PHP_SELF'], 'wp-admin' ) !== false )
       
  2509 		$admin_dir = '';
       
  2510 	else
       
  2511 		$admin_dir = 'wp-admin/';
       
  2512 
       
  2513 	if ( !function_exists( 'did_action' ) || !did_action( 'admin_head' ) ) :
       
  2514 	if( !headers_sent() ){
       
  2515 		status_header( $r['response'] );
       
  2516 		nocache_headers();
       
  2517 		header( 'Content-Type: text/html; charset=utf-8' );
       
  2518 	}
       
  2519 
       
  2520 	if ( empty($title) ) {
       
  2521 		$title = $have_gettext? __('WordPress &rsaquo; Error') : 'WordPress &rsaquo; Error';
       
  2522 	}
       
  2523 
       
  2524 	$text_direction = 'ltr';
       
  2525 	if ( isset($r['text_direction']) && $r['text_direction'] == 'rtl' ) $text_direction = 'rtl';
       
  2526 	if ( ( $wp_locale ) && ( 'rtl' == $wp_locale->text_direction ) ) $text_direction = 'rtl';
       
  2527 ?>
       
  2528 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
       
  2529 <!-- Ticket #11289, IE bug fix: always pad the error page with enough characters such that it is greater than 512 bytes, even after gzip compression abcdefghijklmnopqrstuvwxyz1234567890aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz11223344556677889900abacbcbdcdcededfefegfgfhghgihihjijikjkjlklkmlmlnmnmononpopoqpqprqrqsrsrtstsubcbcdcdedefefgfabcadefbghicjkldmnoepqrfstugvwxhyz1i234j567k890laabmbccnddeoeffpgghqhiirjjksklltmmnunoovppqwqrrxsstytuuzvvw0wxx1yyz2z113223434455666777889890091abc2def3ghi4jkl5mno6pqr7stu8vwx9yz11aab2bcc3dd4ee5ff6gg7hh8ii9j0jk1kl2lmm3nnoo4p5pq6qrr7ss8tt9uuvv0wwx1x2yyzz13aba4cbcb5dcdc6dedfef8egf9gfh0ghg1ihi2hji3jik4jkj5lkl6kml7mln8mnm9ono -->
       
  2530 <html xmlns="http://www.w3.org/1999/xhtml" <?php if ( function_exists( 'language_attributes' ) ) language_attributes(); ?>>
       
  2531 <head>
       
  2532 	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
       
  2533 	<title><?php echo $title ?></title>
       
  2534 	<link rel="stylesheet" href="<?php echo $admin_dir; ?>css/install.css" type="text/css" />
       
  2535 <?php
       
  2536 if ( 'rtl' == $text_direction ) : ?>
       
  2537 	<link rel="stylesheet" href="<?php echo $admin_dir; ?>css/install-rtl.css" type="text/css" />
       
  2538 <?php endif; ?>
       
  2539 </head>
       
  2540 <body id="error-page">
       
  2541 <?php endif; ?>
       
  2542 	<?php echo $message; ?>
       
  2543 </body>
       
  2544 </html>
       
  2545 <?php
       
  2546 	die();
       
  2547 }
       
  2548 
       
  2549 /**
       
  2550  * Retrieve the WordPress home page URL.
       
  2551  *
       
  2552  * If the constant named 'WP_HOME' exists, then it willl be used and returned by
       
  2553  * the function. This can be used to counter the redirection on your local
       
  2554  * development environment.
       
  2555  *
       
  2556  * @access private
       
  2557  * @package WordPress
       
  2558  * @since 2.2.0
       
  2559  *
       
  2560  * @param string $url URL for the home location
       
  2561  * @return string Homepage location.
       
  2562  */
       
  2563 function _config_wp_home( $url = '' ) {
       
  2564 	if ( defined( 'WP_HOME' ) )
       
  2565 		return WP_HOME;
       
  2566 	return $url;
       
  2567 }
       
  2568 
       
  2569 /**
       
  2570  * Retrieve the WordPress site URL.
       
  2571  *
       
  2572  * If the constant named 'WP_SITEURL' is defined, then the value in that
       
  2573  * constant will always be returned. This can be used for debugging a site on
       
  2574  * your localhost while not having to change the database to your URL.
       
  2575  *
       
  2576  * @access private
       
  2577  * @package WordPress
       
  2578  * @since 2.2.0
       
  2579  *
       
  2580  * @param string $url URL to set the WordPress site location.
       
  2581  * @return string The WordPress Site URL
       
  2582  */
       
  2583 function _config_wp_siteurl( $url = '' ) {
       
  2584 	if ( defined( 'WP_SITEURL' ) )
       
  2585 		return WP_SITEURL;
       
  2586 	return $url;
       
  2587 }
       
  2588 
       
  2589 /**
       
  2590  * Set the localized direction for MCE plugin.
       
  2591  *
       
  2592  * Will only set the direction to 'rtl', if the WordPress locale has the text
       
  2593  * direction set to 'rtl'.
       
  2594  *
       
  2595  * Fills in the 'directionality', 'plugins', and 'theme_advanced_button1' array
       
  2596  * keys. These keys are then returned in the $input array.
       
  2597  *
       
  2598  * @access private
       
  2599  * @package WordPress
       
  2600  * @subpackage MCE
       
  2601  * @since 2.1.0
       
  2602  *
       
  2603  * @param array $input MCE plugin array.
       
  2604  * @return array Direction set for 'rtl', if needed by locale.
       
  2605  */
       
  2606 function _mce_set_direction( $input ) {
       
  2607 	global $wp_locale;
       
  2608 
       
  2609 	if ( 'rtl' == $wp_locale->text_direction ) {
       
  2610 		$input['directionality'] = 'rtl';
       
  2611 		$input['plugins'] .= ',directionality';
       
  2612 		$input['theme_advanced_buttons1'] .= ',ltr';
       
  2613 	}
       
  2614 
       
  2615 	return $input;
       
  2616 }
       
  2617 
       
  2618 
       
  2619 /**
       
  2620  * Convert smiley code to the icon graphic file equivalent.
       
  2621  *
       
  2622  * You can turn off smilies, by going to the write setting screen and unchecking
       
  2623  * the box, or by setting 'use_smilies' option to false or removing the option.
       
  2624  *
       
  2625  * Plugins may override the default smiley list by setting the $wpsmiliestrans
       
  2626  * to an array, with the key the code the blogger types in and the value the
       
  2627  * image file.
       
  2628  *
       
  2629  * The $wp_smiliessearch global is for the regular expression and is set each
       
  2630  * time the function is called.
       
  2631  *
       
  2632  * The full list of smilies can be found in the function and won't be listed in
       
  2633  * the description. Probably should create a Codex page for it, so that it is
       
  2634  * available.
       
  2635  *
       
  2636  * @global array $wpsmiliestrans
       
  2637  * @global array $wp_smiliessearch
       
  2638  * @since 2.2.0
       
  2639  */
       
  2640 function smilies_init() {
       
  2641 	global $wpsmiliestrans, $wp_smiliessearch;
       
  2642 
       
  2643 	// don't bother setting up smilies if they are disabled
       
  2644 	if ( !get_option( 'use_smilies' ) )
       
  2645 		return;
       
  2646 
       
  2647 	if ( !isset( $wpsmiliestrans ) ) {
       
  2648 		$wpsmiliestrans = array(
       
  2649 		':mrgreen:' => 'icon_mrgreen.gif',
       
  2650 		':neutral:' => 'icon_neutral.gif',
       
  2651 		':twisted:' => 'icon_twisted.gif',
       
  2652 		  ':arrow:' => 'icon_arrow.gif',
       
  2653 		  ':shock:' => 'icon_eek.gif',
       
  2654 		  ':smile:' => 'icon_smile.gif',
       
  2655 		    ':???:' => 'icon_confused.gif',
       
  2656 		   ':cool:' => 'icon_cool.gif',
       
  2657 		   ':evil:' => 'icon_evil.gif',
       
  2658 		   ':grin:' => 'icon_biggrin.gif',
       
  2659 		   ':idea:' => 'icon_idea.gif',
       
  2660 		   ':oops:' => 'icon_redface.gif',
       
  2661 		   ':razz:' => 'icon_razz.gif',
       
  2662 		   ':roll:' => 'icon_rolleyes.gif',
       
  2663 		   ':wink:' => 'icon_wink.gif',
       
  2664 		    ':cry:' => 'icon_cry.gif',
       
  2665 		    ':eek:' => 'icon_surprised.gif',
       
  2666 		    ':lol:' => 'icon_lol.gif',
       
  2667 		    ':mad:' => 'icon_mad.gif',
       
  2668 		    ':sad:' => 'icon_sad.gif',
       
  2669 		      '8-)' => 'icon_cool.gif',
       
  2670 		      '8-O' => 'icon_eek.gif',
       
  2671 		      ':-(' => 'icon_sad.gif',
       
  2672 		      ':-)' => 'icon_smile.gif',
       
  2673 		      ':-?' => 'icon_confused.gif',
       
  2674 		      ':-D' => 'icon_biggrin.gif',
       
  2675 		      ':-P' => 'icon_razz.gif',
       
  2676 		      ':-o' => 'icon_surprised.gif',
       
  2677 		      ':-x' => 'icon_mad.gif',
       
  2678 		      ':-|' => 'icon_neutral.gif',
       
  2679 		      ';-)' => 'icon_wink.gif',
       
  2680 		       '8)' => 'icon_cool.gif',
       
  2681 		       '8O' => 'icon_eek.gif',
       
  2682 		       ':(' => 'icon_sad.gif',
       
  2683 		       ':)' => 'icon_smile.gif',
       
  2684 		       ':?' => 'icon_confused.gif',
       
  2685 		       ':D' => 'icon_biggrin.gif',
       
  2686 		       ':P' => 'icon_razz.gif',
       
  2687 		       ':o' => 'icon_surprised.gif',
       
  2688 		       ':x' => 'icon_mad.gif',
       
  2689 		       ':|' => 'icon_neutral.gif',
       
  2690 		       ';)' => 'icon_wink.gif',
       
  2691 		      ':!:' => 'icon_exclaim.gif',
       
  2692 		      ':?:' => 'icon_question.gif',
       
  2693 		);
       
  2694 	}
       
  2695 
       
  2696 	if (count($wpsmiliestrans) == 0) {
       
  2697 		return;
       
  2698 	}
       
  2699 
       
  2700 	/*
       
  2701 	 * NOTE: we sort the smilies in reverse key order. This is to make sure
       
  2702 	 * we match the longest possible smilie (:???: vs :?) as the regular
       
  2703 	 * expression used below is first-match
       
  2704 	 */
       
  2705 	krsort($wpsmiliestrans);
       
  2706 
       
  2707 	$wp_smiliessearch = '/(?:\s|^)';
       
  2708 
       
  2709 	$subchar = '';
       
  2710 	foreach ( (array) $wpsmiliestrans as $smiley => $img ) {
       
  2711 		$firstchar = substr($smiley, 0, 1);
       
  2712 		$rest = substr($smiley, 1);
       
  2713 
       
  2714 		// new subpattern?
       
  2715 		if ($firstchar != $subchar) {
       
  2716 			if ($subchar != '') {
       
  2717 				$wp_smiliessearch .= ')|(?:\s|^)';
       
  2718 			}
       
  2719 			$subchar = $firstchar;
       
  2720 			$wp_smiliessearch .= preg_quote($firstchar, '/') . '(?:';
       
  2721 		} else {
       
  2722 			$wp_smiliessearch .= '|';
       
  2723 		}
       
  2724 		$wp_smiliessearch .= preg_quote($rest, '/');
       
  2725 	}
       
  2726 
       
  2727 	$wp_smiliessearch .= ')(?:\s|$)/m';
       
  2728 }
       
  2729 
       
  2730 /**
       
  2731  * Merge user defined arguments into defaults array.
       
  2732  *
       
  2733  * This function is used throughout WordPress to allow for both string or array
       
  2734  * to be merged into another array.
       
  2735  *
       
  2736  * @since 2.2.0
       
  2737  *
       
  2738  * @param string|array $args Value to merge with $defaults
       
  2739  * @param array $defaults Array that serves as the defaults.
       
  2740  * @return array Merged user defined values with defaults.
       
  2741  */
       
  2742 function wp_parse_args( $args, $defaults = '' ) {
       
  2743 	if ( is_object( $args ) )
       
  2744 		$r = get_object_vars( $args );
       
  2745 	elseif ( is_array( $args ) )
       
  2746 		$r =& $args;
       
  2747 	else
       
  2748 		wp_parse_str( $args, $r );
       
  2749 
       
  2750 	if ( is_array( $defaults ) )
       
  2751 		return array_merge( $defaults, $r );
       
  2752 	return $r;
       
  2753 }
       
  2754 
       
  2755 /**
       
  2756  * Determines if default embed handlers should be loaded.
       
  2757  *
       
  2758  * Checks to make sure that the embeds library hasn't already been loaded. If
       
  2759  * it hasn't, then it will load the embeds library.
       
  2760  *
       
  2761  * @since 2.9
       
  2762  */
       
  2763 function wp_maybe_load_embeds() {
       
  2764 	if ( ! apply_filters('load_default_embeds', true) )
       
  2765 		return;
       
  2766 	require_once( ABSPATH . WPINC . '/default-embeds.php' );
       
  2767 }
       
  2768 
       
  2769 /**
       
  2770  * Determines if Widgets library should be loaded.
       
  2771  *
       
  2772  * Checks to make sure that the widgets library hasn't already been loaded. If
       
  2773  * it hasn't, then it will load the widgets library and run an action hook.
       
  2774  *
       
  2775  * @since 2.2.0
       
  2776  * @uses add_action() Calls '_admin_menu' hook with 'wp_widgets_add_menu' value.
       
  2777  */
       
  2778 function wp_maybe_load_widgets() {
       
  2779 	if ( ! apply_filters('load_default_widgets', true) )
       
  2780 		return;
       
  2781 	require_once( ABSPATH . WPINC . '/default-widgets.php' );
       
  2782 	add_action( '_admin_menu', 'wp_widgets_add_menu' );
       
  2783 }
       
  2784 
       
  2785 /**
       
  2786  * Append the Widgets menu to the themes main menu.
       
  2787  *
       
  2788  * @since 2.2.0
       
  2789  * @uses $submenu The administration submenu list.
       
  2790  */
       
  2791 function wp_widgets_add_menu() {
       
  2792 	global $submenu;
       
  2793 	$submenu['themes.php'][7] = array( __( 'Widgets' ), 'switch_themes', 'widgets.php' );
       
  2794 	ksort( $submenu['themes.php'], SORT_NUMERIC );
       
  2795 }
       
  2796 
       
  2797 /**
       
  2798  * Flush all output buffers for PHP 5.2.
       
  2799  *
       
  2800  * Make sure all output buffers are flushed before our singletons our destroyed.
       
  2801  *
       
  2802  * @since 2.2.0
       
  2803  */
       
  2804 function wp_ob_end_flush_all() {
       
  2805 	$levels = ob_get_level();
       
  2806 	for ($i=0; $i<$levels; $i++)
       
  2807 		ob_end_flush();
       
  2808 }
       
  2809 
       
  2810 /**
       
  2811  * Load the correct database class file.
       
  2812  *
       
  2813  * This function is used to load the database class file either at runtime or by
       
  2814  * wp-admin/setup-config.php We must globalise $wpdb to ensure that it is
       
  2815  * defined globally by the inline code in wp-db.php.
       
  2816  *
       
  2817  * @since 2.5.0
       
  2818  * @global $wpdb WordPress Database Object
       
  2819  */
       
  2820 function require_wp_db() {
       
  2821 	global $wpdb;
       
  2822 	if ( file_exists( WP_CONTENT_DIR . '/db.php' ) )
       
  2823 		require_once( WP_CONTENT_DIR . '/db.php' );
       
  2824 	else
       
  2825 		require_once( ABSPATH . WPINC . '/wp-db.php' );
       
  2826 }
       
  2827 
       
  2828 /**
       
  2829  * Load custom DB error or display WordPress DB error.
       
  2830  *
       
  2831  * If a file exists in the wp-content directory named db-error.php, then it will
       
  2832  * be loaded instead of displaying the WordPress DB error. If it is not found,
       
  2833  * then the WordPress DB error will be displayed instead.
       
  2834  *
       
  2835  * The WordPress DB error sets the HTTP status header to 500 to try to prevent
       
  2836  * search engines from caching the message. Custom DB messages should do the
       
  2837  * same.
       
  2838  *
       
  2839  * This function was backported to the the WordPress 2.3.2, but originally was
       
  2840  * added in WordPress 2.5.0.
       
  2841  *
       
  2842  * @since 2.3.2
       
  2843  * @uses $wpdb
       
  2844  */
       
  2845 function dead_db() {
       
  2846 	global $wpdb;
       
  2847 
       
  2848 	// Load custom DB error template, if present.
       
  2849 	if ( file_exists( WP_CONTENT_DIR . '/db-error.php' ) ) {
       
  2850 		require_once( WP_CONTENT_DIR . '/db-error.php' );
       
  2851 		die();
       
  2852 	}
       
  2853 
       
  2854 	// If installing or in the admin, provide the verbose message.
       
  2855 	if ( defined('WP_INSTALLING') || defined('WP_ADMIN') )
       
  2856 		wp_die($wpdb->error);
       
  2857 
       
  2858 	// Otherwise, be terse.
       
  2859 	status_header( 500 );
       
  2860 	nocache_headers();
       
  2861 	header( 'Content-Type: text/html; charset=utf-8' );
       
  2862 ?>
       
  2863 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
       
  2864 <html xmlns="http://www.w3.org/1999/xhtml" <?php if ( function_exists( 'language_attributes' ) ) language_attributes(); ?>>
       
  2865 <head>
       
  2866 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
       
  2867 	<title>Database Error</title>
       
  2868 
       
  2869 </head>
       
  2870 <body>
       
  2871 	<h1>Error establishing a database connection</h1>
       
  2872 </body>
       
  2873 </html>
       
  2874 <?php
       
  2875 	die();
       
  2876 }
       
  2877 
       
  2878 /**
       
  2879  * Converts value to nonnegative integer.
       
  2880  *
       
  2881  * @since 2.5.0
       
  2882  *
       
  2883  * @param mixed $maybeint Data you wish to have convered to an nonnegative integer
       
  2884  * @return int An nonnegative integer
       
  2885  */
       
  2886 function absint( $maybeint ) {
       
  2887 	return abs( intval( $maybeint ) );
       
  2888 }
       
  2889 
       
  2890 /**
       
  2891  * Determines if the blog can be accessed over SSL.
       
  2892  *
       
  2893  * Determines if blog can be accessed over SSL by using cURL to access the site
       
  2894  * using the https in the siteurl. Requires cURL extension to work correctly.
       
  2895  *
       
  2896  * @since 2.5.0
       
  2897  *
       
  2898  * @return bool Whether or not SSL access is available
       
  2899  */
       
  2900 function url_is_accessable_via_ssl($url)
       
  2901 {
       
  2902 	if (in_array('curl', get_loaded_extensions())) {
       
  2903 		$ssl = preg_replace( '/^http:\/\//', 'https://',  $url );
       
  2904 
       
  2905 		$ch = curl_init();
       
  2906 		curl_setopt($ch, CURLOPT_URL, $ssl);
       
  2907 		curl_setopt($ch, CURLOPT_FAILONERROR, true);
       
  2908 		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
       
  2909 		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
       
  2910 		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
       
  2911 
       
  2912 		curl_exec($ch);
       
  2913 
       
  2914 		$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
       
  2915 		curl_close ($ch);
       
  2916 
       
  2917 		if ($status == 200 || $status == 401) {
       
  2918 			return true;
       
  2919 		}
       
  2920 	}
       
  2921 	return false;
       
  2922 }
       
  2923 
       
  2924 /**
       
  2925  * Secure URL, if available or the given URL.
       
  2926  *
       
  2927  * @since 2.5.0
       
  2928  *
       
  2929  * @param string $url Complete URL path with transport.
       
  2930  * @return string Secure or regular URL path.
       
  2931  */
       
  2932 function atom_service_url_filter($url)
       
  2933 {
       
  2934 	if ( url_is_accessable_via_ssl($url) )
       
  2935 		return preg_replace( '/^http:\/\//', 'https://',  $url );
       
  2936 	else
       
  2937 		return $url;
       
  2938 }
       
  2939 
       
  2940 /**
       
  2941  * Marks a function as deprecated and informs when it has been used.
       
  2942  *
       
  2943  * There is a hook deprecated_function_run that will be called that can be used
       
  2944  * to get the backtrace up to what file and function called the deprecated
       
  2945  * function.
       
  2946  *
       
  2947  * The current behavior is to trigger an user error if WP_DEBUG is true.
       
  2948  *
       
  2949  * This function is to be used in every function in depreceated.php
       
  2950  *
       
  2951  * @package WordPress
       
  2952  * @package Debug
       
  2953  * @since 2.5.0
       
  2954  * @access private
       
  2955  *
       
  2956  * @uses do_action() Calls 'deprecated_function_run' and passes the function name and what to use instead.
       
  2957  * @uses apply_filters() Calls 'deprecated_function_trigger_error' and expects boolean value of true to do trigger or false to not trigger error.
       
  2958  *
       
  2959  * @param string $function The function that was called
       
  2960  * @param string $version The version of WordPress that deprecated the function
       
  2961  * @param string $replacement Optional. The function that should have been called
       
  2962  */
       
  2963 function _deprecated_function($function, $version, $replacement=null) {
       
  2964 
       
  2965 	do_action('deprecated_function_run', $function, $replacement);
       
  2966 
       
  2967 	// Allow plugin to filter the output error trigger
       
  2968 	if( WP_DEBUG && apply_filters( 'deprecated_function_trigger_error', true )) {
       
  2969 		if( !is_null($replacement) )
       
  2970 			trigger_error( sprintf( __('%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.'), $function, $version, $replacement ) );
       
  2971 		else
       
  2972 			trigger_error( sprintf( __('%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.'), $function, $version ) );
       
  2973 	}
       
  2974 }
       
  2975 
       
  2976 /**
       
  2977  * Marks a file as deprecated and informs when it has been used.
       
  2978  *
       
  2979  * There is a hook deprecated_file_included that will be called that can be used
       
  2980  * to get the backtrace up to what file and function included the deprecated
       
  2981  * file.
       
  2982  *
       
  2983  * The current behavior is to trigger an user error if WP_DEBUG is true.
       
  2984  *
       
  2985  * This function is to be used in every file that is depreceated
       
  2986  *
       
  2987  * @package WordPress
       
  2988  * @package Debug
       
  2989  * @since 2.5.0
       
  2990  * @access private
       
  2991  *
       
  2992  * @uses do_action() Calls 'deprecated_file_included' and passes the file name and what to use instead.
       
  2993  * @uses apply_filters() Calls 'deprecated_file_trigger_error' and expects boolean value of true to do trigger or false to not trigger error.
       
  2994  *
       
  2995  * @param string $file The file that was included
       
  2996  * @param string $version The version of WordPress that deprecated the function
       
  2997  * @param string $replacement Optional. The function that should have been called
       
  2998  */
       
  2999 function _deprecated_file($file, $version, $replacement=null) {
       
  3000 
       
  3001 	do_action('deprecated_file_included', $file, $replacement);
       
  3002 
       
  3003 	// Allow plugin to filter the output error trigger
       
  3004 	if( WP_DEBUG && apply_filters( 'deprecated_file_trigger_error', true ) ) {
       
  3005 		if( !is_null($replacement) )
       
  3006 			trigger_error( sprintf( __('%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.'), $file, $version, $replacement ) );
       
  3007 		else
       
  3008 			trigger_error( sprintf( __('%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.'), $file, $version ) );
       
  3009 	}
       
  3010 }
       
  3011 
       
  3012 /**
       
  3013  * Is the server running earlier than 1.5.0 version of lighttpd
       
  3014  *
       
  3015  * @since 2.5.0
       
  3016  *
       
  3017  * @return bool Whether the server is running lighttpd < 1.5.0
       
  3018  */
       
  3019 function is_lighttpd_before_150() {
       
  3020 	$server_parts = explode( '/', isset( $_SERVER['SERVER_SOFTWARE'] )? $_SERVER['SERVER_SOFTWARE'] : '' );
       
  3021 	$server_parts[1] = isset( $server_parts[1] )? $server_parts[1] : '';
       
  3022 	return  'lighttpd' == $server_parts[0] && -1 == version_compare( $server_parts[1], '1.5.0' );
       
  3023 }
       
  3024 
       
  3025 /**
       
  3026  * Does the specified module exist in the apache config?
       
  3027  *
       
  3028  * @since 2.5.0
       
  3029  *
       
  3030  * @param string $mod e.g. mod_rewrite
       
  3031  * @param bool $default The default return value if the module is not found
       
  3032  * @return bool
       
  3033  */
       
  3034 function apache_mod_loaded($mod, $default = false) {
       
  3035 	global $is_apache;
       
  3036 
       
  3037 	if ( !$is_apache )
       
  3038 		return false;
       
  3039 
       
  3040 	if ( function_exists('apache_get_modules') ) {
       
  3041 		$mods = apache_get_modules();
       
  3042 		if ( in_array($mod, $mods) )
       
  3043 			return true;
       
  3044 	} elseif ( function_exists('phpinfo') ) {
       
  3045 			ob_start();
       
  3046 			phpinfo(8);
       
  3047 			$phpinfo = ob_get_clean();
       
  3048 			if ( false !== strpos($phpinfo, $mod) )
       
  3049 				return true;
       
  3050 	}
       
  3051 	return $default;
       
  3052 }
       
  3053 
       
  3054 /**
       
  3055  * File validates against allowed set of defined rules.
       
  3056  *
       
  3057  * A return value of '1' means that the $file contains either '..' or './'. A
       
  3058  * return value of '2' means that the $file contains ':' after the first
       
  3059  * character. A return value of '3' means that the file is not in the allowed
       
  3060  * files list.
       
  3061  *
       
  3062  * @since 1.2.0
       
  3063  *
       
  3064  * @param string $file File path.
       
  3065  * @param array $allowed_files List of allowed files.
       
  3066  * @return int 0 means nothing is wrong, greater than 0 means something was wrong.
       
  3067  */
       
  3068 function validate_file( $file, $allowed_files = '' ) {
       
  3069 	if ( false !== strpos( $file, '..' ))
       
  3070 		return 1;
       
  3071 
       
  3072 	if ( false !== strpos( $file, './' ))
       
  3073 		return 1;
       
  3074 
       
  3075 	if (!empty ( $allowed_files ) && (!in_array( $file, $allowed_files ) ) )
       
  3076 		return 3;
       
  3077 
       
  3078 	if (':' == substr( $file, 1, 1 ))
       
  3079 		return 2;
       
  3080 
       
  3081 	return 0;
       
  3082 }
       
  3083 
       
  3084 /**
       
  3085  * Determine if SSL is used.
       
  3086  *
       
  3087  * @since 2.6.0
       
  3088  *
       
  3089  * @return bool True if SSL, false if not used.
       
  3090  */
       
  3091 function is_ssl() {
       
  3092 	if ( isset($_SERVER['HTTPS']) ) {
       
  3093 		if ( 'on' == strtolower($_SERVER['HTTPS']) )
       
  3094 			return true;
       
  3095 		if ( '1' == $_SERVER['HTTPS'] )
       
  3096 			return true;
       
  3097 	} elseif ( isset($_SERVER['SERVER_PORT']) && ( '443' == $_SERVER['SERVER_PORT'] ) ) {
       
  3098 		return true;
       
  3099 	}
       
  3100 	return false;
       
  3101 }
       
  3102 
       
  3103 /**
       
  3104  * Whether SSL login should be forced.
       
  3105  *
       
  3106  * @since 2.6.0
       
  3107  *
       
  3108  * @param string|bool $force Optional.
       
  3109  * @return bool True if forced, false if not forced.
       
  3110  */
       
  3111 function force_ssl_login( $force = null ) {
       
  3112 	static $forced = false;
       
  3113 
       
  3114 	if ( !is_null( $force ) ) {
       
  3115 		$old_forced = $forced;
       
  3116 		$forced = $force;
       
  3117 		return $old_forced;
       
  3118 	}
       
  3119 
       
  3120 	return $forced;
       
  3121 }
       
  3122 
       
  3123 /**
       
  3124  * Whether to force SSL used for the Administration Panels.
       
  3125  *
       
  3126  * @since 2.6.0
       
  3127  *
       
  3128  * @param string|bool $force
       
  3129  * @return bool True if forced, false if not forced.
       
  3130  */
       
  3131 function force_ssl_admin( $force = null ) {
       
  3132 	static $forced = false;
       
  3133 
       
  3134 	if ( !is_null( $force ) ) {
       
  3135 		$old_forced = $forced;
       
  3136 		$forced = $force;
       
  3137 		return $old_forced;
       
  3138 	}
       
  3139 
       
  3140 	return $forced;
       
  3141 }
       
  3142 
       
  3143 /**
       
  3144  * Guess the URL for the site.
       
  3145  *
       
  3146  * Will remove wp-admin links to retrieve only return URLs not in the wp-admin
       
  3147  * directory.
       
  3148  *
       
  3149  * @since 2.6.0
       
  3150  *
       
  3151  * @return string
       
  3152  */
       
  3153 function wp_guess_url() {
       
  3154 	if ( defined('WP_SITEURL') && '' != WP_SITEURL ) {
       
  3155 		$url = WP_SITEURL;
       
  3156 	} else {
       
  3157 		$schema = ( isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on' ) ? 'https://' : 'http://';
       
  3158 		$url = preg_replace('|/wp-admin/.*|i', '', $schema . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
       
  3159 	}
       
  3160 	return $url;
       
  3161 }
       
  3162 
       
  3163 /**
       
  3164  * Suspend cache invalidation.
       
  3165  *
       
  3166  * Turns cache invalidation on and off.  Useful during imports where you don't wont to do invalidations
       
  3167  * every time a post is inserted.  Callers must be sure that what they are doing won't lead to an inconsistent
       
  3168  * cache when invalidation is suspended.
       
  3169  *
       
  3170  * @since 2.7.0
       
  3171  *
       
  3172  * @param bool $suspend Whether to suspend or enable cache invalidation
       
  3173  * @return bool The current suspend setting
       
  3174  */
       
  3175 function wp_suspend_cache_invalidation($suspend = true) {
       
  3176 	global $_wp_suspend_cache_invalidation;
       
  3177 
       
  3178 	$current_suspend = $_wp_suspend_cache_invalidation;
       
  3179 	$_wp_suspend_cache_invalidation = $suspend;
       
  3180 	return $current_suspend;
       
  3181 }
       
  3182 
       
  3183 function get_site_option( $key, $default = false, $use_cache = true ) {
       
  3184 	// Allow plugins to short-circuit site options.
       
  3185  	$pre = apply_filters( 'pre_site_option_' . $key, false );
       
  3186  	if ( false !== $pre )
       
  3187  		return $pre;
       
  3188 
       
  3189  	$value = get_option($key, $default);
       
  3190 
       
  3191  	return apply_filters( 'site_option_' . $key, $value );
       
  3192 }
       
  3193 
       
  3194 // expects $key, $value not to be SQL escaped
       
  3195 function add_site_option( $key, $value ) {
       
  3196 	$value = apply_filters( 'pre_add_site_option_' . $key, $value );
       
  3197 	$result =  add_option($key, $value);
       
  3198 	do_action( "add_site_option_{$key}", $key, $value );
       
  3199 	return $result;
       
  3200 }
       
  3201 
       
  3202 function delete_site_option( $key ) {
       
  3203 	$result = delete_option($key);
       
  3204 	do_action( "delete_site_option_{$key}", $key );
       
  3205 	return $result;
       
  3206 }
       
  3207 
       
  3208 // expects $key, $value not to be SQL escaped
       
  3209 function update_site_option( $key, $value ) {
       
  3210 	$oldvalue = get_site_option( $key );
       
  3211 	$value = apply_filters( 'pre_update_site_option_' . $key, $value, $oldvalue );
       
  3212 	$result = update_option($key, $value);
       
  3213 	do_action( "update_site_option_{$key}", $key, $value );
       
  3214 	return $result;
       
  3215 }
       
  3216 
       
  3217 /**
       
  3218  * Delete a site transient
       
  3219  *
       
  3220  * @since 2.890
       
  3221  * @package WordPress
       
  3222  * @subpackage Transient
       
  3223  *
       
  3224  * @param string $transient Transient name. Expected to not be SQL-escaped
       
  3225  * @return bool true if successful, false otherwise
       
  3226  */
       
  3227 function delete_site_transient($transient) {
       
  3228 	global $_wp_using_ext_object_cache, $wpdb;
       
  3229 
       
  3230 	if ( $_wp_using_ext_object_cache ) {
       
  3231 		return wp_cache_delete($transient, 'site-transient');
       
  3232 	} else {
       
  3233 		$transient = '_site_transient_' . esc_sql($transient);
       
  3234 		return delete_site_option($transient);
       
  3235 	}
       
  3236 }
       
  3237 
       
  3238 /**
       
  3239  * Get the value of a site transient
       
  3240  *
       
  3241  * If the transient does not exist or does not have a value, then the return value
       
  3242  * will be false.
       
  3243  * 
       
  3244  * @since 2.9.0
       
  3245  * @package WordPress
       
  3246  * @subpackage Transient
       
  3247  *
       
  3248  * @param string $transient Transient name. Expected to not be SQL-escaped
       
  3249  * @return mixed Value of transient
       
  3250  */
       
  3251 function get_site_transient($transient) {
       
  3252 	global $_wp_using_ext_object_cache, $wpdb;
       
  3253 
       
  3254 	$pre = apply_filters( 'pre_site_transient_' . $transient, false );
       
  3255 	if ( false !== $pre )
       
  3256 		return $pre;
       
  3257 
       
  3258 	if ( $_wp_using_ext_object_cache ) {
       
  3259 		$value = wp_cache_get($transient, 'site-transient');
       
  3260 	} else {
       
  3261 		$transient_option = '_site_transient_' . esc_sql($transient);
       
  3262 		$transient_timeout = '_site_transient_timeout_' . esc_sql($transient);
       
  3263 		if ( get_site_option($transient_timeout) < time() ) {
       
  3264 			delete_site_option($transient_option);
       
  3265 			delete_site_option($transient_timeout);
       
  3266 			return false;
       
  3267 		}
       
  3268 
       
  3269 		$value = get_site_option($transient_option);
       
  3270 	}
       
  3271 
       
  3272 	return apply_filters('site_transient_' . $transient, $value);
       
  3273 }
       
  3274 
       
  3275 /**
       
  3276  * Set/update the value of a site transient
       
  3277  *
       
  3278  * You do not need to serialize values, if the value needs to be serialize, then
       
  3279  * it will be serialized before it is set.
       
  3280  *
       
  3281  * @since 2.9.0
       
  3282  * @package WordPress
       
  3283  * @subpackage Transient
       
  3284  *
       
  3285  * @param string $transient Transient name. Expected to not be SQL-escaped
       
  3286  * @param mixed $value Transient value.
       
  3287  * @param int $expiration Time until expiration in seconds, default 0
       
  3288  * @return bool False if value was not set and true if value was set.
       
  3289  */
       
  3290 function set_site_transient($transient, $value, $expiration = 0) {
       
  3291 	global $_wp_using_ext_object_cache, $wpdb;
       
  3292 
       
  3293 	if ( $_wp_using_ext_object_cache ) {
       
  3294 		return wp_cache_set($transient, $value, 'site-transient', $expiration);
       
  3295 	} else {
       
  3296 		$transient_timeout = '_site_transient_timeout_' . $transient;
       
  3297 		$transient = '_site_transient_' . $transient;
       
  3298 		$safe_transient = esc_sql($transient);
       
  3299 		if ( false === get_site_option( $safe_transient ) ) {
       
  3300 			if ( 0 != $expiration )
       
  3301 				add_site_option($transient_timeout, time() + $expiration);
       
  3302 			return add_site_option($transient, $value);
       
  3303 		} else {
       
  3304 			if ( 0 != $expiration )
       
  3305 				update_site_option($transient_timeout, time() + $expiration);
       
  3306 			return update_site_option($transient, $value);
       
  3307 		}
       
  3308 	}
       
  3309 }
       
  3310 
       
  3311 /**
       
  3312  * gmt_offset modification for smart timezone handling
       
  3313  *
       
  3314  * Overrides the gmt_offset option if we have a timezone_string available
       
  3315  */
       
  3316 function wp_timezone_override_offset() {
       
  3317 	if ( !wp_timezone_supported() ) {
       
  3318 		return false;
       
  3319 	}
       
  3320 	if ( !$timezone_string = get_option( 'timezone_string' ) ) {
       
  3321 		return false;
       
  3322 	}
       
  3323 
       
  3324 	@date_default_timezone_set( $timezone_string );
       
  3325 	$timezone_object = timezone_open( $timezone_string );
       
  3326 	$datetime_object = date_create();
       
  3327 	if ( false === $timezone_object || false === $datetime_object ) {
       
  3328 		return false;
       
  3329 	}
       
  3330 	return round( timezone_offset_get( $timezone_object, $datetime_object ) / 3600, 2 );
       
  3331 }
       
  3332 
       
  3333 /**
       
  3334  * Check for PHP timezone support
       
  3335  */
       
  3336 function wp_timezone_supported() {
       
  3337 	$support = false;
       
  3338 	if (
       
  3339 		function_exists( 'date_default_timezone_set' ) &&
       
  3340 		function_exists( 'timezone_identifiers_list' ) &&
       
  3341 		function_exists( 'timezone_open' ) &&
       
  3342 		function_exists( 'timezone_offset_get' )
       
  3343 	) {
       
  3344 		$support = true;
       
  3345 	}
       
  3346 	return apply_filters( 'timezone_support', $support );
       
  3347 }
       
  3348 
       
  3349 function _wp_timezone_choice_usort_callback( $a, $b ) {
       
  3350 	// Don't use translated versions of Etc
       
  3351 	if ( 'Etc' === $a['continent'] && 'Etc' === $b['continent'] ) {
       
  3352 		// Make the order of these more like the old dropdown
       
  3353 		if ( 'GMT+' === substr( $a['city'], 0, 4 ) && 'GMT+' === substr( $b['city'], 0, 4 ) ) {
       
  3354 			return -1 * ( strnatcasecmp( $a['city'], $b['city'] ) );
       
  3355 		}
       
  3356 		if ( 'UTC' === $a['city'] ) {
       
  3357 			if ( 'GMT+' === substr( $b['city'], 0, 4 ) ) {
       
  3358 				return 1;
       
  3359 			}
       
  3360 			return -1;
       
  3361 		}
       
  3362 		if ( 'UTC' === $b['city'] ) {
       
  3363 			if ( 'GMT+' === substr( $a['city'], 0, 4 ) ) {
       
  3364 				return -1;
       
  3365 			}
       
  3366 			return 1;
       
  3367 		}
       
  3368 		return strnatcasecmp( $a['city'], $b['city'] );
       
  3369 	}
       
  3370 	if ( $a['t_continent'] == $b['t_continent'] ) {
       
  3371 		if ( $a['t_city'] == $b['t_city'] ) {
       
  3372 			return strnatcasecmp( $a['t_subcity'], $b['t_subcity'] );
       
  3373 		}
       
  3374 		return strnatcasecmp( $a['t_city'], $b['t_city'] );
       
  3375 	} else {
       
  3376 		// Force Etc to the bottom of the list
       
  3377 		if ( 'Etc' === $a['continent'] ) {
       
  3378 			return 1;
       
  3379 		}
       
  3380 		if ( 'Etc' === $b['continent'] ) {
       
  3381 			return -1;
       
  3382 		}
       
  3383 		return strnatcasecmp( $a['t_continent'], $b['t_continent'] );
       
  3384 	}
       
  3385 }
       
  3386 
       
  3387 /**
       
  3388  * Gives a nicely formatted list of timezone strings // temporary! Not in final
       
  3389  *
       
  3390  * @param $selected_zone string Selected Zone
       
  3391  *
       
  3392  */
       
  3393 function wp_timezone_choice( $selected_zone ) {
       
  3394 	static $mo_loaded = false;
       
  3395 
       
  3396 	$continents = array( 'Africa', 'America', 'Antarctica', 'Arctic', 'Asia', 'Atlantic', 'Australia', 'Europe', 'Indian', 'Pacific');
       
  3397 
       
  3398 	// Load translations for continents and cities
       
  3399 	if ( !$mo_loaded ) {
       
  3400 		$locale = get_locale();
       
  3401 		$mofile = WP_LANG_DIR . '/continents-cities-' . $locale . '.mo';
       
  3402 		load_textdomain( 'continents-cities', $mofile );
       
  3403 		$mo_loaded = true;
       
  3404 	}
       
  3405 
       
  3406 	$zonen = array();
       
  3407 	foreach ( timezone_identifiers_list() as $zone ) {
       
  3408 		$zone = explode( '/', $zone );
       
  3409 		if ( !in_array( $zone[0], $continents ) ) {
       
  3410 			continue;
       
  3411 		}
       
  3412 
       
  3413 		// This determines what gets set and translated - we don't translate Etc/* strings here, they are done later
       
  3414 		$exists = array(
       
  3415 			0 => ( isset( $zone[0] ) && $zone[0] ) ? true : false,
       
  3416 			1 => ( isset( $zone[1] ) && $zone[1] ) ? true : false,
       
  3417 			2 => ( isset( $zone[2] ) && $zone[2] ) ? true : false
       
  3418 		);
       
  3419 		$exists[3] = ( $exists[0] && 'Etc' !== $zone[0] ) ? true : false;
       
  3420 		$exists[4] = ( $exists[1] && $exists[3] ) ? true : false;
       
  3421 		$exists[5] = ( $exists[2] && $exists[3] ) ? true : false;
       
  3422 
       
  3423 		$zonen[] = array(
       
  3424 			'continent'   => ( $exists[0] ? $zone[0] : '' ),
       
  3425 			'city'        => ( $exists[1] ? $zone[1] : '' ),
       
  3426 			'subcity'     => ( $exists[2] ? $zone[2] : '' ),
       
  3427 			't_continent' => ( $exists[3] ? translate( str_replace( '_', ' ', $zone[0] ), 'continents-cities' ) : '' ),
       
  3428 			't_city'      => ( $exists[4] ? translate( str_replace( '_', ' ', $zone[1] ), 'continents-cities' ) : '' ),
       
  3429 			't_subcity'   => ( $exists[5] ? translate( str_replace( '_', ' ', $zone[2] ), 'continents-cities' ) : '' )
       
  3430 		);
       
  3431 	}
       
  3432 	usort( $zonen, '_wp_timezone_choice_usort_callback' );
       
  3433 
       
  3434 	$structure = array();
       
  3435 
       
  3436 	if ( empty( $selected_zone ) ) {
       
  3437 		$structure[] = '<option selected="selected" value="">' . __( 'Select a city' ) . '</option>';
       
  3438 	}
       
  3439 
       
  3440 	foreach ( $zonen as $key => $zone ) {
       
  3441 		// Build value in an array to join later
       
  3442 		$value = array( $zone['continent'] );
       
  3443 
       
  3444 		if ( empty( $zone['city'] ) ) {
       
  3445 			// It's at the continent level (generally won't happen)
       
  3446 			$display = $zone['t_continent'];
       
  3447 		} else {
       
  3448 			// It's inside a continent group
       
  3449 
       
  3450 			// Continent optgroup
       
  3451 			if ( !isset( $zonen[$key - 1] ) || $zonen[$key - 1]['continent'] !== $zone['continent'] ) {
       
  3452 				$label = $zone['t_continent'];
       
  3453 				$structure[] = '<optgroup label="'. esc_attr( $label ) .'">';
       
  3454 			}
       
  3455 
       
  3456 			// Add the city to the value
       
  3457 			$value[] = $zone['city'];
       
  3458 
       
  3459 			$display = $zone['t_city'];
       
  3460 			if ( !empty( $zone['subcity'] ) ) {
       
  3461 				// Add the subcity to the value
       
  3462 				$value[] = $zone['subcity'];
       
  3463 				$display .= ' - ' . $zone['t_subcity'];
       
  3464 			}
       
  3465 		}
       
  3466 
       
  3467 		// Build the value
       
  3468 		$value = join( '/', $value );
       
  3469 		$selected = '';
       
  3470 		if ( $value === $selected_zone ) {
       
  3471 			$selected = 'selected="selected" ';
       
  3472 		}
       
  3473 		$structure[] = '<option ' . $selected . 'value="' . esc_attr( $value ) . '">' . esc_html( $display ) . "</option>";
       
  3474 
       
  3475 		// Close continent optgroup
       
  3476 		if ( !empty( $zone['city'] ) && ( !isset($zonen[$key + 1]) || (isset( $zonen[$key + 1] ) && $zonen[$key + 1]['continent'] !== $zone['continent']) ) ) {
       
  3477 			$structure[] = '</optgroup>';
       
  3478 		}
       
  3479 	}
       
  3480 
       
  3481 	// Do UTC
       
  3482 	$structure[] = '<optgroup label="'. esc_attr__( 'UTC' ) .'">';
       
  3483 	$selected = '';
       
  3484 	if ( 'UTC' === $selected_zone )
       
  3485 		$selected = 'selected="selected" ';
       
  3486 	$structure[] = '<option ' . $selected . 'value="' . esc_attr( 'UTC' ) . '">' . __('UTC') . '</option>';
       
  3487 	$structure[] = '</optgroup>';
       
  3488 
       
  3489 	// Do manual UTC offsets
       
  3490 	$structure[] = '<optgroup label="'. esc_attr__( 'Manual Offsets' ) .'">';
       
  3491 	$offset_range = array (-12, -11.5, -11, -10.5, -10, -9.5, -9, -8.5, -8, -7.5, -7, -6.5, -6, -5.5, -5, -4.5, -4, -3.5, -3, -2.5, -2, -1.5, -1, -0.5,
       
  3492 		0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 5.75, 6, 6.5, 7, 7.5, 8, 8.5, 8.75, 9, 9.5, 10, 10.5, 11, 11.5, 12, 12.75, 13, 13.75, 14);
       
  3493 	foreach ( $offset_range as $offset ) {
       
  3494 		if ( 0 <= $offset )
       
  3495 			$offset_name = '+' . $offset;
       
  3496 		else
       
  3497 			$offset_name = (string) $offset;
       
  3498 
       
  3499 		$offset_value = $offset_name;
       
  3500 		$offset_name = str_replace(array('.25','.5','.75'), array(':15',':30',':45'), $offset_name);
       
  3501 		$offset_name = 'UTC' . $offset_name;
       
  3502 		$offset_value = 'UTC' . $offset_value;
       
  3503 		$selected = '';
       
  3504 		if ( $offset_value === $selected_zone )
       
  3505 			$selected = 'selected="selected" ';
       
  3506 		$structure[] = '<option ' . $selected . 'value="' . esc_attr( $offset_value ) . '">' . esc_html( $offset_name ) . "</option>";
       
  3507 		
       
  3508 	}
       
  3509 	$structure[] = '</optgroup>';
       
  3510 
       
  3511 	return join( "\n", $structure );
       
  3512 }
       
  3513 
       
  3514 /**
       
  3515  * Strip close comment and close php tags from file headers used by WP
       
  3516  * See http://core.trac.wordpress.org/ticket/8497
       
  3517  *
       
  3518  * @since 2.8
       
  3519 **/
       
  3520 function _cleanup_header_comment($str) {
       
  3521 	return trim(preg_replace("/\s*(?:\*\/|\?>).*/", '', $str));
       
  3522 }
       
  3523 
       
  3524 /**
       
  3525  * Permanently deletes posts, pages, attachments, and comments which have been in the trash for EMPTY_TRASH_DAYS.
       
  3526  *
       
  3527  * @since 2.9.0
       
  3528  *
       
  3529  * @return void
       
  3530  */
       
  3531 function wp_scheduled_delete() {
       
  3532 	global $wpdb;
       
  3533 
       
  3534 	$delete_timestamp = time() - (60*60*24*EMPTY_TRASH_DAYS);
       
  3535 
       
  3536 	$posts_to_delete = $wpdb->get_results($wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_wp_trash_meta_time' AND meta_value < '%d'", $delete_timestamp), ARRAY_A);
       
  3537 
       
  3538 	foreach ( (array) $posts_to_delete as $post ) {
       
  3539 		$post_id = (int) $post['post_id'];
       
  3540 		if ( !$post_id )
       
  3541 			continue;
       
  3542 
       
  3543 		$del_post = get_post($post_id);
       
  3544 
       
  3545 		if ( !$del_post || 'trash' != $del_post->post_status ) {
       
  3546 			delete_post_meta($post_id, '_wp_trash_meta_status');
       
  3547 			delete_post_meta($post_id, '_wp_trash_meta_time');
       
  3548 		} else {
       
  3549 			wp_delete_post($post_id);
       
  3550 		}
       
  3551 	}
       
  3552 
       
  3553 	$comments_to_delete = $wpdb->get_results($wpdb->prepare("SELECT comment_id FROM $wpdb->commentmeta WHERE meta_key = '_wp_trash_meta_time' AND meta_value < '%d'", $delete_timestamp), ARRAY_A);
       
  3554 
       
  3555 	foreach ( (array) $comments_to_delete as $comment ) {
       
  3556 		$comment_id = (int) $comment['comment_id'];
       
  3557 		if ( !$comment_id )
       
  3558 			continue;
       
  3559 
       
  3560 		$del_comment = get_comment($comment_id);
       
  3561 
       
  3562 		if ( !$del_comment || 'trash' != $del_comment->comment_approved ) {
       
  3563 			delete_comment_meta($comment_id, '_wp_trash_meta_time');
       
  3564 			delete_comment_meta($comment_id, '_wp_trash_meta_status');
       
  3565 		} else {
       
  3566 			wp_delete_comment($comment_id);
       
  3567 		}
       
  3568 	}
       
  3569 }
       
  3570 
       
  3571 /**
       
  3572  * Parse the file contents to retrieve its metadata.
       
  3573  *
       
  3574  * Searches for metadata for a file, such as a plugin or theme.  Each piece of 
       
  3575  * metadata must be on its own line. For a field spanning multple lines, it
       
  3576  * must not have any newlines or only parts of it will be displayed.
       
  3577  *
       
  3578  * Some users have issues with opening large files and manipulating the contents
       
  3579  * for want is usually the first 1kiB or 2kiB. This function stops pulling in
       
  3580  * the file contents when it has all of the required data.
       
  3581  *
       
  3582  * The first 8kiB of the file will be pulled in and if the file data is not
       
  3583  * within that first 8kiB, then the author should correct their plugin file
       
  3584  * and move the data headers to the top.
       
  3585  *
       
  3586  * The file is assumed to have permissions to allow for scripts to read
       
  3587  * the file. This is not checked however and the file is only opened for
       
  3588  * reading.
       
  3589  *
       
  3590  * @since 2.9.0
       
  3591  *
       
  3592  * @param string $file Path to the file
       
  3593  * @param bool $markup If the returned data should have HTML markup applied
       
  3594  * @param string $context If specified adds filter hook "extra_<$context>_headers" 
       
  3595  */
       
  3596 function get_file_data( $file, $default_headers, $context = '' ) {
       
  3597 	// We don't need to write to the file, so just open for reading.
       
  3598 	$fp = fopen( $file, 'r' );
       
  3599 
       
  3600 	// Pull only the first 8kiB of the file in.
       
  3601 	$file_data = fread( $fp, 8192 );
       
  3602 
       
  3603 	// PHP will close file handle, but we are good citizens.
       
  3604 	fclose( $fp );
       
  3605 
       
  3606 	if( $context != '' ) {
       
  3607 		$extra_headers = apply_filters( "extra_$context".'_headers', array() );
       
  3608 
       
  3609 		$extra_headers = array_flip( $extra_headers );
       
  3610 		foreach( $extra_headers as $key=>$value ) {
       
  3611 			$extra_headers[$key] = $key;
       
  3612 		}
       
  3613 		$all_headers = array_merge($extra_headers, $default_headers);
       
  3614 	} else {
       
  3615 		$all_headers = $default_headers;
       
  3616 	}
       
  3617 
       
  3618 	
       
  3619 	foreach ( $all_headers as $field => $regex ) {
       
  3620 		preg_match( '/' . preg_quote( $regex, '/' ) . ':(.*)$/mi', $file_data, ${$field});
       
  3621 		if ( !empty( ${$field} ) )
       
  3622 			${$field} = _cleanup_header_comment( ${$field}[1] );
       
  3623 		else
       
  3624 			${$field} = '';
       
  3625 	}
       
  3626 
       
  3627 	$file_data = compact( array_keys( $all_headers ) );
       
  3628 	
       
  3629 	return $file_data;
       
  3630 }
       
  3631 /*
       
  3632  * Used internally to tidy up the search terms
       
  3633  * 
       
  3634  * @private
       
  3635  * @since 2.9.0
       
  3636  */
       
  3637 function _search_terms_tidy($t) {
       
  3638 	return trim($t, "\"\'\n\r ");
       
  3639 }
       
  3640 ?>