Ticket #45749: 45749.8.diff
| File 45749.8.diff, 17.5 KB (added by , 7 years ago) |
|---|
-
src/wp-includes/class-wp-network-query.php
diff --git src/wp-includes/class-wp-network-query.php src/wp-includes/class-wp-network-query.php index d381e60117..c245660b88 100644
2 2 /** 3 3 * Network API: WP_Network_Query class 4 4 * 5 * @package WordPress5 * @package WordPress 6 6 * @subpackage Multisite 7 * @since 4.6.07 * @since 4.6.0 8 8 */ 9 9 10 10 /** … … 12 12 * 13 13 * @since 4.6.0 14 14 * 15 * @see WP_Network_Query::__construct() for accepted arguments.15 * @see WP_Network_Query::__construct() for accepted arguments. 16 16 */ 17 17 class WP_Network_Query { 18 18 … … class WP_Network_Query { 63 63 */ 64 64 public $networks; 65 65 66 /** 67 * List of network ids in the query. 68 * 69 * @since 5.2.0 70 * @var array|null 71 */ 72 public $network_ids = null; 73 66 74 /** 67 75 * The amount of found networks for the current query. 68 76 * … … class WP_Network_Query { 86 94 * 87 95 * @since 4.6.0 88 96 * 89 * @param string|array $query {90 * Optional. Array or query string of network query parameters. Default empty.97 * @param string|array $query { 98 * Optional. Array or query string of network query parameters. Default empty. 91 99 * 92 * @type array$network__in Array of network IDs to include. Default empty.93 * @type array$network__not_in Array of network IDs to exclude. Default empty.94 * @type bool$count Whether to return a network count (true) or array of network objects.100 * @type array $network__in Array of network IDs to include. Default empty. 101 * @type array $network__not_in Array of network IDs to exclude. Default empty. 102 * @type bool $count Whether to return a network count (true) or array of network objects. 95 103 * Default false. 96 * @type string$fields Network fields to return. Accepts 'ids' (returns an array of network IDs)104 * @type string $fields Network fields to return. Accepts 'ids' (returns an array of network IDs) 97 105 * or empty (returns an array of complete network objects). Default empty. 98 * @type int$number Maximum number of networks to retrieve. Default empty (no limit).99 * @type int$offset Number of networks to offset the query. Used to build LIMIT clause.106 * @type int $number Maximum number of networks to retrieve. Default empty (no limit). 107 * @type int $offset Number of networks to offset the query. Used to build LIMIT clause. 100 108 * Default 0. 101 * @type bool$no_found_rows Whether to disable the `SQL_CALC_FOUND_ROWS` query. Default true.102 * @type string|array$orderby Network status or array of statuses. Accepts 'id', 'domain', 'path',109 * @type bool $no_found_rows Whether to disable the `SQL_CALC_FOUND_ROWS` query. Default true. 110 * @type string|array $orderby Network status or array of statuses. Accepts 'id', 'domain', 'path', 103 111 * 'domain_length', 'path_length' and 'network__in'. Also accepts false, 104 112 * an empty array, or 'none' to disable `ORDER BY` clause. Default 'id'. 105 * @type string$order How to order retrieved networks. Accepts 'ASC', 'DESC'. Default 'ASC'.106 * @type string$domain Limit results to those affiliated with a given domain. Default empty.107 * @type array$domain__in Array of domains to include affiliated networks for. Default empty.108 * @type array$domain__not_in Array of domains to exclude affiliated networks for. Default empty.109 * @type string$path Limit results to those affiliated with a given path. Default empty.110 * @type array$path__in Array of paths to include affiliated networks for. Default empty.111 * @type array$path__not_in Array of paths to exclude affiliated networks for. Default empty.112 * @type string$search Search term(s) to retrieve matching networks for. Default empty.113 * @type bool$update_network_cache Whether to prime the cache for found networks. Default true.113 * @type string $order How to order retrieved networks. Accepts 'ASC', 'DESC'. Default 'ASC'. 114 * @type string $domain Limit results to those affiliated with a given domain. Default empty. 115 * @type array $domain__in Array of domains to include affiliated networks for. Default empty. 116 * @type array $domain__not_in Array of domains to exclude affiliated networks for. Default empty. 117 * @type string $path Limit results to those affiliated with a given path. Default empty. 118 * @type array $path__in Array of paths to include affiliated networks for. Default empty. 119 * @type array $path__not_in Array of paths to exclude affiliated networks for. Default empty. 120 * @type string $search Search term(s) to retrieve matching networks for. Default empty. 121 * @type bool $update_network_cache Whether to prime the cache for found networks. Default true. 114 122 * } 115 123 */ 116 124 public function __construct( $query = '' ) { … … class WP_Network_Query { 169 177 * @since 4.6.0 170 178 * 171 179 * @param string|array $query Array or URL query string of parameters. 180 * 172 181 * @return array|int List of WP_Network objects, a list of network ids when 'fields' is set to 'ids', 173 182 * or the number of networks when 'count' is passed as a query var. 174 183 */ 175 184 public function query( $query ) { 176 185 $this->query_vars = wp_parse_args( $query ); 186 177 187 return $this->get_networks(); 178 188 } 179 189 … … class WP_Network_Query { 197 207 */ 198 208 do_action_ref_array( 'pre_get_networks', array( &$this ) ); 199 209 200 // $args can include anything. Only use the args defined in the query_var_defaults to compute the key. 201 $_args = wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) ); 210 /** 211 * Filter the sites array before the query takes place. 212 * 213 * Return a non-null value to bypass WordPress's default site queries. 214 * 215 * 216 * @since 5.2.0 217 * 218 * @param array|null $site_ids Return an array of site data to short-circuit WP's site query, 219 * or null to allow WP to run its normal queries. 220 * @param WP_Network_Query $this The WP_Network_Query instance, passed by reference. 221 */ 222 $this->network_ids = apply_filters_ref_array( 'networks_pre_query', array( $this->network_ids, &$this ) ); 202 223 203 // Ignore the $fields argument as the queried result will be the same regardless. 204 unset( $_args['fields'] ); 224 if ( null === $this->network_ids ) { 205 225 206 $key = md5( serialize( $_args ) );207 $last_changed = wp_cache_get_last_changed( 'networks');226 // $args can include anything. Only use the args defined in the query_var_defaults to compute the key. 227 $_args = wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) ); 208 228 209 $cache_key = "get_network_ids:$key:$last_changed";210 $cache_value = wp_cache_get( $cache_key, 'networks');229 // Ignore the $fields argument as the queried result will be the same regardless. 230 unset( $_args['fields'] ); 211 231 212 if ( false === $cache_value ) { 213 $network_ids = $this->get_network_ids(); 214 if ( $network_ids ) { 215 $this->set_found_networks(); 216 } 232 $key = md5( serialize( $_args ) ); 233 $last_changed = wp_cache_get_last_changed( 'networks' ); 217 234 218 $cache_value = array( 219 'network_ids' => $network_ids, 220 'found_networks' => $this->found_networks, 221 ); 222 wp_cache_add( $cache_key, $cache_value, 'networks' ); 223 } else { 224 $network_ids = $cache_value['network_ids']; 225 $this->found_networks = $cache_value['found_networks']; 235 $cache_key = "get_network_ids:$key:$last_changed"; 236 $cache_value = wp_cache_get( $cache_key, 'networks' ); 237 238 if ( false === $cache_value ) { 239 $this->network_ids = $this->get_network_ids(); 240 if ( $this->network_ids ) { 241 $this->set_found_networks(); 242 } 243 244 $cache_value = array( 245 'network_ids' => $this->network_ids, 246 'found_networks' => $this->found_networks, 247 ); 248 wp_cache_add( $cache_key, $cache_value, 'networks' ); 249 } else { 250 $this->network_ids = $cache_value['network_ids']; 251 $this->found_networks = $cache_value['found_networks']; 252 } 226 253 } 227 254 228 255 if ( $this->found_networks && $this->query_vars['number'] ) { … … class WP_Network_Query { 232 259 // If querying for a count only, there's nothing more to do. 233 260 if ( $this->query_vars['count'] ) { 234 261 // $network_ids is actually a count in this case. 235 return intval( $ network_ids );262 return intval( $this->network_ids ); 236 263 } 237 264 238 $ network_ids = array_map( 'intval', $network_ids );265 $this->network_ids = array_map( 'intval', $this->network_ids ); 239 266 240 267 if ( 'ids' == $this->query_vars['fields'] ) { 241 $this->networks = $network_ids; 268 $this->networks = $this->network_ids; 269 242 270 return $this->networks; 243 271 } 244 272 245 273 if ( $this->query_vars['update_network_cache'] ) { 246 _prime_network_caches( $ network_ids );274 _prime_network_caches( $this->network_ids ); 247 275 } 248 276 249 277 // Fetch full network objects from the primed cache. 250 278 $_networks = array(); 251 foreach ( $ network_ids as $network_id ) {279 foreach ( $this->network_ids as $network_id ) { 252 280 if ( $_network = get_network( $network_id ) ) { 253 281 $_networks[] = $_network; 254 282 } … … class WP_Network_Query { 479 507 * 480 508 * @since 4.6.0 481 509 * 482 * @global wpdb $wpdbWordPress database abstraction object.510 * @global wpdb $wpdb WordPress database abstraction object. 483 511 * 484 512 * @param string $string Search string. 485 513 * @param string[] $columns Array of columns to search. … … class WP_Network_Query { 504 532 * 505 533 * @since 4.6.0 506 534 * 507 * @global wpdb $wpdbWordPress database abstraction object.535 * @global wpdb $wpdb WordPress database abstraction object. 508 536 * 509 537 * @param string $orderby Alias for the field to order by. 538 * 510 539 * @return string|false Value to used in the ORDER clause. False otherwise. 511 540 */ 512 541 protected function parse_orderby( $orderby ) { … … class WP_Network_Query { 538 567 * @since 4.6.0 539 568 * 540 569 * @param string $order The 'order' query variable. 570 * 541 571 * @return string The sanitized 'order' query variable. 542 572 */ 543 573 protected function parse_order( $order ) { -
src/wp-includes/class-wp-site-query.php
diff --git src/wp-includes/class-wp-site-query.php src/wp-includes/class-wp-site-query.php index bc3e3519a3..88337ff823 100644
class WP_Site_Query { 87 87 */ 88 88 public $sites; 89 89 90 /** 91 * List of site ids in the query. 92 * 93 * @since 5.2.0 94 * @var array|null 95 */ 96 public $site_ids = null; 97 90 98 /** 91 99 * The amount of found sites for the current query. 92 100 * … … class WP_Site_Query { 288 296 $this->meta_query_clauses = $this->meta_query->get_sql( 'blog', $wpdb->blogs, 'blog_id', $this ); 289 297 } 290 298 291 // $args can include anything. Only use the args defined in the query_var_defaults to compute the key. 292 $_args = wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) ); 299 /** 300 * Filter the sites array before the query takes place. 301 * 302 * Return a non-null value to bypass WordPress's default site queries. 303 * 304 * 305 * @since 5.2.0 306 * 307 * @param array|null $site_ids Return an array of site data to short-circuit WP's site query, 308 * or null to allow WP to run its normal queries. 309 * @param WP_Site_Query $this The WP_Site_Query instance, passed by reference. 310 */ 311 $this->site_ids = apply_filters_ref_array( 'sites_pre_query', array( $this->site_ids, &$this ) ); 293 312 294 // Ignore the $fields argument as the queried result will be the same regardless. 295 unset( $_args['fields'] ); 313 if ( null === $this->site_ids ) { 296 314 297 $key = md5( serialize( $_args ) );298 $last_changed = wp_cache_get_last_changed( 'sites');315 // $args can include anything. Only use the args defined in the query_var_defaults to compute the key. 316 $_args = wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) ); 299 317 300 $cache_key = "get_sites:$key:$last_changed";301 $cache_value = wp_cache_get( $cache_key, 'sites');318 // Ignore the $fields argument as the queried result will be the same regardless. 319 unset( $_args['fields'] ); 302 320 303 if ( false === $cache_value ) { 304 $site_ids = $this->get_site_ids(); 305 if ( $site_ids ) { 306 $this->set_found_sites(); 307 } 321 $key = md5( serialize( $_args ) ); 322 $last_changed = wp_cache_get_last_changed( 'sites' ); 308 323 309 $cache_value = array( 310 'site_ids' => $site_ids, 311 'found_sites' => $this->found_sites, 312 ); 313 wp_cache_add( $cache_key, $cache_value, 'sites' ); 314 } else { 315 $site_ids = $cache_value['site_ids']; 316 $this->found_sites = $cache_value['found_sites']; 324 $cache_key = "get_sites:$key:$last_changed"; 325 $cache_value = wp_cache_get( $cache_key, 'sites' ); 326 327 if ( false === $cache_value ) { 328 $this->site_ids = $this->get_site_ids(); 329 if ( $this->site_ids ) { 330 $this->set_found_sites(); 331 } 332 333 $cache_value = array( 334 'site_ids' => $this->site_ids, 335 'found_sites' => $this->found_sites, 336 ); 337 wp_cache_add( $cache_key, $cache_value, 'sites' ); 338 } else { 339 $this->site_ids = $cache_value['site_ids']; 340 $this->found_sites = $cache_value['found_sites']; 341 } 317 342 } 318 343 319 344 if ( $this->found_sites && $this->query_vars['number'] ) { … … class WP_Site_Query { 323 348 // If querying for a count only, there's nothing more to do. 324 349 if ( $this->query_vars['count'] ) { 325 350 // $site_ids is actually a count in this case. 326 return intval( $ site_ids );351 return intval( $this->site_ids ); 327 352 } 328 353 329 $ site_ids = array_map( 'intval', $site_ids );354 $this->site_ids = array_map( 'intval', $this->site_ids ); 330 355 331 356 if ( 'ids' == $this->query_vars['fields'] ) { 332 $this->sites = $ site_ids;357 $this->sites = $this->site_ids; 333 358 334 359 return $this->sites; 335 360 } 336 361 337 362 // Prime site network caches. 338 363 if ( $this->query_vars['update_site_cache'] ) { 339 _prime_site_caches( $ site_ids, $this->query_vars['update_site_meta_cache'] );364 _prime_site_caches( $this->site_ids, $this->query_vars['update_site_meta_cache'] ); 340 365 } 341 366 342 367 // Fetch full site objects from the primed cache. 343 368 $_sites = array(); 344 foreach ( $ site_ids as $site_id ) {369 foreach ( $this->site_ids as $site_id ) { 345 370 if ( $_site = get_site( $site_id ) ) { 346 371 $_sites[] = $_site; 347 372 } -
tests/phpunit/tests/multisite/networkQuery.php
diff --git tests/phpunit/tests/multisite/networkQuery.php tests/phpunit/tests/multisite/networkQuery.php index 6ec7f16c42..0b48fdc8d5 100644
if ( is_multisite() ) : 522 522 ); 523 523 $this->assertEquals( $number_of_queries + 1, $wpdb->num_queries ); 524 524 } 525 526 /** 527 * @ticket 45749 528 */ 529 public function test_networks_pre_query_filter_should_bypass_database_query() { 530 global $wpdb; 531 532 add_filter( 'networks_pre_query', array( __CLASS__, 'filter_networks_pre_query' ), 10, 2 ); 533 534 $num_queries = $wpdb->num_queries; 535 536 $q = new WP_Network_Query(); 537 $results = $q->query( 538 array( 539 'fields' => 'ids', 540 ) 541 ); 542 543 remove_filter( 'networks_pre_query', array( __CLASS__, 'filter_networks_pre_query' ), 10, 2 ); 544 545 // Make sure no queries were executed. 546 $this->assertSame( $num_queries, $wpdb->num_queries ); 547 548 // We manually inserted a non-existing site and overrode the results with it. 549 $this->assertSame( array( 555 ), $q->networks ); 550 551 // Make sure manually setting total_users doesn't get overwritten. 552 $this->assertEquals( 1, $q->found_networks ); 553 } 554 555 public static function filter_networks_pre_query( $networks, $query ) { 556 $query->found_networks = 1; 557 558 return array( 555 ); 559 } 525 560 } 526 561 527 562 endif; -
tests/phpunit/tests/multisite/siteQuery.php
diff --git tests/phpunit/tests/multisite/siteQuery.php tests/phpunit/tests/multisite/siteQuery.php index bac9269ff4..c17f977932 100644
if ( is_multisite() ) : 911 911 } 912 912 } 913 913 914 915 /** 916 * @ticket 45749 917 */ 918 public function test_sites_pre_query_filter_should_bypass_database_query() { 919 global $wpdb; 920 921 add_filter( 'sites_pre_query', array( __CLASS__, 'filter_sites_pre_query' ), 10, 2 ); 922 923 $num_queries = $wpdb->num_queries; 924 925 $q = new WP_Site_Query(); 926 $results = $q->query( 927 array( 928 'fields' => 'ids', 929 ) 930 ); 931 932 remove_filter( 'sites_pre_query', array( __CLASS__, 'filter_sites_pre_query' ), 10, 2 ); 933 934 // Make sure no queries were executed. 935 $this->assertSame( $num_queries, $wpdb->num_queries ); 936 937 // We manually inserted a non-existing site and overrode the results with it. 938 $this->assertSame( array( 555 ), $q->sites ); 939 940 // Make sure manually setting total_users doesn't get overwritten. 941 $this->assertEquals( 1, $q->found_sites ); 942 } 943 944 public static function filter_sites_pre_query( $sites, $query ) { 945 $query->found_sites = 1; 946 947 return array( 555 ); 948 } 949 914 950 public function data_wp_site_query_meta_query() { 915 951 return array( 916 952 array(