Ticket #32504: 32504.5.diff
File 32504.5.diff, 33.4 KB (added by , 9 years ago) |
---|
-
src/wp-includes/class-wp-network-query.php
1 <?php 2 /** 3 * Network API: WP_Network_Query class 4 * 5 * @package WordPress 6 * @subpackage Multisite 7 * @since 4.6.0 8 */ 9 10 /** 11 * Core class used for querying networks. 12 * 13 * @since 4.6.0 14 * 15 * @see WP_Network_Query::__construct() for accepted arguments. 16 */ 17 class WP_Network_Query { 18 19 /** 20 * SQL for database query. 21 * 22 * @since 4.6.0 23 * @access public 24 * @var string 25 */ 26 public $request; 27 28 /** 29 * SQL query clauses. 30 * 31 * @since 4.6.0 32 * @access protected 33 * @var array 34 */ 35 protected $sql_clauses = array( 36 'select' => '', 37 'from' => '', 38 'where' => array(), 39 'groupby' => '', 40 'orderby' => '', 41 'limits' => '', 42 ); 43 44 /** 45 * Query vars set by the user. 46 * 47 * @since 4.6.0 48 * @access public 49 * @var array 50 */ 51 public $query_vars; 52 53 /** 54 * Default values for query vars. 55 * 56 * @since 4.6.0 57 * @access public 58 * @var array 59 */ 60 public $query_var_defaults; 61 62 /** 63 * List of networks located by the query. 64 * 65 * @since 4.6.0 66 * @access public 67 * @var array 68 */ 69 public $networks; 70 71 /** 72 * The amount of found networks for the current query. 73 * 74 * @since 4.6.0 75 * @access public 76 * @var int 77 */ 78 public $found_networks = 0; 79 80 /** 81 * The number of pages. 82 * 83 * @since 4.6.0 84 * @access public 85 * @var int 86 */ 87 public $max_num_pages = 0; 88 89 /** 90 * Constructor. 91 * 92 * Sets up the network query, based on the query vars passed. 93 * 94 * @since 4.6.0 95 * @access public 96 * 97 * @param string|array $query { 98 * Optional. Array or query string of network query parameters. Default empty. 99 * 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. 103 * Default false. 104 * @type string $fields Network fields to return. Accepts 'ids' for network IDs only or empty 105 * for all fields. Default empty. 106 * @type int $number Maximum number of networks to retrieve. Default null (no limit). 107 * @type int $offset Number of networks to offset the query. Used to build LIMIT clause. 108 * Default 0. 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', 111 * 'domain_length', 'path_length' and 'network__in'. Also accepts false, an empty array, or 'none' to disable 112 * `ORDER BY` clause. Default 'id'. 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 network ID. 115 * Default current network ID. 116 * @type array $domain__in Array of domains to include affiliated networks for. Default empty. 117 * @type array $domain__not_in Array of domains to exclude affiliated networks for. Default empty. 118 * @type string $path Limit results to those affiliated with a given network ID. 119 * Default current network ID. 120 * @type array $path__in Array of paths to include affiliated networks for. Default empty. 121 * @type array $path__not_in Array of paths to exclude affiliated networks for. Default empty. 122 * @type string $search Search term(s) to retrieve matching networks for. Default empty. 123 * @type bool $update_network_cache Whether to prime the cache for found networks. Default true. 124 * } 125 */ 126 public function __construct( $query = '' ) { 127 $this->query_var_defaults = array( 128 'network__in' => '', 129 'network__not_in' => '', 130 'count' => false, 131 'fields' => '', 132 'number' => '', 133 'offset' => '', 134 'no_found_rows' => true, 135 'orderby' => '', 136 'order' => 'ASC', 137 'domain' => '', 138 'domain__in' => '', 139 'domain__not_in' => '', 140 'path' => '', 141 'path__in' => '', 142 'path__not_in' => '', 143 'search' => '', 144 'update_network_cache' => true, 145 ); 146 147 if ( ! empty( $query ) ) { 148 $this->query( $query ); 149 } 150 } 151 152 /** 153 * Parse arguments passed to the network query with default query parameters. 154 * 155 * @since 4.6.0 156 * 157 * @access public 158 * 159 * @param string|array $query WP_Network_Query arguments. See WP_Network_Query::__construct() 160 */ 161 public function parse_query( $query = '' ) { 162 if ( empty( $query ) ) { 163 $query = $this->query_vars; 164 } 165 166 $this->query_vars = wp_parse_args( $query, $this->query_var_defaults ); 167 168 /** 169 * Fires after the network query vars have been parsed. 170 * 171 * @since 4.6.0 172 * 173 * @param WP_Network_Query &$this The WP_Network_Query instance (passed by reference). 174 */ 175 do_action_ref_array( 'parse_network_query', array( &$this ) ); 176 } 177 178 /** 179 * Sets up the WordPress query for retrieving networks. 180 * 181 * @since 4.6.0 182 * @access public 183 * 184 * @param string|array $query Array or URL query string of parameters. 185 * @return array|int List of networks, or number of networks when 'count' is passed as a query var. 186 */ 187 public function query( $query ) { 188 $this->query_vars = wp_parse_args( $query ); 189 return $this->get_networks(); 190 } 191 192 /** 193 * Get a list of networks matching the query vars. 194 * 195 * @since 4.6.0 196 * @access public 197 * 198 * @global wpdb $wpdb WordPress database abstraction object. 199 * 200 * @return int|array The list of networks. 201 */ 202 public function get_networks() { 203 global $wpdb; 204 205 $this->parse_query(); 206 207 /** 208 * Fires before networks are retrieved. 209 * 210 * @since 4.6.0 211 * 212 * @param WP_Network_Query &$this Current instance of WP_Network_Query, passed by reference. 213 */ 214 do_action_ref_array( 'pre_get_networks', array( &$this ) ); 215 216 // $args can include anything. Only use the args defined in the query_var_defaults to compute the key. 217 $key = md5( serialize( wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) ) ) ); 218 $last_changed = wp_cache_get( 'last_changed', 'networks' ); 219 if ( ! $last_changed ) { 220 $last_changed = microtime(); 221 wp_cache_set( 'last_changed', $last_changed, 'networks' ); 222 } 223 $cache_key = "get_network_ids:$key:$last_changed"; 224 225 $network_ids = wp_cache_get( $cache_key, 'networks' ); 226 if ( false === $network_ids ) { 227 $network_ids = $this->get_network_ids(); 228 wp_cache_add( $cache_key, $network_ids, 'networks' ); 229 } 230 231 // If querying for a count only, there's nothing more to do. 232 if ( $this->query_vars['count'] ) { 233 // $network_ids is actually a count in this case. 234 return intval( $network_ids ); 235 } 236 237 $network_ids = array_map( 'intval', $network_ids ); 238 239 $this->network_count = count( $this->networks ); 240 241 if ( $network_ids && $this->query_vars['number'] && ! $this->query_vars['no_found_rows'] ) { 242 /** 243 * Filter the query used to retrieve found network count. 244 * 245 * @since 4.6.0 246 * 247 * @param string $found_networks_query SQL query. Default 'SELECT FOUND_ROWS()'. 248 * @param WP_Network_Query $network_query The `WP_Network_Query` instance. 249 */ 250 $found_networks_query = apply_filters( 'found_networks_query', 'SELECT FOUND_ROWS()', $this ); 251 $this->found_networks = (int) $wpdb->get_var( $found_networks_query ); 252 253 $this->max_num_pages = ceil( $this->found_networks / $this->query_vars['number'] ); 254 } 255 256 if ( 'ids' == $this->query_vars['fields'] ) { 257 $this->networks = $network_ids; 258 return $this->networks; 259 } 260 261 if ( $this->query_vars['update_network_cache'] ) { 262 _prime_network_caches( $network_ids ); 263 } 264 265 // Fetch full network objects from the primed cache. 266 $_networks = array(); 267 foreach ( $network_ids as $network_id ) { 268 if ( $_network = get_network( $network_id ) ) { 269 $_networks[] = $_network; 270 } 271 } 272 273 /** 274 * Filter the network query results. 275 * 276 * @since 4.6.0 277 * 278 * @param array $results An array of networks. 279 * @param WP_Network_Query &$this Current instance of WP_Network_Query, passed by reference. 280 */ 281 $_networks = apply_filters_ref_array( 'the_networks', array( $_networks, &$this ) ); 282 283 // Convert to WP_Network instances 284 $this->networks = array_map( 'get_network', $_networks ); 285 286 return $this->networks; 287 } 288 289 /** 290 * Used internally to get a list of network IDs matching the query vars. 291 * 292 * @since 4.6.0 293 * @access protected 294 * 295 * @global wpdb $wpdb WordPress database abstraction object. 296 */ 297 protected function get_network_ids() { 298 global $wpdb; 299 300 $order = $this->parse_order( $this->query_vars['order'] ); 301 302 // Disable ORDER BY with 'none', an empty array, or boolean false. 303 if ( in_array( $this->query_vars['orderby'], array( 'none', array(), false ), true ) ) { 304 $orderby = ''; 305 } elseif ( ! empty( $this->query_vars['orderby'] ) ) { 306 $ordersby = is_array( $this->query_vars['orderby'] ) ? 307 $this->query_vars['orderby'] : 308 preg_split( '/[,\s]/', $this->query_vars['orderby'] ); 309 310 $orderby_array = array(); 311 foreach ( $ordersby as $_key => $_value ) { 312 if ( ! $_value ) { 313 continue; 314 } 315 316 if ( is_int( $_key ) ) { 317 $_orderby = $_value; 318 $_order = $order; 319 } else { 320 $_orderby = $_key; 321 $_order = $_value; 322 } 323 324 $parsed = $this->parse_orderby( $_orderby ); 325 326 if ( ! $parsed ) { 327 continue; 328 } 329 330 if ( 'network__in' === $_orderby ) { 331 $orderby_array[] = $parsed; 332 continue; 333 } 334 335 $orderby_array[] = $parsed . ' ' . $this->parse_order( $_order ); 336 } 337 338 $orderby = implode( ', ', $orderby_array ); 339 } else { 340 $orderby = "$wpdb->site.id $order"; 341 } 342 343 $number = absint( $this->query_vars['number'] ); 344 $offset = absint( $this->query_vars['offset'] ); 345 346 if ( ! empty( $number ) ) { 347 if ( $offset ) { 348 $limits = 'LIMIT ' . $offset . ',' . $number; 349 } else { 350 $limits = 'LIMIT ' . $number; 351 } 352 } 353 354 if ( $this->query_vars['count'] ) { 355 $fields = 'COUNT(*)'; 356 } else { 357 $fields = "$wpdb->site.id"; 358 } 359 360 // Parse network IDs for an IN clause. 361 if ( ! empty( $this->query_vars['network__in'] ) ) { 362 $this->sql_clauses['where']['network__in'] = "$wpdb->site.id IN ( " . implode( ',', wp_parse_id_list( $this->query_vars['network__in'] ) ) . ' )'; 363 } 364 365 // Parse network IDs for a NOT IN clause. 366 if ( ! empty( $this->query_vars['network__not_in'] ) ) { 367 $this->sql_clauses['where']['network__not_in'] = "$wpdb->site.id NOT IN ( " . implode( ',', wp_parse_id_list( $this->query_vars['network__not_in'] ) ) . ' )'; 368 } 369 370 if ( ! empty( $this->query_vars['domain'] ) ) { 371 $this->sql_clauses['where']['domain'] = $wpdb->prepare( "$wpdb->site.domain = %s", $this->query_vars['domain'] ); 372 } 373 374 // Parse network domain for an IN clause. 375 if ( is_array( $this->query_vars['domain__in'] ) ) { 376 $this->sql_clauses['where']['domain__in'] = "$wpdb->site.domain IN ( '" . implode( "', '", $wpdb->_escape( $this->query_vars['domain__in'] ) ) . "' )"; 377 } 378 379 // Parse network domain for a NOT IN clause. 380 if ( is_array( $this->query_vars['domain__not_in'] ) ) { 381 $this->sql_clauses['where']['domain__not_in'] = "$wpdb->site.domain NOT IN ( '" . implode( "', '", $wpdb->_escape( $this->query_vars['domain__not_in'] ) ) . "' )"; 382 } 383 384 if ( ! empty( $this->query_vars['path'] ) ) { 385 $this->sql_clauses['where']['path'] = $wpdb->prepare( "$wpdb->site.path = %s", $this->query_vars['path'] ); 386 } 387 388 // Parse network path for an IN clause. 389 if ( is_array( $this->query_vars['path__in'] ) ) { 390 $this->sql_clauses['where']['path__in'] = "$wpdb->site.path IN ( '" . implode( "', '", $wpdb->_escape( $this->query_vars['path__in'] ) ) . "' )"; 391 } 392 393 // Parse network path for a NOT IN clause. 394 if ( is_array( $this->query_vars['path__not_in'] ) ) { 395 $this->sql_clauses['where']['path__not_in'] = "$wpdb->site.path NOT IN ( '" . implode( "', '", $wpdb->_escape( $this->query_vars['path__not_in'] ) ) . "' )"; 396 } 397 398 // Falsey search strings are ignored. 399 if ( strlen( $this->query_vars['search'] ) ) { 400 $this->sql_clauses['where']['search'] = $this->get_search_sql( 401 $this->query_vars['search'], 402 array( "$wpdb->site.domain", "$wpdb->site.path" ) 403 ); 404 } 405 406 $join = ''; 407 408 $where = implode( ' AND ', $this->sql_clauses['where'] ); 409 410 $pieces = array( 'fields', 'join', 'where', 'orderby', 'limits', 'groupby' ); 411 412 /** 413 * Filters the network query clauses. 414 * 415 * @since 4.6.0 416 * 417 * @param array $pieces A compacted array of network query clauses. 418 * @param WP_Network_Query &$this Current instance of WP_Network_Query, passed by reference. 419 */ 420 $clauses = apply_filters_ref_array( 'networks_clauses', array( compact( $pieces ), &$this ) ); 421 422 $fields = isset( $clauses['fields'] ) ? $clauses['fields'] : ''; 423 $join = isset( $clauses['join'] ) ? $clauses['join'] : ''; 424 $where = isset( $clauses['where'] ) ? $clauses['where'] : ''; 425 $orderby = isset( $clauses['orderby'] ) ? $clauses['orderby'] : ''; 426 $limits = isset( $clauses['limits'] ) ? $clauses['limits'] : ''; 427 $groupby = isset( $clauses['groupby'] ) ? $clauses['groupby'] : ''; 428 429 if ( $where ) { 430 $where = 'WHERE ' . $where; 431 } 432 433 if ( $groupby ) { 434 $groupby = 'GROUP BY ' . $groupby; 435 } 436 437 if ( $orderby ) { 438 $orderby = "ORDER BY $orderby"; 439 } 440 441 $found_rows = ''; 442 if ( ! $this->query_vars['no_found_rows'] ) { 443 $found_rows = 'SQL_CALC_FOUND_ROWS'; 444 } 445 446 $this->sql_clauses['select'] = "SELECT $found_rows $fields"; 447 $this->sql_clauses['from'] = "FROM $wpdb->site $join"; 448 $this->sql_clauses['groupby'] = $groupby; 449 $this->sql_clauses['orderby'] = $orderby; 450 $this->sql_clauses['limits'] = $limits; 451 452 $this->request = "{$this->sql_clauses['select']} {$this->sql_clauses['from']} {$where} {$this->sql_clauses['groupby']} {$this->sql_clauses['orderby']} {$this->sql_clauses['limits']}"; 453 454 if ( $this->query_vars['count'] ) { 455 return intval( $wpdb->get_var( $this->request ) ); 456 } 457 458 $network_ids = $wpdb->get_col( $this->request ); 459 460 return array_map( 'intval', $network_ids ); 461 } 462 463 /** 464 * Used internally to generate an SQL string for searching across multiple columns 465 * 466 * @since 4.6.0 467 * @access protected 468 * 469 * @global wpdb $wpdb WordPress database abstraction object. 470 * 471 * @param string $string Search string. 472 * @param array $columns Columns to search. 473 * 474 * @return string Search SQL. 475 */ 476 protected function get_search_sql( $string, $columns ) { 477 global $wpdb; 478 479 $like = '%' . $wpdb->esc_like( $string ) . '%'; 480 481 $searches = array(); 482 foreach ( $columns as $column ) { 483 $searches[] = $wpdb->prepare( "$column LIKE %s", $like ); 484 } 485 486 return '(' . implode( ' OR ', $searches ) . ')'; 487 } 488 489 /** 490 * Parses and sanitizes 'orderby' keys passed to the network query. 491 * 492 * @since 4.6.0 493 * @access protected 494 * 495 * @global wpdb $wpdb WordPress database abstraction object. 496 * 497 * @param string $orderby Alias for the field to order by. 498 * @return string|false Value to used in the ORDER clause. False otherwise. 499 */ 500 protected function parse_orderby( $orderby ) { 501 global $wpdb; 502 503 $allowed_keys = array( 504 'id', 505 'domain', 506 'path', 507 ); 508 509 $parsed = false; 510 if ( $orderby == 'network__in' ) { 511 $network__in = implode( ',', array_map( 'absint', $this->query_vars['network__in'] ) ); 512 $parsed = "FIELD( {$wpdb->site}.id, $network__in )"; 513 } elseif ( $orderby == 'domain_length' || $orderby == 'path_length' ) { 514 $field = substr( $orderby, 0, -7 ); 515 $parsed = "CHAR_LENGTH($wpdb->site.$field)"; 516 } elseif ( in_array( $orderby, $allowed_keys ) ) { 517 $parsed = "$wpdb->site.$orderby"; 518 } 519 520 return $parsed; 521 } 522 523 /** 524 * Parses an 'order' query variable and cast it to 'ASC' or 'DESC' as necessary. 525 * 526 * @since 4.6.0 527 * @access protected 528 * 529 * @param string $order The 'order' query variable. 530 * @return string The sanitized 'order' query variable. 531 */ 532 protected function parse_order( $order ) { 533 if ( ! is_string( $order ) || empty( $order ) ) { 534 return 'ASC'; 535 } 536 537 if ( 'ASC' === strtoupper( $order ) ) { 538 return 'ASC'; 539 } else { 540 return 'DESC'; 541 } 542 } 543 } -
src/wp-includes/class-wp-network.php
Property changes on: src/wp-includes/class-wp-network-query.php ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property
205 205 } 206 206 207 207 /** 208 * Convert object to array. 209 * 210 * @since 4.6.0 211 * @access public 212 * 213 * @return array Object as array. 214 */ 215 public function to_array() { 216 return get_object_vars( $this ); 217 } 218 219 /** 208 220 * Set the site name assigned to the network if one has not been populated. 209 221 * 210 222 * @since 4.4.0 -
src/wp-includes/ms-blogs.php
1064 1064 } 1065 1065 1066 1066 /** 1067 * Retrieve a list of networks. 1068 * 1069 * @since 4.6.0 1070 * 1071 * @param string|array $args Optional. Array or string of arguments. See {@see WP_Network_Query::parse_query()} 1072 * for information on accepted arguments. Default empty. 1073 * 1074 * @return int|array List of networks or number of found networks if `$count` argument is true. 1075 */ 1076 function get_networks( $args = '' ) { 1077 $query = new WP_Network_Query(); 1078 return $query->query( $args ); 1079 } 1080 1081 /** 1082 * Retrieves network data given a network ID or network object. 1083 * 1084 * Network data will be cached and returned after being passed through a filter. 1085 * If the provided network is empty, the current network global will be used. 1086 * 1087 * @since 4.6.0 1088 * 1089 * @global WP_Network $current_site 1090 * 1091 * @param WP_Network|int|null $network Network to retrieve. 1092 * @return WP_Network|null The network object or null if not found. 1093 */ 1094 function get_network( &$network = null ) { 1095 global $current_site; 1096 if ( empty( $network ) && isset( $current_site ) ) { 1097 $network = $current_site; 1098 } 1099 1100 if ( $network instanceof WP_Network ) { 1101 $_network = $network; 1102 } elseif ( is_object( $network ) ) { 1103 $_network = new WP_Network( $network ); 1104 } else { 1105 $_network = WP_Network::get_instance( $network ); 1106 } 1107 1108 if ( ! $_network ) { 1109 return null; 1110 } 1111 1112 /** 1113 * Fires after a network is retrieved. 1114 * 1115 * @since 4.6.0 1116 * 1117 * @param WP_Network $_network Network data. 1118 */ 1119 $_network = apply_filters( 'get_network', $_network ); 1120 1121 return $_network; 1122 } 1123 1124 /** 1125 * Removes a network from the object cache. 1126 * 1127 * @since 4.6.0 1128 * 1129 * @param int|array $ids Network ID or an array of network IDs to remove from cache. 1130 */ 1131 function clean_network_cache( $ids ) { 1132 foreach ( (array) $ids as $id ) { 1133 wp_cache_delete( $id, 'networks' ); 1134 1135 /** 1136 * Fires immediately after a network has been removed from the object cache. 1137 * 1138 * @since 4.6.0 1139 * 1140 * @param int $id Network ID. 1141 */ 1142 do_action( 'clean_network_cache', $id ); 1143 } 1144 1145 wp_cache_set( 'last_changed', microtime(), 'networks' ); 1146 } 1147 1148 /** 1149 * Updates the network cache of given networks. 1150 * 1151 * Will add the networks in $networks to the cache. If network ID already exists 1152 * in the network cache then it will not be updated. The network is added to the 1153 * cache using the network group with the key using the ID of the networks. 1154 * 1155 * @since 4.6.0 1156 * 1157 * @param array $networks Array of network row objects. 1158 */ 1159 function update_network_cache( $networks ) { 1160 foreach ( (array) $networks as $network ) { 1161 wp_cache_add( $network->id, $network, 'networks' ); 1162 } 1163 } 1164 1165 /** 1166 * Adds any networks from the given IDs to the cache that do not already exist in cache. 1167 * 1168 * @since 4.6.0 1169 * @access private 1170 * 1171 * @see update_network_cache() 1172 * @global wpdb $wpdb WordPress database abstraction object. 1173 * 1174 * @param array $network_ids Array of network IDs. 1175 */ 1176 function _prime_network_caches( $network_ids ) { 1177 global $wpdb; 1178 1179 $non_cached_ids = _get_non_cached_ids( $network_ids, 'networks' ); 1180 if ( !empty( $non_cached_ids ) ) { 1181 $fresh_networks = $wpdb->get_results( sprintf( "SELECT $wpdb->site.* FROM $wpdb->site WHERE id IN (%s)", join( ",", array_map( 'intval', $non_cached_ids ) ) ) ); 1182 1183 update_network_cache( $fresh_networks ); 1184 } 1185 } 1186 1187 /** 1067 1188 * Handler for updating the blog date when a post is published or an already published post is changed. 1068 1189 * 1069 1190 * @since 3.3.0 -
src/wp-includes/ms-load.php
137 137 * 138 138 * @since 3.9.0 139 139 * @since 4.4.0 Converted to leverage WP_Network 140 * @since 4.6.0 Converted to use `get_network()` 140 141 * 141 142 * @param object|int $network The network's database row or ID. 142 143 * @return WP_Network|false Object containing network information if found, false if not. 143 144 */ 144 145 function wp_get_network( $network ) { 145 if ( ! is_object( $network ) ) { 146 $network = WP_Network::get_instance( $network ); 147 } else { 148 $network = new WP_Network( $network ); 146 $network = get_network( $network ); 147 if ( null === $network ) { 148 return false; 149 149 } 150 150 151 151 return $network; -
src/wp-settings.php
115 115 // Initialize multisite if enabled. 116 116 if ( is_multisite() ) { 117 117 require( ABSPATH . WPINC . '/class-wp-site-query.php' ); 118 require( ABSPATH . WPINC . '/class-wp-network-query.php' ); 118 119 require( ABSPATH . WPINC . '/ms-blogs.php' ); 119 120 require( ABSPATH . WPINC . '/ms-settings.php' ); 120 121 } elseif ( ! defined( 'MULTISITE' ) ) { -
tests/phpunit/tests/multisite/networkQuery.php
1 <?php 2 3 if ( is_multisite() ) : 4 5 /** 6 * Test network query functionality in multisite. 7 * 8 * @group ms-network 9 * @group ms-network-query 10 * @group multisite 11 */ 12 class Tests_Multisite_Network_Query extends WP_UnitTestCase { 13 protected static $network_ids; 14 15 protected $suppress = false; 16 17 function setUp() { 18 global $wpdb; 19 parent::setUp(); 20 $this->suppress = $wpdb->suppress_errors(); 21 } 22 23 function tearDown() { 24 global $wpdb; 25 $wpdb->suppress_errors( $this->suppress ); 26 parent::tearDown(); 27 } 28 29 public static function wpSetUpBeforeClass( $factory ) { 30 self::$network_ids = array( 31 'wordpress.org/' => array( 'domain' => 'wordpress.org', 'path' => '/' ), 32 'make.wordpress.org/' => array( 'domain' => 'make.wordpress.org', 'path' => '/' ), 33 'www.wordpress.net/' => array( 'domain' => 'www.wordpress.net', 'path' => '/' ), 34 'www.w.org/foo/' => array( 'domain' => 'www.w.org', 'path' => '/foo/' ), 35 ); 36 37 foreach ( self::$network_ids as &$id ) { 38 $id = $factory->network->create( $id ); 39 } 40 unset( $id ); 41 } 42 43 public static function wpTearDownAfterClass() { 44 global $wpdb; 45 46 foreach( self::$network_ids as $id ) { 47 $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->sitemeta} WHERE site_id = %d", $id ) ); 48 $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->site} WHERE id= %d", $id ) ); 49 } 50 } 51 52 public function test_wp_network_query_by_number() { 53 $q = new WP_Network_Query(); 54 $found = $q->query( array( 55 'fields' => 'ids', 56 'number' => 3, 57 ) ); 58 59 $this->assertEquals( 3, count( $found ) ); 60 } 61 62 public function test_wp_network_query_by_network__in_with_single_id() { 63 $expected = array( self::$network_ids['wordpress.org/'] ); 64 65 $q = new WP_Network_Query(); 66 $found = $q->query( array( 67 'fields' => 'ids', 68 'network__in' => $expected, 69 ) ); 70 71 $this->assertEqualSets( $expected, $found ); 72 } 73 74 public function test_wp_network_query_by_network__in_with_multiple_ids() { 75 $expected = array( self::$network_ids['wordpress.org/'], self::$network_ids['www.wordpress.net/'] ); 76 77 $q = new WP_Network_Query(); 78 $found = $q->query( array( 79 'fields' => 'ids', 80 'network__in' => $expected, 81 ) ); 82 83 $this->assertEqualSets( $expected, $found ); 84 } 85 86 public function test_wp_network_query_by_network__in_and_count_with_multiple_ids() { 87 $expected = array( self::$network_ids['wordpress.org/'], self::$network_ids['make.wordpress.org/'] ); 88 89 $q = new WP_Network_Query(); 90 $found = $q->query( array( 91 'fields' => 'ids', 92 'count' => true, 93 'network__in' => $expected, 94 ) ); 95 96 $this->assertEquals( 2, $found ); 97 } 98 99 public function test_wp_network_query_by_network__not_in_with_single_id() { 100 $excluded = array( self::$network_ids['wordpress.org/'] ); 101 $expected = array_diff( self::$network_ids, $excluded ); 102 103 // Exclude main network since we don't have control over it here. 104 $excluded[] = 1; 105 106 $q = new WP_Network_Query(); 107 $found = $q->query( array( 108 'fields' => 'ids', 109 'network__not_in' => $excluded, 110 ) ); 111 112 $this->assertEqualSets( $expected, $found ); 113 } 114 115 public function test_wp_network_query_by_network__not_in_with_multiple_ids() { 116 $excluded = array( self::$network_ids['wordpress.org/'], self::$network_ids['www.w.org/foo/'] ); 117 $expected = array_diff( self::$network_ids, $excluded ); 118 119 // Exclude main network since we don't have control over it here. 120 $excluded[] = 1; 121 122 $q = new WP_Network_Query(); 123 $found = $q->query( array( 124 'fields' => 'ids', 125 'network__not_in' => $excluded, 126 ) ); 127 128 $this->assertEqualSets( $expected, $found ); 129 } 130 131 public function test_wp_network_query_by_domain() { 132 $q = new WP_Network_Query(); 133 $found = $q->query( array( 134 'fields' => 'ids', 135 'domain' => 'www.w.org', 136 ) ); 137 138 $expected = array( 139 self::$network_ids['www.w.org/foo/'], 140 ); 141 142 $this->assertEqualSets( $expected, $found ); 143 } 144 145 public function test_wp_network_query_by_domain__in_with_single_domain() { 146 $q = new WP_Network_Query(); 147 $found = $q->query( array( 148 'fields' => 'ids', 149 'domain__in' => array( 'make.wordpress.org' ), 150 )); 151 152 $expected = array( 153 self::$network_ids['make.wordpress.org/'], 154 ); 155 156 $this->assertEqualSets( $expected, $found ); 157 } 158 159 public function test_wp_network_query_by_domain__in_with_multiple_domains() { 160 $q = new WP_Network_Query(); 161 $found = $q->query( array( 162 'fields' => 'ids', 163 'domain__in' => array( 'wordpress.org', 'make.wordpress.org' ), 164 )); 165 166 $expected = array( 167 self::$network_ids['wordpress.org/'], 168 self::$network_ids['make.wordpress.org/'], 169 ); 170 171 $this->assertEqualSets( $expected, $found ); 172 } 173 174 public function test_wp_network_query_by_domain__in_with_multiple_domains_and_number() { 175 $q = new WP_Network_Query(); 176 $found = $q->query( array( 177 'fields' => 'ids', 178 'number' => 1, 179 'domain__in' => array( 'wordpress.org', 'make.wordpress.org' ), 180 )); 181 182 $expected = array( 183 self::$network_ids['wordpress.org/'], 184 ); 185 186 $this->assertEqualSets( $expected, $found ); 187 } 188 189 public function test_wp_network_query_by_domain__in_with_multiple_domains_and_number_and_offset() { 190 $q = new WP_Network_Query(); 191 $found = $q->query( array( 192 'fields' => 'ids', 193 'number' => 1, 194 'offset' => 1, 195 'domain__in' => array( 'wordpress.org', 'make.wordpress.org' ), 196 )); 197 198 $expected = array( 199 self::$network_ids['make.wordpress.org/'], 200 ); 201 202 $this->assertEqualSets( $expected, $found ); 203 } 204 205 public function test_wp_network_query_by_domain__not_in_with_single_domain() { 206 $q = new WP_Network_Query(); 207 $found = $q->query( array( 208 'fields' => 'ids', 209 'domain__not_in' => array( 'www.w.org' ), 210 )); 211 212 $expected = array( 213 get_current_site()->id, // Account for the initial network added by the test suite. 214 self::$network_ids['wordpress.org/'], 215 self::$network_ids['make.wordpress.org/'], 216 self::$network_ids['www.wordpress.net/'], 217 ); 218 219 $this->assertEqualSets( $expected, $found ); 220 } 221 222 public function test_wp_network_query_by_domain__not_in_with_multiple_domains() { 223 $q = new WP_Network_Query(); 224 $found = $q->query( array( 225 'fields' => 'ids', 226 'domain__not_in' => array( 'wordpress.org', 'www.w.org' ), 227 )); 228 229 $expected = array( 230 get_current_site()->id, // Account for the initial network added by the test suite. 231 self::$network_ids['make.wordpress.org/'], 232 self::$network_ids['www.wordpress.net/'], 233 ); 234 235 $this->assertEqualSets( $expected, $found ); 236 } 237 238 public function test_wp_network_query_by_domain__not_in_with_multiple_domains_and_number() { 239 $q = new WP_Network_Query(); 240 $found = $q->query( array( 241 'fields' => 'ids', 242 'number' => 2, 243 'domain__not_in' => array( 'wordpress.org', 'www.w.org' ), 244 )); 245 246 $expected = array( 247 get_current_site()->id, // Account for the initial network added by the test suite. 248 self::$network_ids['make.wordpress.org/'], 249 ); 250 251 $this->assertEqualSets( $expected, $found ); 252 } 253 254 public function test_wp_network_query_by_domain__not_in_with_multiple_domains_and_number_and_offset() { 255 $q = new WP_Network_Query(); 256 $found = $q->query( array( 257 'fields' => 'ids', 258 'number' => 2, 259 'offset' => 1, 260 'domain__not_in' => array( 'wordpress.org', 'www.w.org' ), 261 )); 262 263 $expected = array( 264 self::$network_ids['make.wordpress.org/'], 265 self::$network_ids['www.wordpress.net/'], 266 ); 267 268 $this->assertEqualSets( $expected, $found ); 269 } 270 271 public function test_wp_network_query_by_path_with_expected_results() { 272 $q = new WP_Network_Query(); 273 $found = $q->query( array( 274 'fields' => 'ids', 275 'path' => '/', 276 'network__not_in' => get_current_site()->id, // Exclude the initial network added by the test suite. 277 ) ); 278 279 $expected = array( 280 self::$network_ids['wordpress.org/'], 281 self::$network_ids['make.wordpress.org/'], 282 self::$network_ids['www.wordpress.net/'], 283 ); 284 285 $this->assertEqualSets( $expected, $found ); 286 } 287 288 public function test_wp_network_query_by_path_and_number_and_offset_with_expected_results() { 289 $q = new WP_Network_Query(); 290 $found = $q->query( array( 291 'fields' => 'ids', 292 'number' => 1, 293 'offset' => 2, 294 'path' => '/', 295 'network__not_in' => get_current_site()->id, // Exclude the initial network added by the test suite. 296 ) ); 297 298 $expected = array( 299 self::$network_ids['www.wordpress.net/'], 300 ); 301 302 $this->assertEqualSets( $expected, $found ); 303 } 304 305 public function test_wp_network_query_by_path_with_no_expected_results() { 306 $q = new WP_Network_Query(); 307 $found = $q->query( array( 308 'fields' => 'ids', 309 'path' => '/bar/', 310 ) ); 311 312 $this->assertEmpty( $found ); 313 } 314 315 public function test_wp_network_query_by_search_with_text_in_domain() { 316 $q = new WP_Network_Query(); 317 $found = $q->query( array( 318 'fields' => 'ids', 319 'search' => 'ww.word', 320 ) ); 321 322 $expected = array( 323 self::$network_ids['www.wordpress.net/'], 324 ); 325 326 $this->assertEqualSets( $expected, $found ); 327 } 328 329 public function test_wp_network_query_by_search_with_text_in_path() { 330 $q = new WP_Network_Query(); 331 $found = $q->query( array( 332 'fields' => 'ids', 333 'search' => 'foo', 334 ) ); 335 336 $expected = array( 337 self::$network_ids['www.w.org/foo/'], 338 ); 339 340 $this->assertEqualSets( $expected, $found ); 341 } 342 343 public function test_wp_network_query_by_path_order_by_domain_desc() { 344 $q = new WP_Network_Query(); 345 $found = $q->query( array( 346 'fields' => 'ids', 347 'path' => '/', 348 'network__not_in' => get_current_site()->id, // Exclude the initial network added by the test suite. 349 'order' => 'DESC', 350 'orderby' => 'domain', 351 ) ); 352 353 $expected = array( 354 self::$network_ids['www.wordpress.net/'], 355 self::$network_ids['wordpress.org/'], 356 self::$network_ids['make.wordpress.org/'], 357 ); 358 359 $this->assertEquals( $expected, $found ); 360 } 361 } 362 363 endif;