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