[ Index ] |
PHP Cross Reference of WordPress |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Option API 4 * 5 * @package WordPress 6 * @subpackage Option 7 */ 8 9 /** 10 * Retrieves an option value based on an option name. 11 * 12 * If the option does not exist, and a default value is not provided, 13 * boolean false is returned. This could be used to check whether you need 14 * to initialize an option during installation of a plugin, however that 15 * can be done better by using add_option() which will not overwrite 16 * existing options. 17 * 18 * Not initializing an option and using boolean `false` as a return value 19 * is a bad practice as it triggers an additional database query. 20 * 21 * The type of the returned value can be different from the type that was passed 22 * when saving or updating the option. If the option value was serialized, 23 * then it will be unserialized when it is returned. In this case the type will 24 * be the same. For example, storing a non-scalar value like an array will 25 * return the same array. 26 * 27 * In most cases non-string scalar and null values will be converted and returned 28 * as string equivalents. 29 * 30 * Exceptions: 31 * 32 * 1. When the option has not been saved in the database, the `$default` value 33 * is returned if provided. If not, boolean `false` is returned. 34 * 2. When one of the Options API filters is used: {@see 'pre_option_$option'}, 35 * {@see 'default_option_$option'}, or {@see 'option_$option'}, the returned 36 * value may not match the expected type. 37 * 3. When the option has just been saved in the database, and get_option() 38 * is used right after, non-string scalar and null values are not converted to 39 * string equivalents and the original type is returned. 40 * 41 * Examples: 42 * 43 * When adding options like this: `add_option( 'my_option_name', 'value' )` 44 * and then retrieving them with `get_option( 'my_option_name' )`, the returned 45 * values will be: 46 * 47 * - `false` returns `string(0) ""` 48 * - `true` returns `string(1) "1"` 49 * - `0` returns `string(1) "0"` 50 * - `1` returns `string(1) "1"` 51 * - `'0'` returns `string(1) "0"` 52 * - `'1'` returns `string(1) "1"` 53 * - `null` returns `string(0) ""` 54 * 55 * When adding options with non-scalar values like 56 * `add_option( 'my_array', array( false, 'str', null ) )`, the returned value 57 * will be identical to the original as it is serialized before saving 58 * it in the database: 59 * 60 * array(3) { 61 * [0] => bool(false) 62 * [1] => string(3) "str" 63 * [2] => NULL 64 * } 65 * 66 * @since 1.5.0 67 * 68 * @global wpdb $wpdb WordPress database abstraction object. 69 * 70 * @param string $option Name of the option to retrieve. Expected to not be SQL-escaped. 71 * @param mixed $default Optional. Default value to return if the option does not exist. 72 * @return mixed Value of the option. A value of any type may be returned, including 73 * scalar (string, boolean, float, integer), null, array, object. 74 * Scalar and null values will be returned as strings as long as they originate 75 * from a database stored option value. If there is no option in the database, 76 * boolean `false` is returned. 77 */ 78 function get_option( $option, $default = false ) { 79 global $wpdb; 80 81 if ( is_scalar( $option ) ) { 82 $option = trim( $option ); 83 } 84 85 if ( empty( $option ) ) { 86 return false; 87 } 88 89 /* 90 * Until a proper _deprecated_option() function can be introduced, 91 * redirect requests to deprecated keys to the new, correct ones. 92 */ 93 $deprecated_keys = array( 94 'blacklist_keys' => 'disallowed_keys', 95 'comment_whitelist' => 'comment_previously_approved', 96 ); 97 98 if ( ! wp_installing() && isset( $deprecated_keys[ $option ] ) ) { 99 _deprecated_argument( 100 __FUNCTION__, 101 '5.5.0', 102 sprintf( 103 /* translators: 1: Deprecated option key, 2: New option key. */ 104 __( 'The "%1$s" option key has been renamed to "%2$s".' ), 105 $option, 106 $deprecated_keys[ $option ] 107 ) 108 ); 109 return get_option( $deprecated_keys[ $option ], $default ); 110 } 111 112 /** 113 * Filters the value of an existing option before it is retrieved. 114 * 115 * The dynamic portion of the hook name, `$option`, refers to the option name. 116 * 117 * Returning a truthy value from the filter will effectively short-circuit retrieval 118 * and return the passed value instead. 119 * 120 * @since 1.5.0 121 * @since 4.4.0 The `$option` parameter was added. 122 * @since 4.9.0 The `$default` parameter was added. 123 * 124 * @param mixed $pre_option The value to return instead of the option value. This differs 125 * from `$default`, which is used as the fallback value in the event 126 * the option doesn't exist elsewhere in get_option(). 127 * Default false (to skip past the short-circuit). 128 * @param string $option Option name. 129 * @param mixed $default The fallback value to return if the option does not exist. 130 * Default false. 131 */ 132 $pre = apply_filters( "pre_option_{$option}", false, $option, $default ); 133 134 if ( false !== $pre ) { 135 return $pre; 136 } 137 138 if ( defined( 'WP_SETUP_CONFIG' ) ) { 139 return false; 140 } 141 142 // Distinguish between `false` as a default, and not passing one. 143 $passed_default = func_num_args() > 1; 144 145 if ( ! wp_installing() ) { 146 // Prevent non-existent options from triggering multiple queries. 147 $notoptions = wp_cache_get( 'notoptions', 'options' ); 148 149 if ( isset( $notoptions[ $option ] ) ) { 150 /** 151 * Filters the default value for an option. 152 * 153 * The dynamic portion of the hook name, `$option`, refers to the option name. 154 * 155 * @since 3.4.0 156 * @since 4.4.0 The `$option` parameter was added. 157 * @since 4.7.0 The `$passed_default` parameter was added to distinguish between a `false` value and the default parameter value. 158 * 159 * @param mixed $default The default value to return if the option does not exist 160 * in the database. 161 * @param string $option Option name. 162 * @param bool $passed_default Was `get_option()` passed a default value? 163 */ 164 return apply_filters( "default_option_{$option}", $default, $option, $passed_default ); 165 } 166 167 $alloptions = wp_load_alloptions(); 168 169 if ( isset( $alloptions[ $option ] ) ) { 170 $value = $alloptions[ $option ]; 171 } else { 172 $value = wp_cache_get( $option, 'options' ); 173 174 if ( false === $value ) { 175 $row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", $option ) ); 176 177 // Has to be get_row() instead of get_var() because of funkiness with 0, false, null values. 178 if ( is_object( $row ) ) { 179 $value = $row->option_value; 180 wp_cache_add( $option, $value, 'options' ); 181 } else { // Option does not exist, so we must cache its non-existence. 182 if ( ! is_array( $notoptions ) ) { 183 $notoptions = array(); 184 } 185 186 $notoptions[ $option ] = true; 187 wp_cache_set( 'notoptions', $notoptions, 'options' ); 188 189 /** This filter is documented in wp-includes/option.php */ 190 return apply_filters( "default_option_{$option}", $default, $option, $passed_default ); 191 } 192 } 193 } 194 } else { 195 $suppress = $wpdb->suppress_errors(); 196 $row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", $option ) ); 197 $wpdb->suppress_errors( $suppress ); 198 199 if ( is_object( $row ) ) { 200 $value = $row->option_value; 201 } else { 202 /** This filter is documented in wp-includes/option.php */ 203 return apply_filters( "default_option_{$option}", $default, $option, $passed_default ); 204 } 205 } 206 207 // If home is not set, use siteurl. 208 if ( 'home' === $option && '' === $value ) { 209 return get_option( 'siteurl' ); 210 } 211 212 if ( in_array( $option, array( 'siteurl', 'home', 'category_base', 'tag_base' ), true ) ) { 213 $value = untrailingslashit( $value ); 214 } 215 216 /** 217 * Filters the value of an existing option. 218 * 219 * The dynamic portion of the hook name, `$option`, refers to the option name. 220 * 221 * @since 1.5.0 As 'option_' . $setting 222 * @since 3.0.0 223 * @since 4.4.0 The `$option` parameter was added. 224 * 225 * @param mixed $value Value of the option. If stored serialized, it will be 226 * unserialized prior to being returned. 227 * @param string $option Option name. 228 */ 229 return apply_filters( "option_{$option}", maybe_unserialize( $value ), $option ); 230 } 231 232 /** 233 * Protects WordPress special option from being modified. 234 * 235 * Will die if $option is in protected list. Protected options are 'alloptions' 236 * and 'notoptions' options. 237 * 238 * @since 2.2.0 239 * 240 * @param string $option Option name. 241 */ 242 function wp_protect_special_option( $option ) { 243 if ( 'alloptions' === $option || 'notoptions' === $option ) { 244 wp_die( 245 sprintf( 246 /* translators: %s: Option name. */ 247 __( '%s is a protected WP option and may not be modified' ), 248 esc_html( $option ) 249 ) 250 ); 251 } 252 } 253 254 /** 255 * Prints option value after sanitizing for forms. 256 * 257 * @since 1.5.0 258 * 259 * @param string $option Option name. 260 */ 261 function form_option( $option ) { 262 echo esc_attr( get_option( $option ) ); 263 } 264 265 /** 266 * Loads and caches all autoloaded options, if available or all options. 267 * 268 * @since 2.2.0 269 * @since 5.3.1 The `$force_cache` parameter was added. 270 * 271 * @global wpdb $wpdb WordPress database abstraction object. 272 * 273 * @param bool $force_cache Optional. Whether to force an update of the local cache 274 * from the persistent cache. Default false. 275 * @return array List of all options. 276 */ 277 function wp_load_alloptions( $force_cache = false ) { 278 global $wpdb; 279 280 if ( ! wp_installing() || ! is_multisite() ) { 281 $alloptions = wp_cache_get( 'alloptions', 'options', $force_cache ); 282 } else { 283 $alloptions = false; 284 } 285 286 if ( ! $alloptions ) { 287 $suppress = $wpdb->suppress_errors(); 288 $alloptions_db = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options WHERE autoload = 'yes'" ); 289 if ( ! $alloptions_db ) { 290 $alloptions_db = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options" ); 291 } 292 $wpdb->suppress_errors( $suppress ); 293 294 $alloptions = array(); 295 foreach ( (array) $alloptions_db as $o ) { 296 $alloptions[ $o->option_name ] = $o->option_value; 297 } 298 299 if ( ! wp_installing() || ! is_multisite() ) { 300 /** 301 * Filters all options before caching them. 302 * 303 * @since 4.9.0 304 * 305 * @param array $alloptions Array with all options. 306 */ 307 $alloptions = apply_filters( 'pre_cache_alloptions', $alloptions ); 308 309 wp_cache_add( 'alloptions', $alloptions, 'options' ); 310 } 311 } 312 313 /** 314 * Filters all options after retrieving them. 315 * 316 * @since 4.9.0 317 * 318 * @param array $alloptions Array with all options. 319 */ 320 return apply_filters( 'alloptions', $alloptions ); 321 } 322 323 /** 324 * Loads and caches certain often requested site options if is_multisite() and a persistent cache is not being used. 325 * 326 * @since 3.0.0 327 * 328 * @global wpdb $wpdb WordPress database abstraction object. 329 * 330 * @param int $network_id Optional site ID for which to query the options. Defaults to the current site. 331 */ 332 function wp_load_core_site_options( $network_id = null ) { 333 global $wpdb; 334 335 if ( ! is_multisite() || wp_using_ext_object_cache() || wp_installing() ) { 336 return; 337 } 338 339 if ( empty( $network_id ) ) { 340 $network_id = get_current_network_id(); 341 } 342 343 $core_options = array( 'site_name', 'siteurl', 'active_sitewide_plugins', '_site_transient_timeout_theme_roots', '_site_transient_theme_roots', 'site_admins', 'can_compress_scripts', 'global_terms_enabled', 'ms_files_rewriting' ); 344 345 $core_options_in = "'" . implode( "', '", $core_options ) . "'"; 346 $options = $wpdb->get_results( $wpdb->prepare( "SELECT meta_key, meta_value FROM $wpdb->sitemeta WHERE meta_key IN ($core_options_in) AND site_id = %d", $network_id ) ); 347 348 $data = array(); 349 foreach ( $options as $option ) { 350 $key = $option->meta_key; 351 $cache_key = "{$network_id}:$key"; 352 $option->meta_value = maybe_unserialize( $option->meta_value ); 353 354 $data[ $cache_key ] = $option->meta_value; 355 } 356 wp_cache_set_multiple( $data, 'site-options' ); 357 } 358 359 /** 360 * Updates the value of an option that was already added. 361 * 362 * You do not need to serialize values. If the value needs to be serialized, 363 * then it will be serialized before it is inserted into the database. 364 * Remember, resources cannot be serialized or added as an option. 365 * 366 * If the option does not exist, it will be created. 367 368 * This function is designed to work with or without a logged-in user. In terms of security, 369 * plugin developers should check the current user's capabilities before updating any options. 370 * 371 * @since 1.0.0 372 * @since 4.2.0 The `$autoload` parameter was added. 373 * 374 * @global wpdb $wpdb WordPress database abstraction object. 375 * 376 * @param string $option Name of the option to update. Expected to not be SQL-escaped. 377 * @param mixed $value Option value. Must be serializable if non-scalar. Expected to not be SQL-escaped. 378 * @param string|bool $autoload Optional. Whether to load the option when WordPress starts up. For existing options, 379 * `$autoload` can only be updated using `update_option()` if `$value` is also changed. 380 * Accepts 'yes'|true to enable or 'no'|false to disable. For non-existent options, 381 * the default value is 'yes'. Default null. 382 * @return bool True if the value was updated, false otherwise. 383 */ 384 function update_option( $option, $value, $autoload = null ) { 385 global $wpdb; 386 387 if ( is_scalar( $option ) ) { 388 $option = trim( $option ); 389 } 390 391 if ( empty( $option ) ) { 392 return false; 393 } 394 395 /* 396 * Until a proper _deprecated_option() function can be introduced, 397 * redirect requests to deprecated keys to the new, correct ones. 398 */ 399 $deprecated_keys = array( 400 'blacklist_keys' => 'disallowed_keys', 401 'comment_whitelist' => 'comment_previously_approved', 402 ); 403 404 if ( ! wp_installing() && isset( $deprecated_keys[ $option ] ) ) { 405 _deprecated_argument( 406 __FUNCTION__, 407 '5.5.0', 408 sprintf( 409 /* translators: 1: Deprecated option key, 2: New option key. */ 410 __( 'The "%1$s" option key has been renamed to "%2$s".' ), 411 $option, 412 $deprecated_keys[ $option ] 413 ) 414 ); 415 return update_option( $deprecated_keys[ $option ], $value, $autoload ); 416 } 417 418 wp_protect_special_option( $option ); 419 420 if ( is_object( $value ) ) { 421 $value = clone $value; 422 } 423 424 $value = sanitize_option( $option, $value ); 425 $old_value = get_option( $option ); 426 427 /** 428 * Filters a specific option before its value is (maybe) serialized and updated. 429 * 430 * The dynamic portion of the hook name, `$option`, refers to the option name. 431 * 432 * @since 2.6.0 433 * @since 4.4.0 The `$option` parameter was added. 434 * 435 * @param mixed $value The new, unserialized option value. 436 * @param mixed $old_value The old option value. 437 * @param string $option Option name. 438 */ 439 $value = apply_filters( "pre_update_option_{$option}", $value, $old_value, $option ); 440 441 /** 442 * Filters an option before its value is (maybe) serialized and updated. 443 * 444 * @since 3.9.0 445 * 446 * @param mixed $value The new, unserialized option value. 447 * @param string $option Name of the option. 448 * @param mixed $old_value The old option value. 449 */ 450 $value = apply_filters( 'pre_update_option', $value, $option, $old_value ); 451 452 /* 453 * If the new and old values are the same, no need to update. 454 * 455 * Unserialized values will be adequate in most cases. If the unserialized 456 * data differs, the (maybe) serialized data is checked to avoid 457 * unnecessary database calls for otherwise identical object instances. 458 * 459 * See https://core.trac.wordpress.org/ticket/38903 460 */ 461 if ( $value === $old_value || maybe_serialize( $value ) === maybe_serialize( $old_value ) ) { 462 return false; 463 } 464 465 /** This filter is documented in wp-includes/option.php */ 466 if ( apply_filters( "default_option_{$option}", false, $option, false ) === $old_value ) { 467 // Default setting for new options is 'yes'. 468 if ( null === $autoload ) { 469 $autoload = 'yes'; 470 } 471 472 return add_option( $option, $value, '', $autoload ); 473 } 474 475 $serialized_value = maybe_serialize( $value ); 476 477 /** 478 * Fires immediately before an option value is updated. 479 * 480 * @since 2.9.0 481 * 482 * @param string $option Name of the option to update. 483 * @param mixed $old_value The old option value. 484 * @param mixed $value The new option value. 485 */ 486 do_action( 'update_option', $option, $old_value, $value ); 487 488 $update_args = array( 489 'option_value' => $serialized_value, 490 ); 491 492 if ( null !== $autoload ) { 493 $update_args['autoload'] = ( 'no' === $autoload || false === $autoload ) ? 'no' : 'yes'; 494 } 495 496 $result = $wpdb->update( $wpdb->options, $update_args, array( 'option_name' => $option ) ); 497 if ( ! $result ) { 498 return false; 499 } 500 501 $notoptions = wp_cache_get( 'notoptions', 'options' ); 502 503 if ( is_array( $notoptions ) && isset( $notoptions[ $option ] ) ) { 504 unset( $notoptions[ $option ] ); 505 wp_cache_set( 'notoptions', $notoptions, 'options' ); 506 } 507 508 if ( ! wp_installing() ) { 509 $alloptions = wp_load_alloptions( true ); 510 if ( isset( $alloptions[ $option ] ) ) { 511 $alloptions[ $option ] = $serialized_value; 512 wp_cache_set( 'alloptions', $alloptions, 'options' ); 513 } else { 514 wp_cache_set( $option, $serialized_value, 'options' ); 515 } 516 } 517 518 /** 519 * Fires after the value of a specific option has been successfully updated. 520 * 521 * The dynamic portion of the hook name, `$option`, refers to the option name. 522 * 523 * @since 2.0.1 524 * @since 4.4.0 The `$option` parameter was added. 525 * 526 * @param mixed $old_value The old option value. 527 * @param mixed $value The new option value. 528 * @param string $option Option name. 529 */ 530 do_action( "update_option_{$option}", $old_value, $value, $option ); 531 532 /** 533 * Fires after the value of an option has been successfully updated. 534 * 535 * @since 2.9.0 536 * 537 * @param string $option Name of the updated option. 538 * @param mixed $old_value The old option value. 539 * @param mixed $value The new option value. 540 */ 541 do_action( 'updated_option', $option, $old_value, $value ); 542 543 return true; 544 } 545 546 /** 547 * Adds a new option. 548 * 549 * You do not need to serialize values. If the value needs to be serialized, 550 * then it will be serialized before it is inserted into the database. 551 * Remember, resources cannot be serialized or added as an option. 552 * 553 * You can create options without values and then update the values later. 554 * Existing options will not be updated and checks are performed to ensure that you 555 * aren't adding a protected WordPress option. Care should be taken to not name 556 * options the same as the ones which are protected. 557 * 558 * @since 1.0.0 559 * 560 * @global wpdb $wpdb WordPress database abstraction object. 561 * 562 * @param string $option Name of the option to add. Expected to not be SQL-escaped. 563 * @param mixed $value Optional. Option value. Must be serializable if non-scalar. 564 * Expected to not be SQL-escaped. 565 * @param string $deprecated Optional. Description. Not used anymore. 566 * @param string|bool $autoload Optional. Whether to load the option when WordPress starts up. 567 * Default is enabled. Accepts 'no' to disable for legacy reasons. 568 * @return bool True if the option was added, false otherwise. 569 */ 570 function add_option( $option, $value = '', $deprecated = '', $autoload = 'yes' ) { 571 global $wpdb; 572 573 if ( ! empty( $deprecated ) ) { 574 _deprecated_argument( __FUNCTION__, '2.3.0' ); 575 } 576 577 if ( is_scalar( $option ) ) { 578 $option = trim( $option ); 579 } 580 581 if ( empty( $option ) ) { 582 return false; 583 } 584 585 /* 586 * Until a proper _deprecated_option() function can be introduced, 587 * redirect requests to deprecated keys to the new, correct ones. 588 */ 589 $deprecated_keys = array( 590 'blacklist_keys' => 'disallowed_keys', 591 'comment_whitelist' => 'comment_previously_approved', 592 ); 593 594 if ( ! wp_installing() && isset( $deprecated_keys[ $option ] ) ) { 595 _deprecated_argument( 596 __FUNCTION__, 597 '5.5.0', 598 sprintf( 599 /* translators: 1: Deprecated option key, 2: New option key. */ 600 __( 'The "%1$s" option key has been renamed to "%2$s".' ), 601 $option, 602 $deprecated_keys[ $option ] 603 ) 604 ); 605 return add_option( $deprecated_keys[ $option ], $value, $deprecated, $autoload ); 606 } 607 608 wp_protect_special_option( $option ); 609 610 if ( is_object( $value ) ) { 611 $value = clone $value; 612 } 613 614 $value = sanitize_option( $option, $value ); 615 616 // Make sure the option doesn't already exist. 617 // We can check the 'notoptions' cache before we ask for a DB query. 618 $notoptions = wp_cache_get( 'notoptions', 'options' ); 619 620 if ( ! is_array( $notoptions ) || ! isset( $notoptions[ $option ] ) ) { 621 /** This filter is documented in wp-includes/option.php */ 622 if ( apply_filters( "default_option_{$option}", false, $option, false ) !== get_option( $option ) ) { 623 return false; 624 } 625 } 626 627 $serialized_value = maybe_serialize( $value ); 628 $autoload = ( 'no' === $autoload || false === $autoload ) ? 'no' : 'yes'; 629 630 /** 631 * Fires before an option is added. 632 * 633 * @since 2.9.0 634 * 635 * @param string $option Name of the option to add. 636 * @param mixed $value Value of the option. 637 */ 638 do_action( 'add_option', $option, $value ); 639 640 $result = $wpdb->query( $wpdb->prepare( "INSERT INTO `$wpdb->options` (`option_name`, `option_value`, `autoload`) VALUES (%s, %s, %s) ON DUPLICATE KEY UPDATE `option_name` = VALUES(`option_name`), `option_value` = VALUES(`option_value`), `autoload` = VALUES(`autoload`)", $option, $serialized_value, $autoload ) ); 641 if ( ! $result ) { 642 return false; 643 } 644 645 if ( ! wp_installing() ) { 646 if ( 'yes' === $autoload ) { 647 $alloptions = wp_load_alloptions( true ); 648 $alloptions[ $option ] = $serialized_value; 649 wp_cache_set( 'alloptions', $alloptions, 'options' ); 650 } else { 651 wp_cache_set( $option, $serialized_value, 'options' ); 652 } 653 } 654 655 // This option exists now. 656 $notoptions = wp_cache_get( 'notoptions', 'options' ); // Yes, again... we need it to be fresh. 657 658 if ( is_array( $notoptions ) && isset( $notoptions[ $option ] ) ) { 659 unset( $notoptions[ $option ] ); 660 wp_cache_set( 'notoptions', $notoptions, 'options' ); 661 } 662 663 /** 664 * Fires after a specific option has been added. 665 * 666 * The dynamic portion of the hook name, `$option`, refers to the option name. 667 * 668 * @since 2.5.0 As "add_option_{$name}" 669 * @since 3.0.0 670 * 671 * @param string $option Name of the option to add. 672 * @param mixed $value Value of the option. 673 */ 674 do_action( "add_option_{$option}", $option, $value ); 675 676 /** 677 * Fires after an option has been added. 678 * 679 * @since 2.9.0 680 * 681 * @param string $option Name of the added option. 682 * @param mixed $value Value of the option. 683 */ 684 do_action( 'added_option', $option, $value ); 685 686 return true; 687 } 688 689 /** 690 * Removes option by name. Prevents removal of protected WordPress options. 691 * 692 * @since 1.2.0 693 * 694 * @global wpdb $wpdb WordPress database abstraction object. 695 * 696 * @param string $option Name of the option to delete. Expected to not be SQL-escaped. 697 * @return bool True if the option was deleted, false otherwise. 698 */ 699 function delete_option( $option ) { 700 global $wpdb; 701 702 if ( is_scalar( $option ) ) { 703 $option = trim( $option ); 704 } 705 706 if ( empty( $option ) ) { 707 return false; 708 } 709 710 wp_protect_special_option( $option ); 711 712 // Get the ID, if no ID then return. 713 $row = $wpdb->get_row( $wpdb->prepare( "SELECT autoload FROM $wpdb->options WHERE option_name = %s", $option ) ); 714 if ( is_null( $row ) ) { 715 return false; 716 } 717 718 /** 719 * Fires immediately before an option is deleted. 720 * 721 * @since 2.9.0 722 * 723 * @param string $option Name of the option to delete. 724 */ 725 do_action( 'delete_option', $option ); 726 727 $result = $wpdb->delete( $wpdb->options, array( 'option_name' => $option ) ); 728 729 if ( ! wp_installing() ) { 730 if ( 'yes' === $row->autoload ) { 731 $alloptions = wp_load_alloptions( true ); 732 if ( is_array( $alloptions ) && isset( $alloptions[ $option ] ) ) { 733 unset( $alloptions[ $option ] ); 734 wp_cache_set( 'alloptions', $alloptions, 'options' ); 735 } 736 } else { 737 wp_cache_delete( $option, 'options' ); 738 } 739 } 740 741 if ( $result ) { 742 743 /** 744 * Fires after a specific option has been deleted. 745 * 746 * The dynamic portion of the hook name, `$option`, refers to the option name. 747 * 748 * @since 3.0.0 749 * 750 * @param string $option Name of the deleted option. 751 */ 752 do_action( "delete_option_{$option}", $option ); 753 754 /** 755 * Fires after an option has been deleted. 756 * 757 * @since 2.9.0 758 * 759 * @param string $option Name of the deleted option. 760 */ 761 do_action( 'deleted_option', $option ); 762 763 return true; 764 } 765 766 return false; 767 } 768 769 /** 770 * Deletes a transient. 771 * 772 * @since 2.8.0 773 * 774 * @param string $transient Transient name. Expected to not be SQL-escaped. 775 * @return bool True if the transient was deleted, false otherwise. 776 */ 777 function delete_transient( $transient ) { 778 779 /** 780 * Fires immediately before a specific transient is deleted. 781 * 782 * The dynamic portion of the hook name, `$transient`, refers to the transient name. 783 * 784 * @since 3.0.0 785 * 786 * @param string $transient Transient name. 787 */ 788 do_action( "delete_transient_{$transient}", $transient ); 789 790 if ( wp_using_ext_object_cache() || wp_installing() ) { 791 $result = wp_cache_delete( $transient, 'transient' ); 792 } else { 793 $option_timeout = '_transient_timeout_' . $transient; 794 $option = '_transient_' . $transient; 795 $result = delete_option( $option ); 796 797 if ( $result ) { 798 delete_option( $option_timeout ); 799 } 800 } 801 802 if ( $result ) { 803 804 /** 805 * Fires after a transient is deleted. 806 * 807 * @since 3.0.0 808 * 809 * @param string $transient Deleted transient name. 810 */ 811 do_action( 'deleted_transient', $transient ); 812 } 813 814 return $result; 815 } 816 817 /** 818 * Retrieves the value of a transient. 819 * 820 * If the transient does not exist, does not have a value, or has expired, 821 * then the return value will be false. 822 * 823 * @since 2.8.0 824 * 825 * @param string $transient Transient name. Expected to not be SQL-escaped. 826 * @return mixed Value of transient. 827 */ 828 function get_transient( $transient ) { 829 830 /** 831 * Filters the value of an existing transient before it is retrieved. 832 * 833 * The dynamic portion of the hook name, `$transient`, refers to the transient name. 834 * 835 * Returning a truthy value from the filter will effectively short-circuit retrieval 836 * and return the passed value instead. 837 * 838 * @since 2.8.0 839 * @since 4.4.0 The `$transient` parameter was added 840 * 841 * @param mixed $pre_transient The default value to return if the transient does not exist. 842 * Any value other than false will short-circuit the retrieval 843 * of the transient, and return that value. 844 * @param string $transient Transient name. 845 */ 846 $pre = apply_filters( "pre_transient_{$transient}", false, $transient ); 847 848 if ( false !== $pre ) { 849 return $pre; 850 } 851 852 if ( wp_using_ext_object_cache() || wp_installing() ) { 853 $value = wp_cache_get( $transient, 'transient' ); 854 } else { 855 $transient_option = '_transient_' . $transient; 856 if ( ! wp_installing() ) { 857 // If option is not in alloptions, it is not autoloaded and thus has a timeout. 858 $alloptions = wp_load_alloptions(); 859 if ( ! isset( $alloptions[ $transient_option ] ) ) { 860 $transient_timeout = '_transient_timeout_' . $transient; 861 $timeout = get_option( $transient_timeout ); 862 if ( false !== $timeout && $timeout < time() ) { 863 delete_option( $transient_option ); 864 delete_option( $transient_timeout ); 865 $value = false; 866 } 867 } 868 } 869 870 if ( ! isset( $value ) ) { 871 $value = get_option( $transient_option ); 872 } 873 } 874 875 /** 876 * Filters an existing transient's value. 877 * 878 * The dynamic portion of the hook name, `$transient`, refers to the transient name. 879 * 880 * @since 2.8.0 881 * @since 4.4.0 The `$transient` parameter was added 882 * 883 * @param mixed $value Value of transient. 884 * @param string $transient Transient name. 885 */ 886 return apply_filters( "transient_{$transient}", $value, $transient ); 887 } 888 889 /** 890 * Sets/updates the value of a transient. 891 * 892 * You do not need to serialize values. If the value needs to be serialized, 893 * then it will be serialized before it is set. 894 * 895 * @since 2.8.0 896 * 897 * @param string $transient Transient name. Expected to not be SQL-escaped. 898 * Must be 172 characters or fewer in length. 899 * @param mixed $value Transient value. Must be serializable if non-scalar. 900 * Expected to not be SQL-escaped. 901 * @param int $expiration Optional. Time until expiration in seconds. Default 0 (no expiration). 902 * @return bool True if the value was set, false otherwise. 903 */ 904 function set_transient( $transient, $value, $expiration = 0 ) { 905 906 $expiration = (int) $expiration; 907 908 /** 909 * Filters a specific transient before its value is set. 910 * 911 * The dynamic portion of the hook name, `$transient`, refers to the transient name. 912 * 913 * @since 3.0.0 914 * @since 4.2.0 The `$expiration` parameter was added. 915 * @since 4.4.0 The `$transient` parameter was added. 916 * 917 * @param mixed $value New value of transient. 918 * @param int $expiration Time until expiration in seconds. 919 * @param string $transient Transient name. 920 */ 921 $value = apply_filters( "pre_set_transient_{$transient}", $value, $expiration, $transient ); 922 923 /** 924 * Filters the expiration for a transient before its value is set. 925 * 926 * The dynamic portion of the hook name, `$transient`, refers to the transient name. 927 * 928 * @since 4.4.0 929 * 930 * @param int $expiration Time until expiration in seconds. Use 0 for no expiration. 931 * @param mixed $value New value of transient. 932 * @param string $transient Transient name. 933 */ 934 $expiration = apply_filters( "expiration_of_transient_{$transient}", $expiration, $value, $transient ); 935 936 if ( wp_using_ext_object_cache() || wp_installing() ) { 937 $result = wp_cache_set( $transient, $value, 'transient', $expiration ); 938 } else { 939 $transient_timeout = '_transient_timeout_' . $transient; 940 $transient_option = '_transient_' . $transient; 941 942 if ( false === get_option( $transient_option ) ) { 943 $autoload = 'yes'; 944 if ( $expiration ) { 945 $autoload = 'no'; 946 add_option( $transient_timeout, time() + $expiration, '', 'no' ); 947 } 948 $result = add_option( $transient_option, $value, '', $autoload ); 949 } else { 950 // If expiration is requested, but the transient has no timeout option, 951 // delete, then re-create transient rather than update. 952 $update = true; 953 954 if ( $expiration ) { 955 if ( false === get_option( $transient_timeout ) ) { 956 delete_option( $transient_option ); 957 add_option( $transient_timeout, time() + $expiration, '', 'no' ); 958 $result = add_option( $transient_option, $value, '', 'no' ); 959 $update = false; 960 } else { 961 update_option( $transient_timeout, time() + $expiration ); 962 } 963 } 964 965 if ( $update ) { 966 $result = update_option( $transient_option, $value ); 967 } 968 } 969 } 970 971 if ( $result ) { 972 973 /** 974 * Fires after the value for a specific transient has been set. 975 * 976 * The dynamic portion of the hook name, `$transient`, refers to the transient name. 977 * 978 * @since 3.0.0 979 * @since 3.6.0 The `$value` and `$expiration` parameters were added. 980 * @since 4.4.0 The `$transient` parameter was added. 981 * 982 * @param mixed $value Transient value. 983 * @param int $expiration Time until expiration in seconds. 984 * @param string $transient The name of the transient. 985 */ 986 do_action( "set_transient_{$transient}", $value, $expiration, $transient ); 987 988 /** 989 * Fires after the value for a transient has been set. 990 * 991 * @since 3.0.0 992 * @since 3.6.0 The `$value` and `$expiration` parameters were added. 993 * 994 * @param string $transient The name of the transient. 995 * @param mixed $value Transient value. 996 * @param int $expiration Time until expiration in seconds. 997 */ 998 do_action( 'setted_transient', $transient, $value, $expiration ); 999 } 1000 1001 return $result; 1002 } 1003 1004 /** 1005 * Deletes all expired transients. 1006 * 1007 * The multi-table delete syntax is used to delete the transient record 1008 * from table a, and the corresponding transient_timeout record from table b. 1009 * 1010 * @since 4.9.0 1011 * 1012 * @param bool $force_db Optional. Force cleanup to run against the database even when an external object cache is used. 1013 */ 1014 function delete_expired_transients( $force_db = false ) { 1015 global $wpdb; 1016 1017 if ( ! $force_db && wp_using_ext_object_cache() ) { 1018 return; 1019 } 1020 1021 $wpdb->query( 1022 $wpdb->prepare( 1023 "DELETE a, b FROM {$wpdb->options} a, {$wpdb->options} b 1024 WHERE a.option_name LIKE %s 1025 AND a.option_name NOT LIKE %s 1026 AND b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) ) 1027 AND b.option_value < %d", 1028 $wpdb->esc_like( '_transient_' ) . '%', 1029 $wpdb->esc_like( '_transient_timeout_' ) . '%', 1030 time() 1031 ) 1032 ); 1033 1034 if ( ! is_multisite() ) { 1035 // Single site stores site transients in the options table. 1036 $wpdb->query( 1037 $wpdb->prepare( 1038 "DELETE a, b FROM {$wpdb->options} a, {$wpdb->options} b 1039 WHERE a.option_name LIKE %s 1040 AND a.option_name NOT LIKE %s 1041 AND b.option_name = CONCAT( '_site_transient_timeout_', SUBSTRING( a.option_name, 17 ) ) 1042 AND b.option_value < %d", 1043 $wpdb->esc_like( '_site_transient_' ) . '%', 1044 $wpdb->esc_like( '_site_transient_timeout_' ) . '%', 1045 time() 1046 ) 1047 ); 1048 } elseif ( is_multisite() && is_main_site() && is_main_network() ) { 1049 // Multisite stores site transients in the sitemeta table. 1050 $wpdb->query( 1051 $wpdb->prepare( 1052 "DELETE a, b FROM {$wpdb->sitemeta} a, {$wpdb->sitemeta} b 1053 WHERE a.meta_key LIKE %s 1054 AND a.meta_key NOT LIKE %s 1055 AND b.meta_key = CONCAT( '_site_transient_timeout_', SUBSTRING( a.meta_key, 17 ) ) 1056 AND b.meta_value < %d", 1057 $wpdb->esc_like( '_site_transient_' ) . '%', 1058 $wpdb->esc_like( '_site_transient_timeout_' ) . '%', 1059 time() 1060 ) 1061 ); 1062 } 1063 } 1064 1065 /** 1066 * Saves and restores user interface settings stored in a cookie. 1067 * 1068 * Checks if the current user-settings cookie is updated and stores it. When no 1069 * cookie exists (different browser used), adds the last saved cookie restoring 1070 * the settings. 1071 * 1072 * @since 2.7.0 1073 */ 1074 function wp_user_settings() { 1075 1076 if ( ! is_admin() || wp_doing_ajax() ) { 1077 return; 1078 } 1079 1080 $user_id = get_current_user_id(); 1081 if ( ! $user_id ) { 1082 return; 1083 } 1084 1085 if ( ! is_user_member_of_blog() ) { 1086 return; 1087 } 1088 1089 $settings = (string) get_user_option( 'user-settings', $user_id ); 1090 1091 if ( isset( $_COOKIE[ 'wp-settings-' . $user_id ] ) ) { 1092 $cookie = preg_replace( '/[^A-Za-z0-9=&_]/', '', $_COOKIE[ 'wp-settings-' . $user_id ] ); 1093 1094 // No change or both empty. 1095 if ( $cookie == $settings ) { 1096 return; 1097 } 1098 1099 $last_saved = (int) get_user_option( 'user-settings-time', $user_id ); 1100 $current = isset( $_COOKIE[ 'wp-settings-time-' . $user_id ] ) ? preg_replace( '/[^0-9]/', '', $_COOKIE[ 'wp-settings-time-' . $user_id ] ) : 0; 1101 1102 // The cookie is newer than the saved value. Update the user_option and leave the cookie as-is. 1103 if ( $current > $last_saved ) { 1104 update_user_option( $user_id, 'user-settings', $cookie, false ); 1105 update_user_option( $user_id, 'user-settings-time', time() - 5, false ); 1106 return; 1107 } 1108 } 1109 1110 // The cookie is not set in the current browser or the saved value is newer. 1111 $secure = ( 'https' === parse_url( admin_url(), PHP_URL_SCHEME ) ); 1112 setcookie( 'wp-settings-' . $user_id, $settings, time() + YEAR_IN_SECONDS, SITECOOKIEPATH, null, $secure ); 1113 setcookie( 'wp-settings-time-' . $user_id, time(), time() + YEAR_IN_SECONDS, SITECOOKIEPATH, null, $secure ); 1114 $_COOKIE[ 'wp-settings-' . $user_id ] = $settings; 1115 } 1116 1117 /** 1118 * Retrieves user interface setting value based on setting name. 1119 * 1120 * @since 2.7.0 1121 * 1122 * @param string $name The name of the setting. 1123 * @param string|false $default Optional. Default value to return when $name is not set. Default false. 1124 * @return mixed The last saved user setting or the default value/false if it doesn't exist. 1125 */ 1126 function get_user_setting( $name, $default = false ) { 1127 $all_user_settings = get_all_user_settings(); 1128 1129 return isset( $all_user_settings[ $name ] ) ? $all_user_settings[ $name ] : $default; 1130 } 1131 1132 /** 1133 * Adds or updates user interface setting. 1134 * 1135 * Both $name and $value can contain only ASCII letters, numbers, hyphens, and underscores. 1136 * 1137 * This function has to be used before any output has started as it calls setcookie(). 1138 * 1139 * @since 2.8.0 1140 * 1141 * @param string $name The name of the setting. 1142 * @param string $value The value for the setting. 1143 * @return bool|null True if set successfully, false otherwise. 1144 * Null if the current user is not a member of the site. 1145 */ 1146 function set_user_setting( $name, $value ) { 1147 if ( headers_sent() ) { 1148 return false; 1149 } 1150 1151 $all_user_settings = get_all_user_settings(); 1152 $all_user_settings[ $name ] = $value; 1153 1154 return wp_set_all_user_settings( $all_user_settings ); 1155 } 1156 1157 /** 1158 * Deletes user interface settings. 1159 * 1160 * Deleting settings would reset them to the defaults. 1161 * 1162 * This function has to be used before any output has started as it calls setcookie(). 1163 * 1164 * @since 2.7.0 1165 * 1166 * @param string $names The name or array of names of the setting to be deleted. 1167 * @return bool|null True if deleted successfully, false otherwise. 1168 * Null if the current user is not a member of the site. 1169 */ 1170 function delete_user_setting( $names ) { 1171 if ( headers_sent() ) { 1172 return false; 1173 } 1174 1175 $all_user_settings = get_all_user_settings(); 1176 $names = (array) $names; 1177 $deleted = false; 1178 1179 foreach ( $names as $name ) { 1180 if ( isset( $all_user_settings[ $name ] ) ) { 1181 unset( $all_user_settings[ $name ] ); 1182 $deleted = true; 1183 } 1184 } 1185 1186 if ( $deleted ) { 1187 return wp_set_all_user_settings( $all_user_settings ); 1188 } 1189 1190 return false; 1191 } 1192 1193 /** 1194 * Retrieves all user interface settings. 1195 * 1196 * @since 2.7.0 1197 * 1198 * @global array $_updated_user_settings 1199 * 1200 * @return array The last saved user settings or empty array. 1201 */ 1202 function get_all_user_settings() { 1203 global $_updated_user_settings; 1204 1205 $user_id = get_current_user_id(); 1206 if ( ! $user_id ) { 1207 return array(); 1208 } 1209 1210 if ( isset( $_updated_user_settings ) && is_array( $_updated_user_settings ) ) { 1211 return $_updated_user_settings; 1212 } 1213 1214 $user_settings = array(); 1215 1216 if ( isset( $_COOKIE[ 'wp-settings-' . $user_id ] ) ) { 1217 $cookie = preg_replace( '/[^A-Za-z0-9=&_-]/', '', $_COOKIE[ 'wp-settings-' . $user_id ] ); 1218 1219 if ( strpos( $cookie, '=' ) ) { // '=' cannot be 1st char. 1220 parse_str( $cookie, $user_settings ); 1221 } 1222 } else { 1223 $option = get_user_option( 'user-settings', $user_id ); 1224 1225 if ( $option && is_string( $option ) ) { 1226 parse_str( $option, $user_settings ); 1227 } 1228 } 1229 1230 $_updated_user_settings = $user_settings; 1231 return $user_settings; 1232 } 1233 1234 /** 1235 * Private. Sets all user interface settings. 1236 * 1237 * @since 2.8.0 1238 * @access private 1239 * 1240 * @global array $_updated_user_settings 1241 * 1242 * @param array $user_settings User settings. 1243 * @return bool|null True if set successfully, false if the current user could not be found. 1244 * Null if the current user is not a member of the site. 1245 */ 1246 function wp_set_all_user_settings( $user_settings ) { 1247 global $_updated_user_settings; 1248 1249 $user_id = get_current_user_id(); 1250 if ( ! $user_id ) { 1251 return false; 1252 } 1253 1254 if ( ! is_user_member_of_blog() ) { 1255 return; 1256 } 1257 1258 $settings = ''; 1259 foreach ( $user_settings as $name => $value ) { 1260 $_name = preg_replace( '/[^A-Za-z0-9_-]+/', '', $name ); 1261 $_value = preg_replace( '/[^A-Za-z0-9_-]+/', '', $value ); 1262 1263 if ( ! empty( $_name ) ) { 1264 $settings .= $_name . '=' . $_value . '&'; 1265 } 1266 } 1267 1268 $settings = rtrim( $settings, '&' ); 1269 parse_str( $settings, $_updated_user_settings ); 1270 1271 update_user_option( $user_id, 'user-settings', $settings, false ); 1272 update_user_option( $user_id, 'user-settings-time', time(), false ); 1273 1274 return true; 1275 } 1276 1277 /** 1278 * Deletes the user settings of the current user. 1279 * 1280 * @since 2.7.0 1281 */ 1282 function delete_all_user_settings() { 1283 $user_id = get_current_user_id(); 1284 if ( ! $user_id ) { 1285 return; 1286 } 1287 1288 update_user_option( $user_id, 'user-settings', '', false ); 1289 setcookie( 'wp-settings-' . $user_id, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH ); 1290 } 1291 1292 /** 1293 * Retrieve an option value for the current network based on name of option. 1294 * 1295 * @since 2.8.0 1296 * @since 4.4.0 The `$use_cache` parameter was deprecated. 1297 * @since 4.4.0 Modified into wrapper for get_network_option() 1298 * 1299 * @see get_network_option() 1300 * 1301 * @param string $option Name of the option to retrieve. Expected to not be SQL-escaped. 1302 * @param mixed $default Optional. Value to return if the option doesn't exist. Default false. 1303 * @param bool $deprecated Whether to use cache. Multisite only. Always set to true. 1304 * @return mixed Value set for the option. 1305 */ 1306 function get_site_option( $option, $default = false, $deprecated = true ) { 1307 return get_network_option( null, $option, $default ); 1308 } 1309 1310 /** 1311 * Adds a new option for the current network. 1312 * 1313 * Existing options will not be updated. Note that prior to 3.3 this wasn't the case. 1314 * 1315 * @since 2.8.0 1316 * @since 4.4.0 Modified into wrapper for add_network_option() 1317 * 1318 * @see add_network_option() 1319 * 1320 * @param string $option Name of the option to add. Expected to not be SQL-escaped. 1321 * @param mixed $value Option value, can be anything. Expected to not be SQL-escaped. 1322 * @return bool True if the option was added, false otherwise. 1323 */ 1324 function add_site_option( $option, $value ) { 1325 return add_network_option( null, $option, $value ); 1326 } 1327 1328 /** 1329 * Removes a option by name for the current network. 1330 * 1331 * @since 2.8.0 1332 * @since 4.4.0 Modified into wrapper for delete_network_option() 1333 * 1334 * @see delete_network_option() 1335 * 1336 * @param string $option Name of the option to delete. Expected to not be SQL-escaped. 1337 * @return bool True if the option was deleted, false otherwise. 1338 */ 1339 function delete_site_option( $option ) { 1340 return delete_network_option( null, $option ); 1341 } 1342 1343 /** 1344 * Updates the value of an option that was already added for the current network. 1345 * 1346 * @since 2.8.0 1347 * @since 4.4.0 Modified into wrapper for update_network_option() 1348 * 1349 * @see update_network_option() 1350 * 1351 * @param string $option Name of the option. Expected to not be SQL-escaped. 1352 * @param mixed $value Option value. Expected to not be SQL-escaped. 1353 * @return bool True if the value was updated, false otherwise. 1354 */ 1355 function update_site_option( $option, $value ) { 1356 return update_network_option( null, $option, $value ); 1357 } 1358 1359 /** 1360 * Retrieves a network's option value based on the option name. 1361 * 1362 * @since 4.4.0 1363 * 1364 * @see get_option() 1365 * 1366 * @global wpdb $wpdb WordPress database abstraction object. 1367 * 1368 * @param int $network_id ID of the network. Can be null to default to the current network ID. 1369 * @param string $option Name of the option to retrieve. Expected to not be SQL-escaped. 1370 * @param mixed $default Optional. Value to return if the option doesn't exist. Default false. 1371 * @return mixed Value set for the option. 1372 */ 1373 function get_network_option( $network_id, $option, $default = false ) { 1374 global $wpdb; 1375 1376 if ( $network_id && ! is_numeric( $network_id ) ) { 1377 return false; 1378 } 1379 1380 $network_id = (int) $network_id; 1381 1382 // Fallback to the current network if a network ID is not specified. 1383 if ( ! $network_id ) { 1384 $network_id = get_current_network_id(); 1385 } 1386 1387 /** 1388 * Filters the value of an existing network option before it is retrieved. 1389 * 1390 * The dynamic portion of the hook name, `$option`, refers to the option name. 1391 * 1392 * Returning a truthy value from the filter will effectively short-circuit retrieval 1393 * and return the passed value instead. 1394 * 1395 * @since 2.9.0 As 'pre_site_option_' . $key 1396 * @since 3.0.0 1397 * @since 4.4.0 The `$option` parameter was added. 1398 * @since 4.7.0 The `$network_id` parameter was added. 1399 * @since 4.9.0 The `$default` parameter was added. 1400 * 1401 * @param mixed $pre_option The value to return instead of the option value. This differs 1402 * from `$default`, which is used as the fallback value in the event 1403 * the option doesn't exist elsewhere in get_network_option(). 1404 * Default false (to skip past the short-circuit). 1405 * @param string $option Option name. 1406 * @param int $network_id ID of the network. 1407 * @param mixed $default The fallback value to return if the option does not exist. 1408 * Default false. 1409 */ 1410 $pre = apply_filters( "pre_site_option_{$option}", false, $option, $network_id, $default ); 1411 1412 if ( false !== $pre ) { 1413 return $pre; 1414 } 1415 1416 // Prevent non-existent options from triggering multiple queries. 1417 $notoptions_key = "$network_id:notoptions"; 1418 $notoptions = wp_cache_get( $notoptions_key, 'site-options' ); 1419 1420 if ( is_array( $notoptions ) && isset( $notoptions[ $option ] ) ) { 1421 1422 /** 1423 * Filters a specific default network option. 1424 * 1425 * The dynamic portion of the hook name, `$option`, refers to the option name. 1426 * 1427 * @since 3.4.0 1428 * @since 4.4.0 The `$option` parameter was added. 1429 * @since 4.7.0 The `$network_id` parameter was added. 1430 * 1431 * @param mixed $default The value to return if the site option does not exist 1432 * in the database. 1433 * @param string $option Option name. 1434 * @param int $network_id ID of the network. 1435 */ 1436 return apply_filters( "default_site_option_{$option}", $default, $option, $network_id ); 1437 } 1438 1439 if ( ! is_multisite() ) { 1440 /** This filter is documented in wp-includes/option.php */ 1441 $default = apply_filters( 'default_site_option_' . $option, $default, $option, $network_id ); 1442 $value = get_option( $option, $default ); 1443 } else { 1444 $cache_key = "$network_id:$option"; 1445 $value = wp_cache_get( $cache_key, 'site-options' ); 1446 1447 if ( ! isset( $value ) || false === $value ) { 1448 $row = $wpdb->get_row( $wpdb->prepare( "SELECT meta_value FROM $wpdb->sitemeta WHERE meta_key = %s AND site_id = %d", $option, $network_id ) ); 1449 1450 // Has to be get_row() instead of get_var() because of funkiness with 0, false, null values. 1451 if ( is_object( $row ) ) { 1452 $value = $row->meta_value; 1453 $value = maybe_unserialize( $value ); 1454 wp_cache_set( $cache_key, $value, 'site-options' ); 1455 } else { 1456 if ( ! is_array( $notoptions ) ) { 1457 $notoptions = array(); 1458 } 1459 1460 $notoptions[ $option ] = true; 1461 wp_cache_set( $notoptions_key, $notoptions, 'site-options' ); 1462 1463 /** This filter is documented in wp-includes/option.php */ 1464 $value = apply_filters( 'default_site_option_' . $option, $default, $option, $network_id ); 1465 } 1466 } 1467 } 1468 1469 if ( ! is_array( $notoptions ) ) { 1470 $notoptions = array(); 1471 wp_cache_set( $notoptions_key, $notoptions, 'site-options' ); 1472 } 1473 1474 /** 1475 * Filters the value of an existing network option. 1476 * 1477 * The dynamic portion of the hook name, `$option`, refers to the option name. 1478 * 1479 * @since 2.9.0 As 'site_option_' . $key 1480 * @since 3.0.0 1481 * @since 4.4.0 The `$option` parameter was added. 1482 * @since 4.7.0 The `$network_id` parameter was added. 1483 * 1484 * @param mixed $value Value of network option. 1485 * @param string $option Option name. 1486 * @param int $network_id ID of the network. 1487 */ 1488 return apply_filters( "site_option_{$option}", $value, $option, $network_id ); 1489 } 1490 1491 /** 1492 * Adds a new network option. 1493 * 1494 * Existing options will not be updated. 1495 * 1496 * @since 4.4.0 1497 * 1498 * @see add_option() 1499 * 1500 * @global wpdb $wpdb WordPress database abstraction object. 1501 * 1502 * @param int $network_id ID of the network. Can be null to default to the current network ID. 1503 * @param string $option Name of the option to add. Expected to not be SQL-escaped. 1504 * @param mixed $value Option value, can be anything. Expected to not be SQL-escaped. 1505 * @return bool True if the option was added, false otherwise. 1506 */ 1507 function add_network_option( $network_id, $option, $value ) { 1508 global $wpdb; 1509 1510 if ( $network_id && ! is_numeric( $network_id ) ) { 1511 return false; 1512 } 1513 1514 $network_id = (int) $network_id; 1515 1516 // Fallback to the current network if a network ID is not specified. 1517 if ( ! $network_id ) { 1518 $network_id = get_current_network_id(); 1519 } 1520 1521 wp_protect_special_option( $option ); 1522 1523 /** 1524 * Filters the value of a specific network option before it is added. 1525 * 1526 * The dynamic portion of the hook name, `$option`, refers to the option name. 1527 * 1528 * @since 2.9.0 As 'pre_add_site_option_' . $key 1529 * @since 3.0.0 1530 * @since 4.4.0 The `$option` parameter was added. 1531 * @since 4.7.0 The `$network_id` parameter was added. 1532 * 1533 * @param mixed $value Value of network option. 1534 * @param string $option Option name. 1535 * @param int $network_id ID of the network. 1536 */ 1537 $value = apply_filters( "pre_add_site_option_{$option}", $value, $option, $network_id ); 1538 1539 $notoptions_key = "$network_id:notoptions"; 1540 1541 if ( ! is_multisite() ) { 1542 $result = add_option( $option, $value, '', 'no' ); 1543 } else { 1544 $cache_key = "$network_id:$option"; 1545 1546 // Make sure the option doesn't already exist. 1547 // We can check the 'notoptions' cache before we ask for a DB query. 1548 $notoptions = wp_cache_get( $notoptions_key, 'site-options' ); 1549 1550 if ( ! is_array( $notoptions ) || ! isset( $notoptions[ $option ] ) ) { 1551 if ( false !== get_network_option( $network_id, $option, false ) ) { 1552 return false; 1553 } 1554 } 1555 1556 $value = sanitize_option( $option, $value ); 1557 1558 $serialized_value = maybe_serialize( $value ); 1559 $result = $wpdb->insert( 1560 $wpdb->sitemeta, 1561 array( 1562 'site_id' => $network_id, 1563 'meta_key' => $option, 1564 'meta_value' => $serialized_value, 1565 ) 1566 ); 1567 1568 if ( ! $result ) { 1569 return false; 1570 } 1571 1572 wp_cache_set( $cache_key, $value, 'site-options' ); 1573 1574 // This option exists now. 1575 $notoptions = wp_cache_get( $notoptions_key, 'site-options' ); // Yes, again... we need it to be fresh. 1576 1577 if ( is_array( $notoptions ) && isset( $notoptions[ $option ] ) ) { 1578 unset( $notoptions[ $option ] ); 1579 wp_cache_set( $notoptions_key, $notoptions, 'site-options' ); 1580 } 1581 } 1582 1583 if ( $result ) { 1584 1585 /** 1586 * Fires after a specific network option has been successfully added. 1587 * 1588 * The dynamic portion of the hook name, `$option`, refers to the option name. 1589 * 1590 * @since 2.9.0 As "add_site_option_{$key}" 1591 * @since 3.0.0 1592 * @since 4.7.0 The `$network_id` parameter was added. 1593 * 1594 * @param string $option Name of the network option. 1595 * @param mixed $value Value of the network option. 1596 * @param int $network_id ID of the network. 1597 */ 1598 do_action( "add_site_option_{$option}", $option, $value, $network_id ); 1599 1600 /** 1601 * Fires after a network option has been successfully added. 1602 * 1603 * @since 3.0.0 1604 * @since 4.7.0 The `$network_id` parameter was added. 1605 * 1606 * @param string $option Name of the network option. 1607 * @param mixed $value Value of the network option. 1608 * @param int $network_id ID of the network. 1609 */ 1610 do_action( 'add_site_option', $option, $value, $network_id ); 1611 1612 return true; 1613 } 1614 1615 return false; 1616 } 1617 1618 /** 1619 * Removes a network option by name. 1620 * 1621 * @since 4.4.0 1622 * 1623 * @see delete_option() 1624 * 1625 * @global wpdb $wpdb WordPress database abstraction object. 1626 * 1627 * @param int $network_id ID of the network. Can be null to default to the current network ID. 1628 * @param string $option Name of the option to delete. Expected to not be SQL-escaped. 1629 * @return bool True if the option was deleted, false otherwise. 1630 */ 1631 function delete_network_option( $network_id, $option ) { 1632 global $wpdb; 1633 1634 if ( $network_id && ! is_numeric( $network_id ) ) { 1635 return false; 1636 } 1637 1638 $network_id = (int) $network_id; 1639 1640 // Fallback to the current network if a network ID is not specified. 1641 if ( ! $network_id ) { 1642 $network_id = get_current_network_id(); 1643 } 1644 1645 /** 1646 * Fires immediately before a specific network option is deleted. 1647 * 1648 * The dynamic portion of the hook name, `$option`, refers to the option name. 1649 * 1650 * @since 3.0.0 1651 * @since 4.4.0 The `$option` parameter was added. 1652 * @since 4.7.0 The `$network_id` parameter was added. 1653 * 1654 * @param string $option Option name. 1655 * @param int $network_id ID of the network. 1656 */ 1657 do_action( "pre_delete_site_option_{$option}", $option, $network_id ); 1658 1659 if ( ! is_multisite() ) { 1660 $result = delete_option( $option ); 1661 } else { 1662 $row = $wpdb->get_row( $wpdb->prepare( "SELECT meta_id FROM {$wpdb->sitemeta} WHERE meta_key = %s AND site_id = %d", $option, $network_id ) ); 1663 if ( is_null( $row ) || ! $row->meta_id ) { 1664 return false; 1665 } 1666 $cache_key = "$network_id:$option"; 1667 wp_cache_delete( $cache_key, 'site-options' ); 1668 1669 $result = $wpdb->delete( 1670 $wpdb->sitemeta, 1671 array( 1672 'meta_key' => $option, 1673 'site_id' => $network_id, 1674 ) 1675 ); 1676 } 1677 1678 if ( $result ) { 1679 1680 /** 1681 * Fires after a specific network option has been deleted. 1682 * 1683 * The dynamic portion of the hook name, `$option`, refers to the option name. 1684 * 1685 * @since 2.9.0 As "delete_site_option_{$key}" 1686 * @since 3.0.0 1687 * @since 4.7.0 The `$network_id` parameter was added. 1688 * 1689 * @param string $option Name of the network option. 1690 * @param int $network_id ID of the network. 1691 */ 1692 do_action( "delete_site_option_{$option}", $option, $network_id ); 1693 1694 /** 1695 * Fires after a network option has been deleted. 1696 * 1697 * @since 3.0.0 1698 * @since 4.7.0 The `$network_id` parameter was added. 1699 * 1700 * @param string $option Name of the network option. 1701 * @param int $network_id ID of the network. 1702 */ 1703 do_action( 'delete_site_option', $option, $network_id ); 1704 1705 return true; 1706 } 1707 1708 return false; 1709 } 1710 1711 /** 1712 * Updates the value of a network option that was already added. 1713 * 1714 * @since 4.4.0 1715 * 1716 * @see update_option() 1717 * 1718 * @global wpdb $wpdb WordPress database abstraction object. 1719 * 1720 * @param int $network_id ID of the network. Can be null to default to the current network ID. 1721 * @param string $option Name of the option. Expected to not be SQL-escaped. 1722 * @param mixed $value Option value. Expected to not be SQL-escaped. 1723 * @return bool True if the value was updated, false otherwise. 1724 */ 1725 function update_network_option( $network_id, $option, $value ) { 1726 global $wpdb; 1727 1728 if ( $network_id && ! is_numeric( $network_id ) ) { 1729 return false; 1730 } 1731 1732 $network_id = (int) $network_id; 1733 1734 // Fallback to the current network if a network ID is not specified. 1735 if ( ! $network_id ) { 1736 $network_id = get_current_network_id(); 1737 } 1738 1739 wp_protect_special_option( $option ); 1740 1741 $old_value = get_network_option( $network_id, $option, false ); 1742 1743 /** 1744 * Filters a specific network option before its value is updated. 1745 * 1746 * The dynamic portion of the hook name, `$option`, refers to the option name. 1747 * 1748 * @since 2.9.0 As 'pre_update_site_option_' . $key 1749 * @since 3.0.0 1750 * @since 4.4.0 The `$option` parameter was added. 1751 * @since 4.7.0 The `$network_id` parameter was added. 1752 * 1753 * @param mixed $value New value of the network option. 1754 * @param mixed $old_value Old value of the network option. 1755 * @param string $option Option name. 1756 * @param int $network_id ID of the network. 1757 */ 1758 $value = apply_filters( "pre_update_site_option_{$option}", $value, $old_value, $option, $network_id ); 1759 1760 /* 1761 * If the new and old values are the same, no need to update. 1762 * 1763 * Unserialized values will be adequate in most cases. If the unserialized 1764 * data differs, the (maybe) serialized data is checked to avoid 1765 * unnecessary database calls for otherwise identical object instances. 1766 * 1767 * See https://core.trac.wordpress.org/ticket/44956 1768 */ 1769 if ( $value === $old_value || maybe_serialize( $value ) === maybe_serialize( $old_value ) ) { 1770 return false; 1771 } 1772 1773 if ( false === $old_value ) { 1774 return add_network_option( $network_id, $option, $value ); 1775 } 1776 1777 $notoptions_key = "$network_id:notoptions"; 1778 $notoptions = wp_cache_get( $notoptions_key, 'site-options' ); 1779 1780 if ( is_array( $notoptions ) && isset( $notoptions[ $option ] ) ) { 1781 unset( $notoptions[ $option ] ); 1782 wp_cache_set( $notoptions_key, $notoptions, 'site-options' ); 1783 } 1784 1785 if ( ! is_multisite() ) { 1786 $result = update_option( $option, $value, 'no' ); 1787 } else { 1788 $value = sanitize_option( $option, $value ); 1789 1790 $serialized_value = maybe_serialize( $value ); 1791 $result = $wpdb->update( 1792 $wpdb->sitemeta, 1793 array( 'meta_value' => $serialized_value ), 1794 array( 1795 'site_id' => $network_id, 1796 'meta_key' => $option, 1797 ) 1798 ); 1799 1800 if ( $result ) { 1801 $cache_key = "$network_id:$option"; 1802 wp_cache_set( $cache_key, $value, 'site-options' ); 1803 } 1804 } 1805 1806 if ( $result ) { 1807 1808 /** 1809 * Fires after the value of a specific network option has been successfully updated. 1810 * 1811 * The dynamic portion of the hook name, `$option`, refers to the option name. 1812 * 1813 * @since 2.9.0 As "update_site_option_{$key}" 1814 * @since 3.0.0 1815 * @since 4.7.0 The `$network_id` parameter was added. 1816 * 1817 * @param string $option Name of the network option. 1818 * @param mixed $value Current value of the network option. 1819 * @param mixed $old_value Old value of the network option. 1820 * @param int $network_id ID of the network. 1821 */ 1822 do_action( "update_site_option_{$option}", $option, $value, $old_value, $network_id ); 1823 1824 /** 1825 * Fires after the value of a network option has been successfully updated. 1826 * 1827 * @since 3.0.0 1828 * @since 4.7.0 The `$network_id` parameter was added. 1829 * 1830 * @param string $option Name of the network option. 1831 * @param mixed $value Current value of the network option. 1832 * @param mixed $old_value Old value of the network option. 1833 * @param int $network_id ID of the network. 1834 */ 1835 do_action( 'update_site_option', $option, $value, $old_value, $network_id ); 1836 1837 return true; 1838 } 1839 1840 return false; 1841 } 1842 1843 /** 1844 * Deletes a site transient. 1845 * 1846 * @since 2.9.0 1847 * 1848 * @param string $transient Transient name. Expected to not be SQL-escaped. 1849 * @return bool True if the transient was deleted, false otherwise. 1850 */ 1851 function delete_site_transient( $transient ) { 1852 1853 /** 1854 * Fires immediately before a specific site transient is deleted. 1855 * 1856 * The dynamic portion of the hook name, `$transient`, refers to the transient name. 1857 * 1858 * @since 3.0.0 1859 * 1860 * @param string $transient Transient name. 1861 */ 1862 do_action( "delete_site_transient_{$transient}", $transient ); 1863 1864 if ( wp_using_ext_object_cache() || wp_installing() ) { 1865 $result = wp_cache_delete( $transient, 'site-transient' ); 1866 } else { 1867 $option_timeout = '_site_transient_timeout_' . $transient; 1868 $option = '_site_transient_' . $transient; 1869 $result = delete_site_option( $option ); 1870 1871 if ( $result ) { 1872 delete_site_option( $option_timeout ); 1873 } 1874 } 1875 1876 if ( $result ) { 1877 1878 /** 1879 * Fires after a transient is deleted. 1880 * 1881 * @since 3.0.0 1882 * 1883 * @param string $transient Deleted transient name. 1884 */ 1885 do_action( 'deleted_site_transient', $transient ); 1886 } 1887 1888 return $result; 1889 } 1890 1891 /** 1892 * Retrieves the value of a site transient. 1893 * 1894 * If the transient does not exist, does not have a value, or has expired, 1895 * then the return value will be false. 1896 * 1897 * @since 2.9.0 1898 * 1899 * @see get_transient() 1900 * 1901 * @param string $transient Transient name. Expected to not be SQL-escaped. 1902 * @return mixed Value of transient. 1903 */ 1904 function get_site_transient( $transient ) { 1905 1906 /** 1907 * Filters the value of an existing site transient before it is retrieved. 1908 * 1909 * The dynamic portion of the hook name, `$transient`, refers to the transient name. 1910 * 1911 * Returning a truthy value from the filter will effectively short-circuit retrieval 1912 * and return the passed value instead. 1913 * 1914 * @since 2.9.0 1915 * @since 4.4.0 The `$transient` parameter was added. 1916 * 1917 * @param mixed $pre_site_transient The default value to return if the site transient does not exist. 1918 * Any value other than false will short-circuit the retrieval 1919 * of the transient, and return that value. 1920 * @param string $transient Transient name. 1921 */ 1922 $pre = apply_filters( "pre_site_transient_{$transient}", false, $transient ); 1923 1924 if ( false !== $pre ) { 1925 return $pre; 1926 } 1927 1928 if ( wp_using_ext_object_cache() || wp_installing() ) { 1929 $value = wp_cache_get( $transient, 'site-transient' ); 1930 } else { 1931 // Core transients that do not have a timeout. Listed here so querying timeouts can be avoided. 1932 $no_timeout = array( 'update_core', 'update_plugins', 'update_themes' ); 1933 $transient_option = '_site_transient_' . $transient; 1934 if ( ! in_array( $transient, $no_timeout, true ) ) { 1935 $transient_timeout = '_site_transient_timeout_' . $transient; 1936 $timeout = get_site_option( $transient_timeout ); 1937 if ( false !== $timeout && $timeout < time() ) { 1938 delete_site_option( $transient_option ); 1939 delete_site_option( $transient_timeout ); 1940 $value = false; 1941 } 1942 } 1943 1944 if ( ! isset( $value ) ) { 1945 $value = get_site_option( $transient_option ); 1946 } 1947 } 1948 1949 /** 1950 * Filters the value of an existing site transient. 1951 * 1952 * The dynamic portion of the hook name, `$transient`, refers to the transient name. 1953 * 1954 * @since 2.9.0 1955 * @since 4.4.0 The `$transient` parameter was added. 1956 * 1957 * @param mixed $value Value of site transient. 1958 * @param string $transient Transient name. 1959 */ 1960 return apply_filters( "site_transient_{$transient}", $value, $transient ); 1961 } 1962 1963 /** 1964 * Sets/updates the value of a site transient. 1965 * 1966 * You do not need to serialize values. If the value needs to be serialized, 1967 * then it will be serialized before it is set. 1968 * 1969 * @since 2.9.0 1970 * 1971 * @see set_transient() 1972 * 1973 * @param string $transient Transient name. Expected to not be SQL-escaped. Must be 1974 * 167 characters or fewer in length. 1975 * @param mixed $value Transient value. Expected to not be SQL-escaped. 1976 * @param int $expiration Optional. Time until expiration in seconds. Default 0 (no expiration). 1977 * @return bool True if the value was set, false otherwise. 1978 */ 1979 function set_site_transient( $transient, $value, $expiration = 0 ) { 1980 1981 /** 1982 * Filters the value of a specific site transient before it is set. 1983 * 1984 * The dynamic portion of the hook name, `$transient`, refers to the transient name. 1985 * 1986 * @since 3.0.0 1987 * @since 4.4.0 The `$transient` parameter was added. 1988 * 1989 * @param mixed $value New value of site transient. 1990 * @param string $transient Transient name. 1991 */ 1992 $value = apply_filters( "pre_set_site_transient_{$transient}", $value, $transient ); 1993 1994 $expiration = (int) $expiration; 1995 1996 /** 1997 * Filters the expiration for a site transient before its value is set. 1998 * 1999 * The dynamic portion of the hook name, `$transient`, refers to the transient name. 2000 * 2001 * @since 4.4.0 2002 * 2003 * @param int $expiration Time until expiration in seconds. Use 0 for no expiration. 2004 * @param mixed $value New value of site transient. 2005 * @param string $transient Transient name. 2006 */ 2007 $expiration = apply_filters( "expiration_of_site_transient_{$transient}", $expiration, $value, $transient ); 2008 2009 if ( wp_using_ext_object_cache() || wp_installing() ) { 2010 $result = wp_cache_set( $transient, $value, 'site-transient', $expiration ); 2011 } else { 2012 $transient_timeout = '_site_transient_timeout_' . $transient; 2013 $option = '_site_transient_' . $transient; 2014 2015 if ( false === get_site_option( $option ) ) { 2016 if ( $expiration ) { 2017 add_site_option( $transient_timeout, time() + $expiration ); 2018 } 2019 $result = add_site_option( $option, $value ); 2020 } else { 2021 if ( $expiration ) { 2022 update_site_option( $transient_timeout, time() + $expiration ); 2023 } 2024 $result = update_site_option( $option, $value ); 2025 } 2026 } 2027 2028 if ( $result ) { 2029 2030 /** 2031 * Fires after the value for a specific site transient has been set. 2032 * 2033 * The dynamic portion of the hook name, `$transient`, refers to the transient name. 2034 * 2035 * @since 3.0.0 2036 * @since 4.4.0 The `$transient` parameter was added 2037 * 2038 * @param mixed $value Site transient value. 2039 * @param int $expiration Time until expiration in seconds. 2040 * @param string $transient Transient name. 2041 */ 2042 do_action( "set_site_transient_{$transient}", $value, $expiration, $transient ); 2043 2044 /** 2045 * Fires after the value for a site transient has been set. 2046 * 2047 * @since 3.0.0 2048 * 2049 * @param string $transient The name of the site transient. 2050 * @param mixed $value Site transient value. 2051 * @param int $expiration Time until expiration in seconds. 2052 */ 2053 do_action( 'setted_site_transient', $transient, $value, $expiration ); 2054 } 2055 2056 return $result; 2057 } 2058 2059 /** 2060 * Registers default settings available in WordPress. 2061 * 2062 * The settings registered here are primarily useful for the REST API, so this 2063 * does not encompass all settings available in WordPress. 2064 * 2065 * @since 4.7.0 2066 */ 2067 function register_initial_settings() { 2068 register_setting( 2069 'general', 2070 'blogname', 2071 array( 2072 'show_in_rest' => array( 2073 'name' => 'title', 2074 ), 2075 'type' => 'string', 2076 'description' => __( 'Site title.' ), 2077 ) 2078 ); 2079 2080 register_setting( 2081 'general', 2082 'blogdescription', 2083 array( 2084 'show_in_rest' => array( 2085 'name' => 'description', 2086 ), 2087 'type' => 'string', 2088 'description' => __( 'Site tagline.' ), 2089 ) 2090 ); 2091 2092 if ( ! is_multisite() ) { 2093 register_setting( 2094 'general', 2095 'siteurl', 2096 array( 2097 'show_in_rest' => array( 2098 'name' => 'url', 2099 'schema' => array( 2100 'format' => 'uri', 2101 ), 2102 ), 2103 'type' => 'string', 2104 'description' => __( 'Site URL.' ), 2105 ) 2106 ); 2107 } 2108 2109 if ( ! is_multisite() ) { 2110 register_setting( 2111 'general', 2112 'admin_email', 2113 array( 2114 'show_in_rest' => array( 2115 'name' => 'email', 2116 'schema' => array( 2117 'format' => 'email', 2118 ), 2119 ), 2120 'type' => 'string', 2121 'description' => __( 'This address is used for admin purposes, like new user notification.' ), 2122 ) 2123 ); 2124 } 2125 2126 register_setting( 2127 'general', 2128 'timezone_string', 2129 array( 2130 'show_in_rest' => array( 2131 'name' => 'timezone', 2132 ), 2133 'type' => 'string', 2134 'description' => __( 'A city in the same timezone as you.' ), 2135 ) 2136 ); 2137 2138 register_setting( 2139 'general', 2140 'date_format', 2141 array( 2142 'show_in_rest' => true, 2143 'type' => 'string', 2144 'description' => __( 'A date format for all date strings.' ), 2145 ) 2146 ); 2147 2148 register_setting( 2149 'general', 2150 'time_format', 2151 array( 2152 'show_in_rest' => true, 2153 'type' => 'string', 2154 'description' => __( 'A time format for all time strings.' ), 2155 ) 2156 ); 2157 2158 register_setting( 2159 'general', 2160 'start_of_week', 2161 array( 2162 'show_in_rest' => true, 2163 'type' => 'integer', 2164 'description' => __( 'A day number of the week that the week should start on.' ), 2165 ) 2166 ); 2167 2168 register_setting( 2169 'general', 2170 'WPLANG', 2171 array( 2172 'show_in_rest' => array( 2173 'name' => 'language', 2174 ), 2175 'type' => 'string', 2176 'description' => __( 'WordPress locale code.' ), 2177 'default' => 'en_US', 2178 ) 2179 ); 2180 2181 register_setting( 2182 'writing', 2183 'use_smilies', 2184 array( 2185 'show_in_rest' => true, 2186 'type' => 'boolean', 2187 'description' => __( 'Convert emoticons like :-) and :-P to graphics on display.' ), 2188 'default' => true, 2189 ) 2190 ); 2191 2192 register_setting( 2193 'writing', 2194 'default_category', 2195 array( 2196 'show_in_rest' => true, 2197 'type' => 'integer', 2198 'description' => __( 'Default post category.' ), 2199 ) 2200 ); 2201 2202 register_setting( 2203 'writing', 2204 'default_post_format', 2205 array( 2206 'show_in_rest' => true, 2207 'type' => 'string', 2208 'description' => __( 'Default post format.' ), 2209 ) 2210 ); 2211 2212 register_setting( 2213 'reading', 2214 'posts_per_page', 2215 array( 2216 'show_in_rest' => true, 2217 'type' => 'integer', 2218 'description' => __( 'Blog pages show at most.' ), 2219 'default' => 10, 2220 ) 2221 ); 2222 2223 register_setting( 2224 'discussion', 2225 'default_ping_status', 2226 array( 2227 'show_in_rest' => array( 2228 'schema' => array( 2229 'enum' => array( 'open', 'closed' ), 2230 ), 2231 ), 2232 'type' => 'string', 2233 'description' => __( 'Allow link notifications from other blogs (pingbacks and trackbacks) on new articles.' ), 2234 ) 2235 ); 2236 2237 register_setting( 2238 'discussion', 2239 'default_comment_status', 2240 array( 2241 'show_in_rest' => array( 2242 'schema' => array( 2243 'enum' => array( 'open', 'closed' ), 2244 ), 2245 ), 2246 'type' => 'string', 2247 'description' => __( 'Allow people to submit comments on new posts.' ), 2248 ) 2249 ); 2250 } 2251 2252 /** 2253 * Registers a setting and its data. 2254 * 2255 * @since 2.7.0 2256 * @since 3.0.0 The `misc` option group was deprecated. 2257 * @since 3.5.0 The `privacy` option group was deprecated. 2258 * @since 4.7.0 `$args` can be passed to set flags on the setting, similar to `register_meta()`. 2259 * @since 5.5.0 `$new_whitelist_options` was renamed to `$new_allowed_options`. 2260 * Please consider writing more inclusive code. 2261 * 2262 * @global array $new_allowed_options 2263 * @global array $wp_registered_settings 2264 * 2265 * @param string $option_group A settings group name. Should correspond to an allowed option key name. 2266 * Default allowed option key names include 'general', 'discussion', 'media', 2267 * 'reading', 'writing', and 'options'. 2268 * @param string $option_name The name of an option to sanitize and save. 2269 * @param array $args { 2270 * Data used to describe the setting when registered. 2271 * 2272 * @type string $type The type of data associated with this setting. 2273 * Valid values are 'string', 'boolean', 'integer', 'number', 'array', and 'object'. 2274 * @type string $description A description of the data attached to this setting. 2275 * @type callable $sanitize_callback A callback function that sanitizes the option's value. 2276 * @type bool|array $show_in_rest Whether data associated with this setting should be included in the REST API. 2277 * When registering complex settings, this argument may optionally be an 2278 * array with a 'schema' key. 2279 * @type mixed $default Default value when calling `get_option()`. 2280 * } 2281 */ 2282 function register_setting( $option_group, $option_name, $args = array() ) { 2283 global $new_allowed_options, $wp_registered_settings; 2284 2285 /* 2286 * In 5.5.0, the `$new_whitelist_options` global variable was renamed to `$new_allowed_options`. 2287 * Please consider writing more inclusive code. 2288 */ 2289 $GLOBALS['new_whitelist_options'] = &$new_allowed_options; 2290 2291 $defaults = array( 2292 'type' => 'string', 2293 'group' => $option_group, 2294 'description' => '', 2295 'sanitize_callback' => null, 2296 'show_in_rest' => false, 2297 ); 2298 2299 // Back-compat: old sanitize callback is added. 2300 if ( is_callable( $args ) ) { 2301 $args = array( 2302 'sanitize_callback' => $args, 2303 ); 2304 } 2305 2306 /** 2307 * Filters the registration arguments when registering a setting. 2308 * 2309 * @since 4.7.0 2310 * 2311 * @param array $args Array of setting registration arguments. 2312 * @param array $defaults Array of default arguments. 2313 * @param string $option_group Setting group. 2314 * @param string $option_name Setting name. 2315 */ 2316 $args = apply_filters( 'register_setting_args', $args, $defaults, $option_group, $option_name ); 2317 2318 $args = wp_parse_args( $args, $defaults ); 2319 2320 // Require an item schema when registering settings with an array type. 2321 if ( false !== $args['show_in_rest'] && 'array' === $args['type'] && ( ! is_array( $args['show_in_rest'] ) || ! isset( $args['show_in_rest']['schema']['items'] ) ) ) { 2322 _doing_it_wrong( __FUNCTION__, __( 'When registering an "array" setting to show in the REST API, you must specify the schema for each array item in "show_in_rest.schema.items".' ), '5.4.0' ); 2323 } 2324 2325 if ( ! is_array( $wp_registered_settings ) ) { 2326 $wp_registered_settings = array(); 2327 } 2328 2329 if ( 'misc' === $option_group ) { 2330 _deprecated_argument( 2331 __FUNCTION__, 2332 '3.0.0', 2333 sprintf( 2334 /* translators: %s: misc */ 2335 __( 'The "%s" options group has been removed. Use another settings group.' ), 2336 'misc' 2337 ) 2338 ); 2339 $option_group = 'general'; 2340 } 2341 2342 if ( 'privacy' === $option_group ) { 2343 _deprecated_argument( 2344 __FUNCTION__, 2345 '3.5.0', 2346 sprintf( 2347 /* translators: %s: privacy */ 2348 __( 'The "%s" options group has been removed. Use another settings group.' ), 2349 'privacy' 2350 ) 2351 ); 2352 $option_group = 'reading'; 2353 } 2354 2355 $new_allowed_options[ $option_group ][] = $option_name; 2356 2357 if ( ! empty( $args['sanitize_callback'] ) ) { 2358 add_filter( "sanitize_option_{$option_name}", $args['sanitize_callback'] ); 2359 } 2360 if ( array_key_exists( 'default', $args ) ) { 2361 add_filter( "default_option_{$option_name}", 'filter_default_option', 10, 3 ); 2362 } 2363 2364 /** 2365 * Fires immediately before the setting is registered but after its filters are in place. 2366 * 2367 * @since 5.5.0 2368 * 2369 * @param string $option_group Setting group. 2370 * @param string $option_name Setting name. 2371 * @param array $args Array of setting registration arguments. 2372 */ 2373 do_action( 'register_setting', $option_group, $option_name, $args ); 2374 2375 $wp_registered_settings[ $option_name ] = $args; 2376 } 2377 2378 /** 2379 * Unregisters a setting. 2380 * 2381 * @since 2.7.0 2382 * @since 4.7.0 `$sanitize_callback` was deprecated. The callback from `register_setting()` is now used instead. 2383 * @since 5.5.0 `$new_whitelist_options` was renamed to `$new_allowed_options`. 2384 * Please consider writing more inclusive code. 2385 * 2386 * @global array $new_allowed_options 2387 * @global array $wp_registered_settings 2388 * 2389 * @param string $option_group The settings group name used during registration. 2390 * @param string $option_name The name of the option to unregister. 2391 * @param callable $deprecated Optional. Deprecated. 2392 */ 2393 function unregister_setting( $option_group, $option_name, $deprecated = '' ) { 2394 global $new_allowed_options, $wp_registered_settings; 2395 2396 /* 2397 * In 5.5.0, the `$new_whitelist_options` global variable was renamed to `$new_allowed_options`. 2398 * Please consider writing more inclusive code. 2399 */ 2400 $GLOBALS['new_whitelist_options'] = &$new_allowed_options; 2401 2402 if ( 'misc' === $option_group ) { 2403 _deprecated_argument( 2404 __FUNCTION__, 2405 '3.0.0', 2406 sprintf( 2407 /* translators: %s: misc */ 2408 __( 'The "%s" options group has been removed. Use another settings group.' ), 2409 'misc' 2410 ) 2411 ); 2412 $option_group = 'general'; 2413 } 2414 2415 if ( 'privacy' === $option_group ) { 2416 _deprecated_argument( 2417 __FUNCTION__, 2418 '3.5.0', 2419 sprintf( 2420 /* translators: %s: privacy */ 2421 __( 'The "%s" options group has been removed. Use another settings group.' ), 2422 'privacy' 2423 ) 2424 ); 2425 $option_group = 'reading'; 2426 } 2427 2428 $pos = array_search( $option_name, (array) $new_allowed_options[ $option_group ], true ); 2429 2430 if ( false !== $pos ) { 2431 unset( $new_allowed_options[ $option_group ][ $pos ] ); 2432 } 2433 2434 if ( '' !== $deprecated ) { 2435 _deprecated_argument( 2436 __FUNCTION__, 2437 '4.7.0', 2438 sprintf( 2439 /* translators: 1: $sanitize_callback, 2: register_setting() */ 2440 __( '%1$s is deprecated. The callback from %2$s is used instead.' ), 2441 '<code>$sanitize_callback</code>', 2442 '<code>register_setting()</code>' 2443 ) 2444 ); 2445 remove_filter( "sanitize_option_{$option_name}", $deprecated ); 2446 } 2447 2448 if ( isset( $wp_registered_settings[ $option_name ] ) ) { 2449 // Remove the sanitize callback if one was set during registration. 2450 if ( ! empty( $wp_registered_settings[ $option_name ]['sanitize_callback'] ) ) { 2451 remove_filter( "sanitize_option_{$option_name}", $wp_registered_settings[ $option_name ]['sanitize_callback'] ); 2452 } 2453 2454 // Remove the default filter if a default was provided during registration. 2455 if ( array_key_exists( 'default', $wp_registered_settings[ $option_name ] ) ) { 2456 remove_filter( "default_option_{$option_name}", 'filter_default_option', 10 ); 2457 } 2458 2459 /** 2460 * Fires immediately before the setting is unregistered and after its filters have been removed. 2461 * 2462 * @since 5.5.0 2463 * 2464 * @param string $option_group Setting group. 2465 * @param string $option_name Setting name. 2466 */ 2467 do_action( 'unregister_setting', $option_group, $option_name ); 2468 2469 unset( $wp_registered_settings[ $option_name ] ); 2470 } 2471 } 2472 2473 /** 2474 * Retrieves an array of registered settings. 2475 * 2476 * @since 4.7.0 2477 * 2478 * @global array $wp_registered_settings 2479 * 2480 * @return array List of registered settings, keyed by option name. 2481 */ 2482 function get_registered_settings() { 2483 global $wp_registered_settings; 2484 2485 if ( ! is_array( $wp_registered_settings ) ) { 2486 return array(); 2487 } 2488 2489 return $wp_registered_settings; 2490 } 2491 2492 /** 2493 * Filters the default value for the option. 2494 * 2495 * For settings which register a default setting in `register_setting()`, this 2496 * function is added as a filter to `default_option_{$option}`. 2497 * 2498 * @since 4.7.0 2499 * 2500 * @param mixed $default Existing default value to return. 2501 * @param string $option Option name. 2502 * @param bool $passed_default Was `get_option()` passed a default value? 2503 * @return mixed Filtered default value. 2504 */ 2505 function filter_default_option( $default, $option, $passed_default ) { 2506 if ( $passed_default ) { 2507 return $default; 2508 } 2509 2510 $registered = get_registered_settings(); 2511 if ( empty( $registered[ $option ] ) ) { 2512 return $default; 2513 } 2514 2515 return $registered[ $option ]['default']; 2516 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Nov 21 01:00:03 2024 | Cross-referenced by PHPXref 0.7.1 |