wp/wp-includes/option.php
changeset 22 8c2e4d02f4ef
parent 21 48c4eec2b7e6
--- a/wp/wp-includes/option.php	Fri Sep 05 18:40:08 2025 +0200
+++ b/wp/wp-includes/option.php	Fri Sep 05 18:52:52 2025 +0200
@@ -162,37 +162,46 @@
 
 	if ( ! wp_installing() ) {
 		$alloptions = wp_load_alloptions();
-
+		/*
+		 * When getting an option value, we check in the following order for performance:
+		 *
+		 * 1. Check the 'alloptions' cache first to prioritize existing loaded options.
+		 * 2. Check the 'notoptions' cache before a cache lookup or DB hit.
+		 * 3. Check the 'options' cache prior to a DB hit.
+		 * 4. Check the DB for the option and cache it in either the 'options' or 'notoptions' cache.
+		 */
 		if ( isset( $alloptions[ $option ] ) ) {
 			$value = $alloptions[ $option ];
 		} else {
+			// Check for non-existent options first to avoid unnecessary object cache lookups and DB hits.
+			$notoptions = wp_cache_get( 'notoptions', 'options' );
+
+			if ( ! is_array( $notoptions ) ) {
+				$notoptions = array();
+				wp_cache_set( 'notoptions', $notoptions, 'options' );
+			}
+
+			if ( isset( $notoptions[ $option ] ) ) {
+				/**
+				 * Filters the default value for an option.
+				 *
+				 * The dynamic portion of the hook name, `$option`, refers to the option name.
+				 *
+				 * @since 3.4.0
+				 * @since 4.4.0 The `$option` parameter was added.
+				 * @since 4.7.0 The `$passed_default` parameter was added to distinguish between a `false` value and the default parameter value.
+				 *
+				 * @param mixed  $default_value  The default value to return if the option does not exist
+				 *                               in the database.
+				 * @param string $option         Option name.
+				 * @param bool   $passed_default Was `get_option()` passed a default value?
+				 */
+				return apply_filters( "default_option_{$option}", $default_value, $option, $passed_default );
+			}
+
 			$value = wp_cache_get( $option, 'options' );
 
 			if ( false === $value ) {
-				// Prevent non-existent options from triggering multiple queries.
-				$notoptions = wp_cache_get( 'notoptions', 'options' );
-
-				// Prevent non-existent `notoptions` key from triggering multiple key lookups.
-				if ( ! is_array( $notoptions ) ) {
-					$notoptions = array();
-					wp_cache_set( 'notoptions', $notoptions, 'options' );
-				} elseif ( isset( $notoptions[ $option ] ) ) {
-					/**
-					 * Filters the default value for an option.
-					 *
-					 * The dynamic portion of the hook name, `$option`, refers to the option name.
-					 *
-					 * @since 3.4.0
-					 * @since 4.4.0 The `$option` parameter was added.
-					 * @since 4.7.0 The `$passed_default` parameter was added to distinguish between a `false` value and the default parameter value.
-					 *
-					 * @param mixed  $default_value  The default value to return if the option does not exist
-					 *                               in the database.
-					 * @param string $option         Option name.
-					 * @param bool   $passed_default Was `get_option()` passed a default value?
-					 */
-					return apply_filters( "default_option_{$option}", $default_value, $option, $passed_default );
-				}
 
 				$row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", $option ) );
 
@@ -375,12 +384,13 @@
  * by the plugin which are generally autoloaded can be set to not autoload when the plugin is inactive.
  *
  * @since 6.4.0
+ * @since 6.7.0 The autoload values 'yes' and 'no' are deprecated.
  *
  * @global wpdb $wpdb WordPress database abstraction object.
  *
  * @param array $options Associative array of option names and their autoload values to set. The option names are
- *                       expected to not be SQL-escaped. The autoload values accept 'yes'|true to enable or 'no'|false
- *                       to disable.
+ *                       expected to not be SQL-escaped. The autoload values should be boolean values. For backward
+ *                       compatibility 'yes' and 'no' are also accepted, though using these values is deprecated.
  * @return array Associative array of all provided $options as keys and boolean values for whether their autoload value
  *               was updated.
  */
@@ -398,7 +408,12 @@
 	$results         = array();
 	foreach ( $options as $option => $autoload ) {
 		wp_protect_special_option( $option ); // Ensure only valid options can be passed.
-		if ( 'off' === $autoload || 'no' === $autoload || false === $autoload ) { // Sanitize autoload value and categorize accordingly.
+
+		/*
+		 * Sanitize autoload value and categorize accordingly.
+		 * The values 'yes', 'no', 'on', and 'off' are supported for backward compatibility.
+		 */
+		if ( 'off' === $autoload || 'no' === $autoload || false === $autoload ) {
 			$grouped_options['off'][] = $option;
 		} else {
 			$grouped_options['on'][] = $option;
@@ -496,12 +511,14 @@
  * each option at once.
  *
  * @since 6.4.0
+ * @since 6.7.0 The autoload values 'yes' and 'no' are deprecated.
  *
  * @see wp_set_option_autoload_values()
  *
- * @param string[]    $options  List of option names. Expected to not be SQL-escaped.
- * @param string|bool $autoload Autoload value to control whether to load the options when WordPress starts up.
- *                              Accepts 'yes'|true to enable or 'no'|false to disable.
+ * @param string[] $options  List of option names. Expected to not be SQL-escaped.
+ * @param bool     $autoload Autoload value to control whether to load the options when WordPress starts up.
+ *                           For backward compatibility 'yes' and 'no' are also accepted, though using these values is
+ *                           deprecated.
  * @return array Associative array of all provided $options as keys and boolean values for whether their autoload value
  *               was updated.
  */
@@ -518,12 +535,14 @@
  * multiple options at once.
  *
  * @since 6.4.0
+ * @since 6.7.0 The autoload values 'yes' and 'no' are deprecated.
  *
  * @see wp_set_option_autoload_values()
  *
- * @param string      $option   Name of the option. Expected to not be SQL-escaped.
- * @param string|bool $autoload Autoload value to control whether to load the option when WordPress starts up.
- *                              Accepts 'yes'|true to enable or 'no'|false to disable.
+ * @param string $option   Name of the option. Expected to not be SQL-escaped.
+ * @param bool   $autoload Autoload value to control whether to load the option when WordPress starts up.
+ *                         For backward compatibility 'yes' and 'no' are also accepted, though using these values is
+ *                         deprecated.
  * @return bool True if the autoload value was modified, false otherwise.
  */
 function wp_set_option_autoload( $option, $autoload ) {
@@ -670,7 +689,7 @@
  *
  * @global wpdb $wpdb WordPress database abstraction object.
  *
- * @param int      $network_id ID of the network. Can be null to default to the current network ID.
+ * @param int|null $network_id ID of the network. Can be null to default to the current network ID.
  * @param string[] $options    An array of option names to be loaded.
  */
 function wp_prime_network_option_caches( $network_id, array $options ) {
@@ -803,17 +822,19 @@
  *
  * @since 1.0.0
  * @since 4.2.0 The `$autoload` parameter was added.
+ * @since 6.7.0 The autoload values 'yes' and 'no' are deprecated.
  *
  * @global wpdb $wpdb WordPress database abstraction object.
  *
  * @param string    $option   Name of the option to update. Expected to not be SQL-escaped.
  * @param mixed     $value    Option value. Must be serializable if non-scalar. Expected to not be SQL-escaped.
  * @param bool|null $autoload Optional. Whether to load the option when WordPress starts up.
- *                            Accepts a boolean, or `null` to stick with the initial value or, if no initial value is set,
- *                            to leave the decision up to default heuristics in WordPress.
- *                            For existing options,
- *                            `$autoload` can only be updated using `update_option()` if `$value` is also changed.
- *                            For backward compatibility 'yes' and 'no' are also accepted.
+ *                            Accepts a boolean, or `null` to stick with the initial value or, if no initial value is
+ *                            set, to leave the decision up to default heuristics in WordPress.
+ *                            For existing options, `$autoload` can only be updated using `update_option()` if `$value`
+ *                            is also changed.
+ *                            For backward compatibility 'yes' and 'no' are also accepted, though using these values is
+ *                            deprecated.
  *                            Autoloading too many options can lead to performance problems, especially if the
  *                            options are not frequently used. For options which are accessed across several places
  *                            in the frontend, it is recommended to autoload them, by using true.
@@ -1026,6 +1047,7 @@
  *
  * @since 1.0.0
  * @since 6.6.0 The $autoload parameter's default value was changed to null.
+ * @since 6.7.0 The autoload values 'yes' and 'no' are deprecated.
  *
  * @global wpdb $wpdb WordPress database abstraction object.
  *
@@ -1034,11 +1056,12 @@
  *                              Expected to not be SQL-escaped.
  * @param string    $deprecated Optional. Description. Not used anymore.
  * @param bool|null $autoload   Optional. Whether to load the option when WordPress starts up.
- *                              Accepts a boolean, or `null` to leave the decision up to default heuristics in WordPress.
- *                              For backward compatibility 'yes' and 'no' are also accepted.
+ *                              Accepts a boolean, or `null` to leave the decision up to default heuristics in
+ *                              WordPress. For backward compatibility 'yes' and 'no' are also accepted, though using
+ *                              these values is deprecated.
  *                              Autoloading too many options can lead to performance problems, especially if the
  *                              options are not frequently used. For options which are accessed across several places
- *                              in the frontend, it is recommended to autoload them, by using 'yes'|true.
+ *                              in the frontend, it is recommended to autoload them, by using true.
  *                              For options which are accessed only on few specific URLs, it is recommended
  *                              to not autoload them, by using false.
  *                              Default is null, which means WordPress will determine the autoload value.
@@ -1145,7 +1168,7 @@
 	 *
 	 * The dynamic portion of the hook name, `$option`, refers to the option name.
 	 *
-	 * @since 2.5.0 As "add_option_{$name}"
+	 * @since 2.5.0 As `add_option_{$name}`
 	 * @since 3.0.0
 	 *
 	 * @param string $option Name of the option to add.
@@ -1217,6 +1240,15 @@
 		} else {
 			wp_cache_delete( $option, 'options' );
 		}
+
+		$notoptions = wp_cache_get( 'notoptions', 'options' );
+
+		if ( ! is_array( $notoptions ) ) {
+			$notoptions = array();
+		}
+		$notoptions[ $option ] = true;
+
+		wp_cache_set( 'notoptions', $notoptions, 'options' );
 	}
 
 	if ( $result ) {
@@ -1260,15 +1292,15 @@
  * @since 6.6.0
  * @access private
  *
- * @param string $option          The name of the option.
- * @param mixed $value            The value of the option to check its autoload value.
- * @param mixed $serialized_value The serialized value of the option to check its autoload value.
- * @param bool|null $autoload     The autoload value to check.
- *                                Accepts 'on'|true to enable or 'off'|false to disable, or
- *                                'auto-on', 'auto-off', or 'auto' for internal purposes.
- *                                Any other autoload value will be forced to either 'auto-on',
- *                                'auto-off', or 'auto'.
- *                                'yes' and 'no' are supported for backward compatibility.
+ * @param string    $option           The name of the option.
+ * @param mixed     $value            The value of the option to check its autoload value.
+ * @param mixed     $serialized_value The serialized value of the option to check its autoload value.
+ * @param bool|null $autoload         The autoload value to check.
+ *                                    Accepts 'on'|true to enable or 'off'|false to disable, or
+ *                                    'auto-on', 'auto-off', or 'auto' for internal purposes.
+ *                                    Any other autoload value will be forced to either 'auto-on',
+ *                                    'auto-off', or 'auto'.
+ *                                    'yes' and 'no' are supported for backward compatibility.
  * @return string Returns the original $autoload value if explicit, or 'auto-on', 'auto-off',
  *                or 'auto' depending on default heuristics.
  */
@@ -1564,14 +1596,26 @@
 		/**
 		 * Fires after the value for a transient has been set.
 		 *
-		 * @since 3.0.0
-		 * @since 3.6.0 The `$value` and `$expiration` parameters were added.
+		 * @since 6.8.0
 		 *
 		 * @param string $transient  The name of the transient.
 		 * @param mixed  $value      Transient value.
 		 * @param int    $expiration Time until expiration in seconds.
 		 */
-		do_action( 'setted_transient', $transient, $value, $expiration );
+		do_action( 'set_transient', $transient, $value, $expiration );
+
+		/**
+		 * Fires after the transient is set.
+		 *
+		 * @since 3.0.0
+		 * @since 3.6.0 The `$value` and `$expiration` parameters were added.
+		 * @deprecated 6.8.0 Use {@see 'set_transient'} instead.
+		 *
+		 * @param string $transient  The name of the transient.
+		 * @param mixed  $value      Transient value.
+		 * @param int    $expiration Time until expiration in seconds.
+		 */
+		do_action_deprecated( 'setted_transient', array( $transient, $value, $expiration ), '6.8.0', 'set_transient' );
 	}
 
 	return $result;
@@ -1677,7 +1721,11 @@
 		}
 
 		$last_saved = (int) get_user_option( 'user-settings-time', $user_id );
-		$current    = isset( $_COOKIE[ 'wp-settings-time-' . $user_id ] ) ? preg_replace( '/[^0-9]/', '', $_COOKIE[ 'wp-settings-time-' . $user_id ] ) : 0;
+		$current    = 0;
+
+		if ( isset( $_COOKIE[ 'wp-settings-time-' . $user_id ] ) ) {
+			$current = (int) preg_replace( '/[^0-9]/', '', $_COOKIE[ 'wp-settings-time-' . $user_id ] );
+		}
 
 		// The cookie is newer than the saved value. Update the user_option and leave the cookie as-is.
 		if ( $current > $last_saved ) {
@@ -1945,9 +1993,9 @@
  *
  * @global wpdb $wpdb WordPress database abstraction object.
  *
- * @param int    $network_id    ID of the network. Can be null to default to the current network ID.
- * @param string $option        Name of the option to retrieve. Expected to not be SQL-escaped.
- * @param mixed  $default_value Optional. Value to return if the option doesn't exist. Default false.
+ * @param int|null $network_id    ID of the network. Can be null to default to the current network ID.
+ * @param string   $option        Name of the option to retrieve. Expected to not be SQL-escaped.
+ * @param mixed    $default_value Optional. Value to return if the option doesn't exist. Default false.
  * @return mixed Value set for the option.
  */
 function get_network_option( $network_id, $option, $default_value = false ) {
@@ -1978,14 +2026,14 @@
 	 * @since 4.7.0 The `$network_id` parameter was added.
 	 * @since 4.9.0 The `$default_value` parameter was added.
 	 *
-	 * @param mixed  $pre_option    The value to return instead of the option value. This differs from
-	 *                              `$default_value`, which is used as the fallback value in the event
-	 *                              the option doesn't exist elsewhere in get_network_option().
-	 *                              Default false (to skip past the short-circuit).
-	 * @param string $option        Option name.
-	 * @param int    $network_id    ID of the network.
-	 * @param mixed  $default_value The fallback value to return if the option does not exist.
-	 *                              Default false.
+	 * @param mixed  $pre_site_option The value to return instead of the option value. This differs from
+	 *                                `$default_value`, which is used as the fallback value in the event
+	 *                                the option doesn't exist elsewhere in get_network_option().
+	 *                                Default false (to skip past the short-circuit).
+	 * @param string $option          Option name.
+	 * @param int    $network_id      ID of the network.
+	 * @param mixed  $default_value   The fallback value to return if the option does not exist.
+	 *                                Default false.
 	 */
 	$pre = apply_filters( "pre_site_option_{$option}", false, $option, $network_id, $default_value );
 
@@ -2079,9 +2127,9 @@
  *
  * @global wpdb $wpdb WordPress database abstraction object.
  *
- * @param int    $network_id ID of the network. Can be null to default to the current network ID.
- * @param string $option     Name of the option to add. Expected to not be SQL-escaped.
- * @param mixed  $value      Option value, can be anything. Expected to not be SQL-escaped.
+ * @param int|null $network_id ID of the network. Can be null to default to the current network ID.
+ * @param string   $option     Name of the option to add. Expected to not be SQL-escaped.
+ * @param mixed    $value      Option value, can be anything. Expected to not be SQL-escaped.
  * @return bool True if the option was added, false otherwise.
  */
 function add_network_option( $network_id, $option, $value ) {
@@ -2206,8 +2254,8 @@
  *
  * @global wpdb $wpdb WordPress database abstraction object.
  *
- * @param int    $network_id ID of the network. Can be null to default to the current network ID.
- * @param string $option     Name of the option to delete. Expected to not be SQL-escaped.
+ * @param int|null $network_id ID of the network. Can be null to default to the current network ID.
+ * @param string   $option     Name of the option to delete. Expected to not be SQL-escaped.
  * @return bool True if the option was deleted, false otherwise.
  */
 function delete_network_option( $network_id, $option ) {
@@ -2255,6 +2303,17 @@
 				'site_id'  => $network_id,
 			)
 		);
+
+		if ( $result ) {
+			$notoptions_key = "$network_id:notoptions";
+			$notoptions     = wp_cache_get( $notoptions_key, 'site-options' );
+
+			if ( ! is_array( $notoptions ) ) {
+				$notoptions = array();
+			}
+			$notoptions[ $option ] = true;
+			wp_cache_set( $notoptions_key, $notoptions, 'site-options' );
+		}
 	}
 
 	if ( $result ) {
@@ -2299,9 +2358,9 @@
  *
  * @global wpdb $wpdb WordPress database abstraction object.
  *
- * @param int    $network_id ID of the network. Can be null to default to the current network ID.
- * @param string $option     Name of the option. Expected to not be SQL-escaped.
- * @param mixed  $value      Option value. Expected to not be SQL-escaped.
+ * @param int|null $network_id ID of the network. Can be null to default to the current network ID.
+ * @param string   $option     Name of the option. Expected to not be SQL-escaped.
+ * @param mixed    $value      Option value. Expected to not be SQL-escaped.
  * @return bool True if the value was updated, false otherwise.
  */
 function update_network_option( $network_id, $option, $value ) {
@@ -2629,13 +2688,25 @@
 		/**
 		 * Fires after the value for a site transient has been set.
 		 *
-		 * @since 3.0.0
+		 * @since 6.8.0
 		 *
 		 * @param string $transient  The name of the site transient.
 		 * @param mixed  $value      Site transient value.
 		 * @param int    $expiration Time until expiration in seconds.
 		 */
-		do_action( 'setted_site_transient', $transient, $value, $expiration );
+		do_action( 'set_site_transient', $transient, $value, $expiration );
+
+		/**
+		 * Fires after the value for a site transient has been set.
+		 *
+		 * @since 3.0.0
+		 * @deprecated 6.8.0 Use {@see 'set_site_transient'} instead.
+		 *
+		 * @param string $transient  The name of the site transient.
+		 * @param mixed  $value      Site transient value.
+		 * @param int    $expiration Time until expiration in seconds.
+		 */
+		do_action_deprecated( 'setted_site_transient', array( $transient, $value, $expiration ), '6.8.0', 'set_site_transient' );
 	}
 
 	return $result;