Merged in feature/81-dev-dev01 (pull request #5)
auto-patch 81-dev-dev01-2023-12-05T22_45_26 * auto-patch 81-dev-dev01-2023-12-05T22_45_26
This commit is contained in:
@@ -161,33 +161,6 @@ function get_option( $option, $default_value = false ) {
|
||||
$passed_default = func_num_args() > 1;
|
||||
|
||||
if ( ! wp_installing() ) {
|
||||
// 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' );
|
||||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
$alloptions = wp_load_alloptions();
|
||||
|
||||
if ( isset( $alloptions[ $option ] ) ) {
|
||||
@@ -196,6 +169,31 @@ function get_option( $option, $default_value = false ) {
|
||||
$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 ) );
|
||||
|
||||
// Has to be get_row() instead of get_var() because of funkiness with 0, false, null values.
|
||||
@@ -203,10 +201,6 @@ function get_option( $option, $default_value = false ) {
|
||||
$value = $row->option_value;
|
||||
wp_cache_add( $option, $value, 'options' );
|
||||
} else { // Option does not exist, so we must cache its non-existence.
|
||||
if ( ! is_array( $notoptions ) ) {
|
||||
$notoptions = array();
|
||||
}
|
||||
|
||||
$notoptions[ $option ] = true;
|
||||
wp_cache_set( 'notoptions', $notoptions, 'options' );
|
||||
|
||||
@@ -253,6 +247,290 @@ function get_option( $option, $default_value = false ) {
|
||||
return apply_filters( "option_{$option}", maybe_unserialize( $value ), $option );
|
||||
}
|
||||
|
||||
/**
|
||||
* Primes specific options into the cache with a single database query.
|
||||
*
|
||||
* Only options that do not already exist in cache will be loaded.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @global wpdb $wpdb WordPress database abstraction object.
|
||||
*
|
||||
* @param array $options An array of option names to be loaded.
|
||||
*/
|
||||
function wp_prime_option_caches( $options ) {
|
||||
$alloptions = wp_load_alloptions();
|
||||
$cached_options = wp_cache_get_multiple( $options, 'options' );
|
||||
$notoptions = wp_cache_get( 'notoptions', 'options' );
|
||||
if ( ! is_array( $notoptions ) ) {
|
||||
$notoptions = array();
|
||||
}
|
||||
|
||||
// Filter options that are not in the cache.
|
||||
$options_to_prime = array();
|
||||
foreach ( $options as $option ) {
|
||||
if (
|
||||
( ! isset( $cached_options[ $option ] ) || false === $cached_options[ $option ] )
|
||||
&& ! isset( $alloptions[ $option ] )
|
||||
&& ! isset( $notoptions[ $option ] )
|
||||
) {
|
||||
$options_to_prime[] = $option;
|
||||
}
|
||||
}
|
||||
|
||||
// Bail early if there are no options to be loaded.
|
||||
if ( empty( $options_to_prime ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
$results = $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
sprintf(
|
||||
"SELECT option_name, option_value FROM $wpdb->options WHERE option_name IN (%s)",
|
||||
implode( ',', array_fill( 0, count( $options_to_prime ), '%s' ) )
|
||||
),
|
||||
$options_to_prime
|
||||
)
|
||||
);
|
||||
|
||||
$options_found = array();
|
||||
foreach ( $results as $result ) {
|
||||
/*
|
||||
* The cache is primed with the raw value (i.e. not maybe_unserialized).
|
||||
*
|
||||
* `get_option()` will handle unserializing the value as needed.
|
||||
*/
|
||||
$options_found[ $result->option_name ] = $result->option_value;
|
||||
}
|
||||
wp_cache_set_multiple( $options_found, 'options' );
|
||||
|
||||
// If all options were found, no need to update `notoptions` cache.
|
||||
if ( count( $options_found ) === count( $options_to_prime ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$options_not_found = array_diff( $options_to_prime, array_keys( $options_found ) );
|
||||
|
||||
// Add the options that were not found to the cache.
|
||||
$update_notoptions = false;
|
||||
foreach ( $options_not_found as $option_name ) {
|
||||
if ( ! isset( $notoptions[ $option_name ] ) ) {
|
||||
$notoptions[ $option_name ] = true;
|
||||
$update_notoptions = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Only update the cache if it was modified.
|
||||
if ( $update_notoptions ) {
|
||||
wp_cache_set( 'notoptions', $notoptions, 'options' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Primes the cache of all options registered with a specific option group.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @global array $new_allowed_options
|
||||
*
|
||||
* @param string $option_group The option group to load options for.
|
||||
*/
|
||||
function wp_prime_option_caches_by_group( $option_group ) {
|
||||
global $new_allowed_options;
|
||||
|
||||
if ( isset( $new_allowed_options[ $option_group ] ) ) {
|
||||
wp_prime_option_caches( $new_allowed_options[ $option_group ] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves multiple options.
|
||||
*
|
||||
* Options are loaded as necessary first in order to use a single database query at most.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @param array $options An array of option names to retrieve.
|
||||
* @return array An array of key-value pairs for the requested options.
|
||||
*/
|
||||
function get_options( $options ) {
|
||||
wp_prime_option_caches( $options );
|
||||
|
||||
$result = array();
|
||||
foreach ( $options as $option ) {
|
||||
$result[ $option ] = get_option( $option );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the autoload values for multiple options in the database.
|
||||
*
|
||||
* Autoloading too many options can lead to performance problems, especially if the options are not frequently used.
|
||||
* This function allows modifying the autoload value for multiple options without changing the actual option value.
|
||||
* This is for example recommended for plugin activation and deactivation hooks, to ensure any options exclusively used
|
||||
* by the plugin which are generally autoloaded can be set to not autoload when the plugin is inactive.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @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.
|
||||
* @return array Associative array of all provided $options as keys and boolean values for whether their autoload value
|
||||
* was updated.
|
||||
*/
|
||||
function wp_set_option_autoload_values( array $options ) {
|
||||
global $wpdb;
|
||||
|
||||
if ( ! $options ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$grouped_options = array(
|
||||
'yes' => array(),
|
||||
'no' => array(),
|
||||
);
|
||||
$results = array();
|
||||
foreach ( $options as $option => $autoload ) {
|
||||
wp_protect_special_option( $option ); // Ensure only valid options can be passed.
|
||||
if ( 'no' === $autoload || false === $autoload ) { // Sanitize autoload value and categorize accordingly.
|
||||
$grouped_options['no'][] = $option;
|
||||
} else {
|
||||
$grouped_options['yes'][] = $option;
|
||||
}
|
||||
$results[ $option ] = false; // Initialize result value.
|
||||
}
|
||||
|
||||
$where = array();
|
||||
$where_args = array();
|
||||
foreach ( $grouped_options as $autoload => $options ) {
|
||||
if ( ! $options ) {
|
||||
continue;
|
||||
}
|
||||
$placeholders = implode( ',', array_fill( 0, count( $options ), '%s' ) );
|
||||
$where[] = "autoload != '%s' AND option_name IN ($placeholders)";
|
||||
$where_args[] = $autoload;
|
||||
foreach ( $options as $option ) {
|
||||
$where_args[] = $option;
|
||||
}
|
||||
}
|
||||
$where = 'WHERE ' . implode( ' OR ', $where );
|
||||
|
||||
/*
|
||||
* Determine the relevant options that do not already use the given autoload value.
|
||||
* If no options are returned, no need to update.
|
||||
*/
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
|
||||
$options_to_update = $wpdb->get_col( $wpdb->prepare( "SELECT option_name FROM $wpdb->options $where", $where_args ) );
|
||||
if ( ! $options_to_update ) {
|
||||
return $results;
|
||||
}
|
||||
|
||||
// Run UPDATE queries as needed (maximum 2) to update the relevant options' autoload values to 'yes' or 'no'.
|
||||
foreach ( $grouped_options as $autoload => $options ) {
|
||||
if ( ! $options ) {
|
||||
continue;
|
||||
}
|
||||
$options = array_intersect( $options, $options_to_update );
|
||||
$grouped_options[ $autoload ] = $options;
|
||||
if ( ! $grouped_options[ $autoload ] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Run query to update autoload value for all the options where it is needed.
|
||||
$success = $wpdb->query(
|
||||
$wpdb->prepare(
|
||||
"UPDATE $wpdb->options SET autoload = %s WHERE option_name IN (" . implode( ',', array_fill( 0, count( $grouped_options[ $autoload ] ), '%s' ) ) . ')',
|
||||
array_merge(
|
||||
array( $autoload ),
|
||||
$grouped_options[ $autoload ]
|
||||
)
|
||||
)
|
||||
);
|
||||
if ( ! $success ) {
|
||||
// Set option list to an empty array to indicate no options were updated.
|
||||
$grouped_options[ $autoload ] = array();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Assume that on success all options were updated, which should be the case given only new values are sent.
|
||||
foreach ( $grouped_options[ $autoload ] as $option ) {
|
||||
$results[ $option ] = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If any options were changed to 'yes', delete their individual caches, and delete 'alloptions' cache so that it
|
||||
* is refreshed as needed.
|
||||
* If no options were changed to 'yes' but any options were changed to 'no', delete them from the 'alloptions'
|
||||
* cache. This is not necessary when options were changed to 'yes', since in that situation the entire cache is
|
||||
* deleted anyway.
|
||||
*/
|
||||
if ( $grouped_options['yes'] ) {
|
||||
wp_cache_delete_multiple( $grouped_options['yes'], 'options' );
|
||||
wp_cache_delete( 'alloptions', 'options' );
|
||||
} elseif ( $grouped_options['no'] ) {
|
||||
$alloptions = wp_load_alloptions( true );
|
||||
foreach ( $grouped_options['no'] as $option ) {
|
||||
if ( isset( $alloptions[ $option ] ) ) {
|
||||
unset( $alloptions[ $option ] );
|
||||
}
|
||||
}
|
||||
wp_cache_set( 'alloptions', $alloptions, 'options' );
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the autoload value for multiple options in the database.
|
||||
*
|
||||
* This is a wrapper for {@see wp_set_option_autoload_values()}, which can be used to set different autoload values for
|
||||
* each option at once.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @see wp_set_option_autoload_values()
|
||||
*
|
||||
* @param array $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.
|
||||
* @return array Associative array of all provided $options as keys and boolean values for whether their autoload value
|
||||
* was updated.
|
||||
*/
|
||||
function wp_set_options_autoload( array $options, $autoload ) {
|
||||
return wp_set_option_autoload_values(
|
||||
array_fill_keys( $options, $autoload )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the autoload value for an option in the database.
|
||||
*
|
||||
* This is a wrapper for {@see wp_set_option_autoload_values()}, which can be used to set the autoload value for
|
||||
* multiple options at once.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @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.
|
||||
* @return bool True if the autoload value was modified, false otherwise.
|
||||
*/
|
||||
function wp_set_option_autoload( $option, $autoload ) {
|
||||
$result = wp_set_option_autoload_values( array( $option => $autoload ) );
|
||||
if ( isset( $result[ $option ] ) ) {
|
||||
return $result[ $option ];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Protects WordPress special option from being modified.
|
||||
*
|
||||
@@ -428,8 +706,13 @@ function wp_load_core_site_options( $network_id = null ) {
|
||||
* @param mixed $value Option value. Must be serializable if non-scalar. Expected to not be SQL-escaped.
|
||||
* @param string|bool $autoload Optional. Whether to load the option when WordPress starts up. For existing options,
|
||||
* `$autoload` can only be updated using `update_option()` if `$value` is also changed.
|
||||
* Accepts 'yes'|true to enable or 'no'|false to disable. For non-existent options,
|
||||
* the default value is 'yes'. Default null.
|
||||
* Accepts 'yes'|true to enable or 'no'|false to disable.
|
||||
* 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.
|
||||
* For options which are accessed only on few specific URLs, it is recommended
|
||||
* to not autoload them, by using 'no'|false. For non-existent options, the default value
|
||||
* is 'yes'. Default null.
|
||||
* @return bool True if the value was updated, false otherwise.
|
||||
*/
|
||||
function update_option( $option, $value, $autoload = null ) {
|
||||
@@ -557,11 +840,30 @@ function update_option( $option, $value, $autoload = null ) {
|
||||
}
|
||||
|
||||
if ( ! wp_installing() ) {
|
||||
$alloptions = wp_load_alloptions( true );
|
||||
if ( isset( $alloptions[ $option ] ) ) {
|
||||
if ( ! isset( $update_args['autoload'] ) ) {
|
||||
// Update the cached value based on where it is currently cached.
|
||||
$alloptions = wp_load_alloptions( true );
|
||||
if ( isset( $alloptions[ $option ] ) ) {
|
||||
$alloptions[ $option ] = $serialized_value;
|
||||
wp_cache_set( 'alloptions', $alloptions, 'options' );
|
||||
} else {
|
||||
wp_cache_set( $option, $serialized_value, 'options' );
|
||||
}
|
||||
} elseif ( 'yes' === $update_args['autoload'] ) {
|
||||
// Delete the individual cache, then set in alloptions cache.
|
||||
wp_cache_delete( $option, 'options' );
|
||||
|
||||
$alloptions = wp_load_alloptions( true );
|
||||
$alloptions[ $option ] = $serialized_value;
|
||||
wp_cache_set( 'alloptions', $alloptions, 'options' );
|
||||
} else {
|
||||
// Delete the alloptions cache, then set the individual cache.
|
||||
$alloptions = wp_load_alloptions( true );
|
||||
if ( isset( $alloptions[ $option ] ) ) {
|
||||
unset( $alloptions[ $option ] );
|
||||
wp_cache_set( 'alloptions', $alloptions, 'options' );
|
||||
}
|
||||
|
||||
wp_cache_set( $option, $serialized_value, 'options' );
|
||||
}
|
||||
}
|
||||
@@ -615,7 +917,12 @@ function update_option( $option, $value, $autoload = null ) {
|
||||
* Expected to not be SQL-escaped.
|
||||
* @param string $deprecated Optional. Description. Not used anymore.
|
||||
* @param string|bool $autoload Optional. Whether to load the option when WordPress starts up.
|
||||
* Default is enabled. Accepts 'no' to disable for legacy reasons.
|
||||
* Accepts 'yes'|true to enable or 'no'|false to disable.
|
||||
* 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.
|
||||
* For options which are accessed only on few specific URLs, it is recommended
|
||||
* to not autoload them, by using 'no'|false. Default 'yes'.
|
||||
* @return bool True if the option was added, false otherwise.
|
||||
*/
|
||||
function add_option( $option, $value = '', $deprecated = '', $autoload = 'yes' ) {
|
||||
@@ -1151,7 +1458,7 @@ function wp_user_settings() {
|
||||
$cookie = preg_replace( '/[^A-Za-z0-9=&_]/', '', $_COOKIE[ 'wp-settings-' . $user_id ] );
|
||||
|
||||
// No change or both empty.
|
||||
if ( $cookie == $settings ) {
|
||||
if ( $cookie === $settings ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1799,7 +2106,7 @@ function update_network_option( $network_id, $option, $value ) {
|
||||
|
||||
wp_protect_special_option( $option );
|
||||
|
||||
$old_value = get_network_option( $network_id, $option, false );
|
||||
$old_value = get_network_option( $network_id, $option );
|
||||
|
||||
/**
|
||||
* Filters a specific network option before its value is updated.
|
||||
@@ -2517,7 +2824,10 @@ function unregister_setting( $option_group, $option_name, $deprecated = '' ) {
|
||||
$option_group = 'reading';
|
||||
}
|
||||
|
||||
$pos = array_search( $option_name, (array) $new_allowed_options[ $option_group ], true );
|
||||
$pos = false;
|
||||
if ( isset( $new_allowed_options[ $option_group ] ) ) {
|
||||
$pos = array_search( $option_name, (array) $new_allowed_options[ $option_group ], true );
|
||||
}
|
||||
|
||||
if ( false !== $pos ) {
|
||||
unset( $new_allowed_options[ $option_group ][ $pos ] );
|
||||
|
||||
Reference in New Issue
Block a user