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