mirror of
https://github.com/WordPress/WordPress.git
synced 2025-02-16 11:35:48 +00:00
Options, Meta APIs: Introduce wp_prime_network_option_caches() to load multiple network options with a single database request.
WordPress's `get_network_option` function generally makes individual database requests for each network option. While some options are preloaded in `wp_load_core_site_options`, many still require single database calls to the network options table. Building on the work done in [56445], [56990], and [57013], which introduced the `wp_prime_option_caches` function, this commit adds two new functions: `wp_prime_network_option_caches` and `wp_prime_site_option_caches`. These functions enable developers to pass an array of option names, allowing caches for these options to be primed in a single object cache or database request. If an option is not found, the notoptions cache key is refreshed, preventing unnecessary repeated requests. The function `wp_prime_site_option_caches` is similar to `get_site_option`, enabling developers to retrieve network options on the current network without needing to know the current network ID. If these functions are called in a non-multisite environment, they fall back to using wp_prime_option_caches. These functions have been implemented in `wp_load_core_site_options`, `get_site_transient`, and `set_site_transient`. Props to spacedmonkey, peterwilsoncc, mukesh27, joemcgill. Fixes #61053. Built from https://develop.svn.wordpress.org/trunk@58182 git-svn-id: http://core.svn.wordpress.org/trunk@57645 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
b6b5ffbf9f
commit
0775b69427
@ -642,51 +642,151 @@ function wp_load_alloptions( $force_cache = false ) {
|
||||
return apply_filters( 'alloptions', $alloptions );
|
||||
}
|
||||
|
||||
/**
|
||||
* Primes specific network options for the current network into the cache with a single database query.
|
||||
*
|
||||
* Only network options that do not already exist in cache will be loaded.
|
||||
*
|
||||
* If site is not multisite, then call wp_prime_option_caches().
|
||||
*
|
||||
* @since 6.6.0
|
||||
*
|
||||
* @see wp_prime_network_option_caches()
|
||||
*
|
||||
* @param string[] $options An array of option names to be loaded.
|
||||
*/
|
||||
function wp_prime_site_option_caches( array $options ) {
|
||||
wp_prime_network_option_caches( null, $options );
|
||||
}
|
||||
|
||||
/**
|
||||
* Primes specific network options into the cache with a single database query.
|
||||
*
|
||||
* Only network options that do not already exist in cache will be loaded.
|
||||
*
|
||||
* If site is not multisite, then call wp_prime_option_caches().
|
||||
*
|
||||
* @since 6.6.0
|
||||
*
|
||||
* @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[] $options An array of option names to be loaded.
|
||||
*/
|
||||
function wp_prime_network_option_caches( $network_id, array $options ) {
|
||||
global $wpdb;
|
||||
|
||||
if ( wp_installing() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! is_multisite() ) {
|
||||
wp_prime_option_caches( $options );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $network_id && ! is_numeric( $network_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$network_id = (int) $network_id;
|
||||
|
||||
// Fallback to the current network if a network ID is not specified.
|
||||
if ( ! $network_id ) {
|
||||
$network_id = get_current_network_id();
|
||||
}
|
||||
|
||||
$cache_keys = array();
|
||||
foreach ( $options as $option ) {
|
||||
$cache_keys[ $option ] = "{$network_id}:{$option}";
|
||||
}
|
||||
|
||||
$cache_group = 'site-options';
|
||||
$cached_options = wp_cache_get_multiple( array_values( $cache_keys ), $cache_group );
|
||||
|
||||
$notoptions_key = "$network_id:notoptions";
|
||||
$notoptions = wp_cache_get( $notoptions_key, $cache_group );
|
||||
|
||||
if ( ! is_array( $notoptions ) ) {
|
||||
$notoptions = array();
|
||||
}
|
||||
|
||||
// Filter options that are not in the cache.
|
||||
$options_to_prime = array();
|
||||
foreach ( $cache_keys as $option => $cache_key ) {
|
||||
if (
|
||||
( ! isset( $cached_options[ $cache_key ] ) || false === $cached_options[ $cache_key ] )
|
||||
&& ! isset( $notoptions[ $option ] )
|
||||
) {
|
||||
$options_to_prime[] = $option;
|
||||
}
|
||||
}
|
||||
|
||||
// Bail early if there are no options to be loaded.
|
||||
if ( empty( $options_to_prime ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$query_args = $options_to_prime;
|
||||
$query_args[] = $network_id;
|
||||
$results = $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
sprintf(
|
||||
"SELECT meta_key, meta_value FROM $wpdb->sitemeta WHERE meta_key IN (%s) AND site_id = %s",
|
||||
implode( ',', array_fill( 0, count( $options_to_prime ), '%s' ) ),
|
||||
'%d'
|
||||
),
|
||||
$query_args
|
||||
)
|
||||
);
|
||||
|
||||
$data = array();
|
||||
$options_found = array();
|
||||
foreach ( $results as $result ) {
|
||||
$key = $result->meta_key;
|
||||
$cache_key = $cache_keys[ $key ];
|
||||
$data[ $cache_key ] = maybe_unserialize( $result->meta_value );
|
||||
$options_found[] = $key;
|
||||
}
|
||||
wp_cache_set_multiple( $data, $cache_group );
|
||||
// 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, $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_key, $notoptions, $cache_group );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads and primes caches of certain often requested network options if is_multisite().
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @since 6.3.0 Also prime caches for network options when persistent object cache is enabled.
|
||||
*
|
||||
* @global wpdb $wpdb WordPress database abstraction object.
|
||||
* @since 6.6.0 Uses wp_prime_network_option_caches().
|
||||
*
|
||||
* @param int $network_id Optional. Network ID of network for which to prime network options cache. Defaults to current network.
|
||||
*/
|
||||
function wp_load_core_site_options( $network_id = null ) {
|
||||
global $wpdb;
|
||||
|
||||
if ( ! is_multisite() || wp_installing() ) {
|
||||
return;
|
||||
}
|
||||
$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', 'WPLANG' );
|
||||
|
||||
if ( empty( $network_id ) ) {
|
||||
$network_id = get_current_network_id();
|
||||
}
|
||||
|
||||
$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' );
|
||||
|
||||
if ( wp_using_ext_object_cache() ) {
|
||||
$cache_keys = array();
|
||||
foreach ( $core_options as $option ) {
|
||||
$cache_keys[] = "{$network_id}:{$option}";
|
||||
}
|
||||
wp_cache_get_multiple( $cache_keys, 'site-options' );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$core_options_in = "'" . implode( "', '", $core_options ) . "'";
|
||||
$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 ) );
|
||||
|
||||
$data = array();
|
||||
foreach ( $options as $option ) {
|
||||
$key = $option->meta_key;
|
||||
$cache_key = "{$network_id}:$key";
|
||||
$option->meta_value = maybe_unserialize( $option->meta_value );
|
||||
|
||||
$data[ $cache_key ] = $option->meta_value;
|
||||
}
|
||||
wp_cache_set_multiple( $data, 'site-options' );
|
||||
wp_prime_network_option_caches( $network_id, $core_options );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2415,7 +2515,9 @@ function get_site_transient( $transient ) {
|
||||
$transient_option = '_site_transient_' . $transient;
|
||||
if ( ! in_array( $transient, $no_timeout, true ) ) {
|
||||
$transient_timeout = '_site_transient_timeout_' . $transient;
|
||||
$timeout = get_site_option( $transient_timeout );
|
||||
wp_prime_site_option_caches( array( $transient_option, $transient_timeout ) );
|
||||
|
||||
$timeout = get_site_option( $transient_timeout );
|
||||
if ( false !== $timeout && $timeout < time() ) {
|
||||
delete_site_option( $transient_option );
|
||||
delete_site_option( $transient_timeout );
|
||||
@ -2493,6 +2595,7 @@ function set_site_transient( $transient, $value, $expiration = 0 ) {
|
||||
} else {
|
||||
$transient_timeout = '_site_transient_timeout_' . $transient;
|
||||
$option = '_site_transient_' . $transient;
|
||||
wp_prime_site_option_caches( array( $option, $transient_timeout ) );
|
||||
|
||||
if ( false === get_site_option( $option ) ) {
|
||||
if ( $expiration ) {
|
||||
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
* @global string $wp_version
|
||||
*/
|
||||
$wp_version = '6.6-alpha-58181';
|
||||
$wp_version = '6.6-alpha-58182';
|
||||
|
||||
/**
|
||||
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
||||
|
Loading…
x
Reference in New Issue
Block a user