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