WordPress.org

Make WordPress Core

Ticket #32504: 32504.6.diff

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

     
    10641064}
    10651065
    10661066/**
     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 */
     1076function 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 */
     1094function 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 */
     1131function 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 */
     1159function 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 */
     1176function _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/**
    10671188 * Handler for updating the blog date when a post is published or an already published post is changed.
    10681189 *
    10691190 * @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;