From 67fd6e281f05c942467b7765f19b4472a5969bd5 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Thu, 12 Sep 2019 22:17:55 +0000 Subject: [PATCH] Multisite: improve `sites_pre_query` and `networks_pre_query` filters, avoiding db queries. Improve the `pre_query` filters in multisite classes introduced in r44983. Return (non null) values immediately, avoiding the database queries entirely, similar to other `pre_query` filters. Props spacedmonkey, SergeyBiryukov, felipeelia. Fixes #47599. Built from https://develop.svn.wordpress.org/trunk@46100 git-svn-id: http://core.svn.wordpress.org/trunk@45912 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/class-wp-network-query.php | 67 ++++++++++++++------------ wp-includes/class-wp-site-query.php | 65 ++++++++++++++----------- wp-includes/version.php | 2 +- 3 files changed, 74 insertions(+), 60 deletions(-) diff --git a/wp-includes/class-wp-network-query.php b/wp-includes/class-wp-network-query.php index 9db0a60462..a12656c702 100644 --- a/wp-includes/class-wp-network-query.php +++ b/wp-includes/class-wp-network-query.php @@ -197,50 +197,57 @@ class WP_Network_Query { */ do_action_ref_array( 'pre_get_networks', array( &$this ) ); - $network_ids = null; + $network_data = null; /** - * Filter the sites array before the query takes place. + * Filter the network data before the query takes place. * - * Return a non-null value to bypass WordPress's default site queries. + * Return a non-null value to bypass WordPress's default network queries. + * + * The expected return type from this filter depends on the value passed in the request query_vars. + * When `$this->query_vars['count']` is set, the filter should return the network count as an int. + * When `'ids' === $this->query_vars['fields']`, the filter should return an array of network ids. + * Otherwise the filter should return an array of WP_Network objects. * * @since 5.2.0 * - * @param array|null $site_ids Return an array of site data to short-circuit WP's site query, - * or null to allow WP to run its normal queries. - * @param WP_Network_Query $this The WP_Network_Query instance, passed by reference. + * @param array|null $network_data Return an array of network data to short-circuit WP's network query, + * the network count as an integer if `$this->query_vars['count']` is set, + * or null to allow WP to run its normal queries. + * @param WP_Network_Query $this The WP_Network_Query instance, passed by reference. */ - $network_ids = apply_filters_ref_array( 'networks_pre_query', array( $network_ids, &$this ) ); + $network_data = apply_filters_ref_array( 'networks_pre_query', array( $network_data, &$this ) ); - if ( null === $network_ids ) { + if ( null !== $network_data ) { + return $network_data; + } - // $args can include anything. Only use the args defined in the query_var_defaults to compute the key. - $_args = wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) ); + // $args can include anything. Only use the args defined in the query_var_defaults to compute the key. + $_args = wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) ); - // Ignore the $fields argument as the queried result will be the same regardless. - unset( $_args['fields'] ); + // Ignore the $fields argument as the queried result will be the same regardless. + unset( $_args['fields'] ); - $key = md5( serialize( $_args ) ); - $last_changed = wp_cache_get_last_changed( 'networks' ); + $key = md5( serialize( $_args ) ); + $last_changed = wp_cache_get_last_changed( 'networks' ); - $cache_key = "get_network_ids:$key:$last_changed"; - $cache_value = wp_cache_get( $cache_key, 'networks' ); + $cache_key = "get_network_ids:$key:$last_changed"; + $cache_value = wp_cache_get( $cache_key, 'networks' ); - if ( false === $cache_value ) { - $network_ids = $this->get_network_ids(); - if ( $network_ids ) { - $this->set_found_networks(); - } - - $cache_value = array( - 'network_ids' => $network_ids, - 'found_networks' => $this->found_networks, - ); - wp_cache_add( $cache_key, $cache_value, 'networks' ); - } else { - $network_ids = $cache_value['network_ids']; - $this->found_networks = $cache_value['found_networks']; + if ( false === $cache_value ) { + $network_ids = $this->get_network_ids(); + if ( $network_ids ) { + $this->set_found_networks(); } + + $cache_value = array( + 'network_ids' => $network_ids, + 'found_networks' => $this->found_networks, + ); + wp_cache_add( $cache_key, $cache_value, 'networks' ); + } else { + $network_ids = $cache_value['network_ids']; + $this->found_networks = $cache_value['found_networks']; } if ( $this->found_networks && $this->query_vars['number'] ) { diff --git a/wp-includes/class-wp-site-query.php b/wp-includes/class-wp-site-query.php index ec42cde2d2..64b139dbbf 100644 --- a/wp-includes/class-wp-site-query.php +++ b/wp-includes/class-wp-site-query.php @@ -288,50 +288,57 @@ class WP_Site_Query { $this->meta_query_clauses = $this->meta_query->get_sql( 'blog', $wpdb->blogs, 'blog_id', $this ); } - $site_ids = null; + $site_data = null; /** - * Filter the sites array before the query takes place. + * Filter the site data before the get_sites query takes place. * * Return a non-null value to bypass WordPress's default site queries. * + * The expected return type from this filter depends on the value passed in the request query_vars: + * When `$this->query_vars['count']` is set, the filter should return the site count as an int. + * When `'ids' == $this->query_vars['fields']`, the filter should return an array of site ids. + * Otherwise the filter should return an array of WP_Site objects. + * * @since 5.2.0 * - * @param array|null $site_ids Return an array of site data to short-circuit WP's site query, - * or null to allow WP to run its normal queries. - * @param WP_Site_Query $this The WP_Site_Query instance, passed by reference. + * @param array|int|null $site_data Return an array of site data to short-circuit WP's site query, + * the site count as an integer if `$this->query_vars['count']` is set, + * or null to run the normal queries. + * @param WP_Site_Query $this The WP_Site_Query instance, passed by reference. */ - $site_ids = apply_filters_ref_array( 'sites_pre_query', array( $site_ids, &$this ) ); + $site_data = apply_filters_ref_array( 'sites_pre_query', array( $site_data, &$this ) ); - if ( null === $site_ids ) { + if ( null !== $site_data ) { + return $site_data; + } - // $args can include anything. Only use the args defined in the query_var_defaults to compute the key. - $_args = wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) ); + // $args can include anything. Only use the args defined in the query_var_defaults to compute the key. + $_args = wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) ); - // Ignore the $fields argument as the queried result will be the same regardless. - unset( $_args['fields'] ); + // Ignore the $fields argument as the queried result will be the same regardless. + unset( $_args['fields'] ); - $key = md5( serialize( $_args ) ); - $last_changed = wp_cache_get_last_changed( 'sites' ); + $key = md5( serialize( $_args ) ); + $last_changed = wp_cache_get_last_changed( 'sites' ); - $cache_key = "get_sites:$key:$last_changed"; - $cache_value = wp_cache_get( $cache_key, 'sites' ); + $cache_key = "get_sites:$key:$last_changed"; + $cache_value = wp_cache_get( $cache_key, 'sites' ); - if ( false === $cache_value ) { - $site_ids = $this->get_site_ids(); - if ( $site_ids ) { - $this->set_found_sites(); - } - - $cache_value = array( - 'site_ids' => $site_ids, - 'found_sites' => $this->found_sites, - ); - wp_cache_add( $cache_key, $cache_value, 'sites' ); - } else { - $site_ids = $cache_value['site_ids']; - $this->found_sites = $cache_value['found_sites']; + if ( false === $cache_value ) { + $site_ids = $this->get_site_ids(); + if ( $site_ids ) { + $this->set_found_sites(); } + + $cache_value = array( + 'site_ids' => $site_ids, + 'found_sites' => $this->found_sites, + ); + wp_cache_add( $cache_key, $cache_value, 'sites' ); + } else { + $site_ids = $cache_value['site_ids']; + $this->found_sites = $cache_value['found_sites']; } if ( $this->found_sites && $this->query_vars['number'] ) { diff --git a/wp-includes/version.php b/wp-includes/version.php index 3a37e57857..de471f5a03 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -13,7 +13,7 @@ * * @global string $wp_version */ -$wp_version = '5.3-alpha-46099'; +$wp_version = '5.3-alpha-46100'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.