Make WordPress Core

Ticket #32504: 32504.7.diff

File 32504.7.diff, 32.9 KB (added by jeremyfelt, 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 */
     17class 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         * Parses 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         * Gets a list of networks matching the query vars.
     194         *
     195         * @since 4.6.0
     196         * @access public
     197         *
     198         * @return int|array The list of networks.
     199         */
     200        public function get_networks() {
     201                $this->parse_query();
     202
     203                /**
     204                 * Fires before networks are retrieved.
     205                 *
     206                 * @since 4.6.0
     207                 *
     208                 * @param WP_Network_Query &$this Current instance of WP_Network_Query, passed by reference.
     209                 */
     210                do_action_ref_array( 'pre_get_networks', array( &$this ) );
     211
     212                // $args can include anything. Only use the args defined in the query_var_defaults to compute the key.
     213                $key = md5( serialize( wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) ) ) );
     214                $last_changed = wp_cache_get( 'last_changed', 'networks' );
     215                if ( ! $last_changed ) {
     216                        $last_changed = microtime();
     217                        wp_cache_set( 'last_changed', $last_changed, 'networks' );
     218                }
     219
     220                $cache_key = "get_network_ids:$key:$last_changed";
     221                $cache_value = wp_cache_get( $cache_key, 'networks' );
     222
     223                if ( false === $cache_value ) {
     224                        $network_ids = $this->get_network_ids();
     225                        if ( $network_ids ) {
     226                                $this->set_found_networks();
     227                        }
     228
     229                        $cache_value = array(
     230                                'network_ids' => $network_ids,
     231                                'found_networks' => $this->found_networks,
     232                                'max_num_pages' => $this->max_num_pages,
     233                        );
     234                        wp_cache_add( $cache_key, $cache_value, 'networks' );
     235                } else {
     236                        $network_ids = $cache_value['network_ids'];
     237                        $this->found_networks = $cache_value['found_networks'];
     238                        $this->max_num_pages = $cache_value['max_num_pages'];
     239                }
     240
     241                // If querying for a count only, there's nothing more to do.
     242                if ( $this->query_vars['count'] ) {
     243                        // $network_ids is actually a count in this case.
     244                        return intval( $network_ids );
     245                }
     246
     247                $network_ids = array_map( 'intval', $network_ids );
     248
     249                if ( 'ids' == $this->query_vars['fields'] ) {
     250                        $this->networks = $network_ids;
     251                        return $this->networks;
     252                }
     253
     254                if ( $this->query_vars['update_network_cache'] ) {
     255                        _prime_network_caches( $network_ids );
     256                }
     257
     258                // Fetch full network objects from the primed cache.
     259                $_networks = array();
     260                foreach ( $network_ids as $network_id ) {
     261                        if ( $_network = get_network( $network_id ) ) {
     262                                $_networks[] = $_network;
     263                        }
     264                }
     265
     266                /**
     267                 * Filters the network query results.
     268                 *
     269                 * @since 4.6.0
     270                 *
     271                 * @param array            $results  An array of networks.
     272                 * @param WP_Network_Query &$this    Current instance of WP_Network_Query, passed by reference.
     273                 */
     274                $_networks = apply_filters_ref_array( 'the_networks', array( $_networks, &$this ) );
     275
     276                // Convert to WP_Network instances
     277                $this->networks = array_map( 'get_network', $_networks );
     278
     279                return $this->networks;
     280        }
     281
     282        /**
     283         * Used internally to get a list of network IDs matching the query vars.
     284         *
     285         * @since 4.6.0
     286         * @access protected
     287         *
     288         * @return int|array A single count of network IDs if a count query. An array of network IDs if a full query.
     289         */
     290        protected function get_network_ids() {
     291                global $wpdb;
     292
     293                $order = $this->parse_order( $this->query_vars['order'] );
     294
     295                // Disable ORDER BY with 'none', an empty array, or boolean false.
     296                if ( in_array( $this->query_vars['orderby'], array( 'none', array(), false ), true ) ) {
     297                        $orderby = '';
     298                } elseif ( ! empty( $this->query_vars['orderby'] ) ) {
     299                        $ordersby = is_array( $this->query_vars['orderby'] ) ?
     300                                $this->query_vars['orderby'] :
     301                                preg_split( '/[,\s]/', $this->query_vars['orderby'] );
     302
     303                        $orderby_array = array();
     304                        foreach ( $ordersby as $_key => $_value ) {
     305                                if ( ! $_value ) {
     306                                        continue;
     307                                }
     308
     309                                if ( is_int( $_key ) ) {
     310                                        $_orderby = $_value;
     311                                        $_order = $order;
     312                                } else {
     313                                        $_orderby = $_key;
     314                                        $_order = $_value;
     315                                }
     316
     317                                $parsed = $this->parse_orderby( $_orderby );
     318
     319                                if ( ! $parsed ) {
     320                                        continue;
     321                                }
     322
     323                                if ( 'network__in' === $_orderby ) {
     324                                        $orderby_array[] = $parsed;
     325                                        continue;
     326                                }
     327
     328                                $orderby_array[] = $parsed . ' ' . $this->parse_order( $_order );
     329                        }
     330
     331                        $orderby = implode( ', ', $orderby_array );
     332                } else {
     333                        $orderby = "$wpdb->site.id $order";
     334                }
     335
     336                $number = absint( $this->query_vars['number'] );
     337                $offset = absint( $this->query_vars['offset'] );
     338
     339                if ( ! empty( $number ) ) {
     340                        if ( $offset ) {
     341                                $limits = 'LIMIT ' . $offset . ',' . $number;
     342                        } else {
     343                                $limits = 'LIMIT ' . $number;
     344                        }
     345                }
     346
     347                if ( $this->query_vars['count'] ) {
     348                        $fields = 'COUNT(*)';
     349                } else {
     350                        $fields = "$wpdb->site.id";
     351                }
     352
     353                // Parse network IDs for an IN clause.
     354                if ( ! empty( $this->query_vars['network__in'] ) ) {
     355                        $this->sql_clauses['where']['network__in'] = "$wpdb->site.id IN ( " . implode( ',', wp_parse_id_list( $this->query_vars['network__in'] ) ) . ' )';
     356                }
     357
     358                // Parse network IDs for a NOT IN clause.
     359                if ( ! empty( $this->query_vars['network__not_in'] ) ) {
     360                        $this->sql_clauses['where']['network__not_in'] = "$wpdb->site.id NOT IN ( " . implode( ',', wp_parse_id_list( $this->query_vars['network__not_in'] ) ) . ' )';
     361                }
     362
     363                if ( ! empty( $this->query_vars['domain'] ) ) {
     364                        $this->sql_clauses['where']['domain'] = $wpdb->prepare( "$wpdb->site.domain = %s", $this->query_vars['domain'] );
     365                }
     366
     367                // Parse network domain for an IN clause.
     368                if ( is_array( $this->query_vars['domain__in'] ) ) {
     369                        $this->sql_clauses['where']['domain__in'] = "$wpdb->site.domain IN ( '" . implode( "', '", $wpdb->_escape( $this->query_vars['domain__in'] ) ) . "' )";
     370                }
     371
     372                // Parse network domain for a NOT IN clause.
     373                if ( is_array( $this->query_vars['domain__not_in'] ) ) {
     374                        $this->sql_clauses['where']['domain__not_in'] = "$wpdb->site.domain NOT IN ( '" . implode( "', '", $wpdb->_escape( $this->query_vars['domain__not_in'] ) ) . "' )";
     375                }
     376
     377                if ( ! empty( $this->query_vars['path'] ) ) {
     378                        $this->sql_clauses['where']['path'] = $wpdb->prepare( "$wpdb->site.path = %s", $this->query_vars['path'] );
     379                }
     380
     381                // Parse network path for an IN clause.
     382                if ( is_array( $this->query_vars['path__in'] ) ) {
     383                        $this->sql_clauses['where']['path__in'] = "$wpdb->site.path IN ( '" . implode( "', '", $wpdb->_escape( $this->query_vars['path__in'] ) ) . "' )";
     384                }
     385
     386                // Parse network path for a NOT IN clause.
     387                if ( is_array( $this->query_vars['path__not_in'] ) ) {
     388                        $this->sql_clauses['where']['path__not_in'] = "$wpdb->site.path NOT IN ( '" . implode( "', '", $wpdb->_escape( $this->query_vars['path__not_in'] ) ) . "' )";
     389                }
     390
     391                // Falsey search strings are ignored.
     392                if ( strlen( $this->query_vars['search'] ) ) {
     393                        $this->sql_clauses['where']['search'] = $this->get_search_sql(
     394                                $this->query_vars['search'],
     395                                array( "$wpdb->site.domain", "$wpdb->site.path" )
     396                        );
     397                }
     398
     399                $join = '';
     400
     401                $where = implode( ' AND ', $this->sql_clauses['where'] );
     402
     403                $pieces = array( 'fields', 'join', 'where', 'orderby', 'limits', 'groupby' );
     404
     405                /**
     406                 * Filters the network query clauses.
     407                 *
     408                 * @since 4.6.0
     409                 *
     410                 * @param array            $pieces A compacted array of network query clauses.
     411                 * @param WP_Network_Query &$this  Current instance of WP_Network_Query, passed by reference.
     412                 */
     413                $clauses = apply_filters_ref_array( 'networks_clauses', array( compact( $pieces ), &$this ) );
     414
     415                $fields = isset( $clauses['fields'] ) ? $clauses['fields'] : '';
     416                $join = isset( $clauses['join'] ) ? $clauses['join'] : '';
     417                $where = isset( $clauses['where'] ) ? $clauses['where'] : '';
     418                $orderby = isset( $clauses['orderby'] ) ? $clauses['orderby'] : '';
     419                $limits = isset( $clauses['limits'] ) ? $clauses['limits'] : '';
     420                $groupby = isset( $clauses['groupby'] ) ? $clauses['groupby'] : '';
     421
     422                if ( $where ) {
     423                        $where = 'WHERE ' . $where;
     424                }
     425
     426                if ( $groupby ) {
     427                        $groupby = 'GROUP BY ' . $groupby;
     428                }
     429
     430                if ( $orderby ) {
     431                        $orderby = "ORDER BY $orderby";
     432                }
     433
     434                $found_rows = '';
     435                if ( ! $this->query_vars['no_found_rows'] ) {
     436                        $found_rows = 'SQL_CALC_FOUND_ROWS';
     437                }
     438
     439                $this->sql_clauses['select']  = "SELECT $found_rows $fields";
     440                $this->sql_clauses['from']    = "FROM $wpdb->site $join";
     441                $this->sql_clauses['groupby'] = $groupby;
     442                $this->sql_clauses['orderby'] = $orderby;
     443                $this->sql_clauses['limits']  = $limits;
     444
     445                $this->request = "{$this->sql_clauses['select']} {$this->sql_clauses['from']} {$where} {$this->sql_clauses['groupby']} {$this->sql_clauses['orderby']} {$this->sql_clauses['limits']}";
     446
     447                if ( $this->query_vars['count'] ) {
     448                        return intval( $wpdb->get_var( $this->request ) );
     449                }
     450
     451                $network_ids = $wpdb->get_col( $this->request );
     452
     453                return array_map( 'intval', $network_ids );
     454        }
     455
     456        /**
     457         * Populates found_networks and max_num_pages properties for the current query
     458         * if the limit clause was used.
     459         *
     460         * @since 4.6.0
     461         * @access private
     462         *
     463         * @global wpdb $wpdb WordPress database abstraction object.
     464         */
     465        private function set_found_networks() {
     466                global $wpdb;
     467
     468                if ( $this->query_vars['number'] && ! $this->query_vars['no_found_rows'] ) {
     469                        /**
     470                         * Filters the query used to retrieve found network count.
     471                         *
     472                         * @since 4.6.0
     473                         *
     474                         * @param string           $found_networks_query SQL query. Default 'SELECT FOUND_ROWS()'.
     475                         * @param WP_Network_Query $network_query        The `WP_Network_Query` instance.
     476                         */
     477                        $found_networks_query = apply_filters( 'found_networks_query', 'SELECT FOUND_ROWS()', $this );
     478
     479                        $this->found_networks = (int) $wpdb->get_var( $found_networks_query );
     480                        $this->max_num_pages = ceil( $this->found_networks / $this->query_vars['number'] );
     481                }
     482        }
     483
     484        /**
     485         * Used internally to generate an SQL string for searching across multiple columns.
     486         *
     487         * @since 4.6.0
     488         * @access protected
     489         *
     490         * @global wpdb  $wpdb WordPress database abstraction object.
     491         *
     492         * @param string $string  Search string.
     493         * @param array  $columns Columns to search.
     494         *
     495         * @return string Search SQL.
     496         */
     497        protected function get_search_sql( $string, $columns ) {
     498                global $wpdb;
     499
     500                $like = '%' . $wpdb->esc_like( $string ) . '%';
     501
     502                $searches = array();
     503                foreach ( $columns as $column ) {
     504                        $searches[] = $wpdb->prepare( "$column LIKE %s", $like );
     505                }
     506
     507                return '(' . implode( ' OR ', $searches ) . ')';
     508        }
     509
     510        /**
     511         * Parses and sanitizes 'orderby' keys passed to the network query.
     512         *
     513         * @since 4.6.0
     514         * @access protected
     515         *
     516         * @global wpdb $wpdb WordPress database abstraction object.
     517         *
     518         * @param string $orderby Alias for the field to order by.
     519         * @return string|false Value to used in the ORDER clause. False otherwise.
     520         */
     521        protected function parse_orderby( $orderby ) {
     522                global $wpdb;
     523
     524                $allowed_keys = array(
     525                        'id',
     526                        'domain',
     527                        'path',
     528                );
     529
     530                $parsed = false;
     531                if ( $orderby == 'network__in' ) {
     532                        $network__in = implode( ',', array_map( 'absint', $this->query_vars['network__in'] ) );
     533                        $parsed = "FIELD( {$wpdb->site}.id, $network__in )";
     534                } elseif ( $orderby == 'domain_length' || $orderby == 'path_length' ) {
     535                        $field = substr( $orderby, 0, -7 );
     536                        $parsed = "CHAR_LENGTH($wpdb->site.$field)";
     537                } elseif ( in_array( $orderby, $allowed_keys ) ) {
     538                        $parsed = "$wpdb->site.$orderby";
     539                }
     540
     541                return $parsed;
     542        }
     543
     544        /**
     545         * Parses an 'order' query variable and cast it to 'ASC' or 'DESC' as necessary.
     546         *
     547         * @since 4.6.0
     548         * @access protected
     549         *
     550         * @param string $order The 'order' query variable.
     551         * @return string The sanitized 'order' query variable.
     552         */
     553        protected function parse_order( $order ) {
     554                if ( ! is_string( $order ) || empty( $order ) ) {
     555                        return 'ASC';
     556                }
     557
     558                if ( 'ASC' === strtoupper( $order ) ) {
     559                        return 'ASC';
     560                } else {
     561                        return 'DESC';
     562                }
     563        }
     564}
  • src/wp-includes/ms-blogs.php

     
    10721072}
    10731073
    10741074/**
     1075 * Retrieves a list of networks.
     1076 *
     1077 * @since 4.6.0
     1078 *
     1079 * @param string|array $args Optional. Array or string of arguments. See {@see WP_Network_Query::parse_query()}
     1080 *                           for information on accepted arguments. Default empty.
     1081 * @return int|array List of networks or number of found networks if `$count` argument is true.
     1082 */
     1083function get_networks( $args = '' ) {
     1084        $query = new WP_Network_Query();
     1085        return $query->query( $args );
     1086}
     1087
     1088/**
     1089 * Retrieves network data given a network ID or network object.
     1090 *
     1091 * Network data will be cached and returned after being passed through a filter.
     1092 * If the provided network is empty, the current network global will be used.
     1093 *
     1094 * @since 4.6.0
     1095 *
     1096 * @global WP_Network $current_site
     1097 *
     1098 * @param WP_Network|int|null $network Network to retrieve.
     1099 * @return WP_Network|null The network object or null if not found.
     1100 */
     1101function get_network( &$network = null ) {
     1102        global $current_site;
     1103        if ( empty( $network ) && isset( $current_site ) ) {
     1104                $network = $current_site;
     1105        }
     1106
     1107        if ( $network instanceof WP_Network ) {
     1108                $_network = $network;
     1109        } elseif ( is_object( $network ) ) {
     1110                $_network = new WP_Network( $network );
     1111        } else {
     1112                $_network = WP_Network::get_instance( $network );
     1113        }
     1114
     1115        if ( ! $_network ) {
     1116                return null;
     1117        }
     1118
     1119        /**
     1120         * Fires after a network is retrieved.
     1121         *
     1122         * @since 4.6.0
     1123         *
     1124         * @param WP_Network $_network Network data.
     1125         */
     1126        $_network = apply_filters( 'get_network', $_network );
     1127
     1128        return $_network;
     1129}
     1130
     1131/**
     1132 * Removes a network from the object cache.
     1133 *
     1134 * @since 4.6.0
     1135 *
     1136 * @param int|array $ids Network ID or an array of network IDs to remove from cache.
     1137 */
     1138function clean_network_cache( $ids ) {
     1139        foreach ( (array) $ids as $id ) {
     1140                wp_cache_delete( $id, 'networks' );
     1141
     1142                /**
     1143                 * Fires immediately after a network has been removed from the object cache.
     1144                 *
     1145                 * @since 4.6.0
     1146                 *
     1147                 * @param int $id Network ID.
     1148                 */
     1149                do_action( 'clean_network_cache', $id );
     1150        }
     1151
     1152        wp_cache_set( 'last_changed', microtime(), 'networks' );
     1153}
     1154
     1155/**
     1156 * Updates the network cache of given networks.
     1157 *
     1158 * Will add the networks in $networks to the cache. If network ID already exists
     1159 * in the network cache then it will not be updated. The network is added to the
     1160 * cache using the network group with the key using the ID of the networks.
     1161 *
     1162 * @since 4.6.0
     1163 *
     1164 * @param array $networks Array of network row objects.
     1165 */
     1166function update_network_cache( $networks ) {
     1167        foreach ( (array) $networks as $network ) {
     1168                wp_cache_add( $network->id, $network, 'networks' );
     1169        }
     1170}
     1171
     1172/**
     1173 * Adds any networks from the given IDs to the cache that do not already exist in cache.
     1174 *
     1175 * @since 4.6.0
     1176 * @access private
     1177 *
     1178 * @see update_network_cache()
     1179 * @global wpdb $wpdb WordPress database abstraction object.
     1180 *
     1181 * @param array $network_ids Array of network IDs.
     1182 */
     1183function _prime_network_caches( $network_ids ) {
     1184        global $wpdb;
     1185
     1186        $non_cached_ids = _get_non_cached_ids( $network_ids, 'networks' );
     1187        if ( !empty( $non_cached_ids ) ) {
     1188                $fresh_networks = $wpdb->get_results( sprintf( "SELECT $wpdb->site.* FROM $wpdb->site WHERE id IN (%s)", join( ",", array_map( 'intval', $non_cached_ids ) ) ) );
     1189
     1190                update_network_cache( $fresh_networks );
     1191        }
     1192}
     1193
     1194/**
    10751195 * Handler for updating the blog date when a post is published or an already published post is changed.
    10761196 *
    10771197 * @since 3.3.0
  • src/wp-includes/ms-load.php

     
    137137 *
    138138 * @since 3.9.0
    139139 * @since 4.4.0 Converted to leverage WP_Network
     140 * @since 4.6.0 Converted to use `get_network()`
    140141 *
    141142 * @param object|int $network The network's database row or ID.
    142143 * @return WP_Network|false Object containing network information if found, false if not.
    143144 */
    144145function 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;
    149149        }
    150150
    151151        return $network;
  • src/wp-settings.php

     
    115115// Initialize multisite if enabled.
    116116if ( is_multisite() ) {
    117117        require( ABSPATH . WPINC . '/class-wp-site-query.php' );
     118        require( ABSPATH . WPINC . '/class-wp-network-query.php' );
    118119        require( ABSPATH . WPINC . '/ms-blogs.php' );
    119120        require( ABSPATH . WPINC . '/ms-settings.php' );
    120121} elseif ( ! defined( 'MULTISITE' ) ) {
  • tests/phpunit/tests/multisite/networkQuery.php

     
     1<?php
     2
     3if ( 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 */
     12class 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
     363endif;