wp/wp-includes/class-wp-site-query.php
changeset 21 48c4eec2b7e6
parent 19 3d72ae0968f4
child 22 8c2e4d02f4ef
equal deleted inserted replaced
20:7b1b88e27a20 21:48c4eec2b7e6
    12  *
    12  *
    13  * @since 4.6.0
    13  * @since 4.6.0
    14  *
    14  *
    15  * @see WP_Site_Query::__construct() for accepted arguments.
    15  * @see WP_Site_Query::__construct() for accepted arguments.
    16  */
    16  */
       
    17 #[AllowDynamicProperties]
    17 class WP_Site_Query {
    18 class WP_Site_Query {
    18 
    19 
    19 	/**
    20 	/**
    20 	 * SQL for database query.
    21 	 * SQL for database query.
    21 	 *
    22 	 *
   155 	 *     @type string[]        $domain__in             Array of domains to include affiliated sites for. Default empty.
   156 	 *     @type string[]        $domain__in             Array of domains to include affiliated sites for. Default empty.
   156 	 *     @type string[]        $domain__not_in         Array of domains to exclude affiliated sites for. Default empty.
   157 	 *     @type string[]        $domain__not_in         Array of domains to exclude affiliated sites for. Default empty.
   157 	 *     @type string          $path                   Limit results to those affiliated with a given path. Default empty.
   158 	 *     @type string          $path                   Limit results to those affiliated with a given path. Default empty.
   158 	 *     @type string[]        $path__in               Array of paths to include affiliated sites for. Default empty.
   159 	 *     @type string[]        $path__in               Array of paths to include affiliated sites for. Default empty.
   159 	 *     @type string[]        $path__not_in           Array of paths to exclude affiliated sites for. Default empty.
   160 	 *     @type string[]        $path__not_in           Array of paths to exclude affiliated sites for. Default empty.
   160 	 *     @type int             $public                 Limit results to public sites. Accepts '1' or '0'. Default empty.
   161 	 *     @type int             $public                 Limit results to public sites. Accepts 1 or 0. Default empty.
   161 	 *     @type int             $archived               Limit results to archived sites. Accepts '1' or '0'. Default empty.
   162 	 *     @type int             $archived               Limit results to archived sites. Accepts 1 or 0. Default empty.
   162 	 *     @type int             $mature                 Limit results to mature sites. Accepts '1' or '0'. Default empty.
   163 	 *     @type int             $mature                 Limit results to mature sites. Accepts 1 or 0. Default empty.
   163 	 *     @type int             $spam                   Limit results to spam sites. Accepts '1' or '0'. Default empty.
   164 	 *     @type int             $spam                   Limit results to spam sites. Accepts 1 or 0. Default empty.
   164 	 *     @type int             $deleted                Limit results to deleted sites. Accepts '1' or '0'. Default empty.
   165 	 *     @type int             $deleted                Limit results to deleted sites. Accepts 1 or 0. Default empty.
   165 	 *     @type int             $lang_id                Limit results to a language ID. Default empty.
   166 	 *     @type int             $lang_id                Limit results to a language ID. Default empty.
   166 	 *     @type string[]        $lang__in               Array of language IDs to include affiliated sites for. Default empty.
   167 	 *     @type string[]        $lang__in               Array of language IDs to include affiliated sites for. Default empty.
   167 	 *     @type string[]        $lang__not_in           Array of language IDs to exclude affiliated sites for. Default empty.
   168 	 *     @type string[]        $lang__not_in           Array of language IDs to exclude affiliated sites for. Default empty.
   168 	 *     @type string          $search                 Search term(s) to retrieve matching sites for. Default empty.
   169 	 *     @type string          $search                 Search term(s) to retrieve matching sites for. Default empty.
   169 	 *     @type string[]        $search_columns         Array of column names to be searched. Accepts 'domain' and 'path'.
   170 	 *     @type string[]        $search_columns         Array of column names to be searched. Accepts 'domain' and 'path'.
   171 	 *     @type bool            $update_site_cache      Whether to prime the cache for found sites. Default true.
   172 	 *     @type bool            $update_site_cache      Whether to prime the cache for found sites. Default true.
   172 	 *     @type bool            $update_site_meta_cache Whether to prime the metadata cache for found sites. Default true.
   173 	 *     @type bool            $update_site_meta_cache Whether to prime the metadata cache for found sites. Default true.
   173 	 *     @type string|string[] $meta_key               Meta key or keys to filter by.
   174 	 *     @type string|string[] $meta_key               Meta key or keys to filter by.
   174 	 *     @type string|string[] $meta_value             Meta value or values to filter by.
   175 	 *     @type string|string[] $meta_value             Meta value or values to filter by.
   175 	 *     @type string          $meta_compare           MySQL operator used for comparing the meta value.
   176 	 *     @type string          $meta_compare           MySQL operator used for comparing the meta value.
   176 	 *                                                   See WP_Meta_Query::__construct for accepted values and default value.
   177 	 *                                                   See WP_Meta_Query::__construct() for accepted values and default value.
   177 	 *     @type string          $meta_compare_key       MySQL operator used for comparing the meta key.
   178 	 *     @type string          $meta_compare_key       MySQL operator used for comparing the meta key.
   178 	 *                                                   See WP_Meta_Query::__construct for accepted values and default value.
   179 	 *                                                   See WP_Meta_Query::__construct() for accepted values and default value.
   179 	 *     @type string          $meta_type              MySQL data type that the meta_value column will be CAST to for comparisons.
   180 	 *     @type string          $meta_type              MySQL data type that the meta_value column will be CAST to for comparisons.
   180 	 *                                                   See WP_Meta_Query::__construct for accepted values and default value.
   181 	 *                                                   See WP_Meta_Query::__construct() for accepted values and default value.
   181 	 *     @type string          $meta_type_key          MySQL data type that the meta_key column will be CAST to for comparisons.
   182 	 *     @type string          $meta_type_key          MySQL data type that the meta_key column will be CAST to for comparisons.
   182 	 *                                                   See WP_Meta_Query::__construct for accepted values and default value.
   183 	 *                                                   See WP_Meta_Query::__construct() for accepted values and default value.
   183 	 *     @type array           $meta_query             An associative array of WP_Meta_Query arguments.
   184 	 *     @type array           $meta_query             An associative array of WP_Meta_Query arguments.
   184 	 *                                                   See WP_Meta_Query::__construct for accepted values.
   185 	 *                                                   See WP_Meta_Query::__construct() for accepted values.
   185 	 * }
   186 	 * }
   186 	 */
   187 	 */
   187 	public function __construct( $query = '' ) {
   188 	public function __construct( $query = '' ) {
   188 		$this->query_var_defaults = array(
   189 		$this->query_var_defaults = array(
   189 			'fields'                 => '',
   190 			'fields'                 => '',
   355 
   356 
   356 		$key          = md5( serialize( $_args ) );
   357 		$key          = md5( serialize( $_args ) );
   357 		$last_changed = wp_cache_get_last_changed( 'sites' );
   358 		$last_changed = wp_cache_get_last_changed( 'sites' );
   358 
   359 
   359 		$cache_key   = "get_sites:$key:$last_changed";
   360 		$cache_key   = "get_sites:$key:$last_changed";
   360 		$cache_value = wp_cache_get( $cache_key, 'sites' );
   361 		$cache_value = wp_cache_get( $cache_key, 'site-queries' );
   361 
   362 
   362 		if ( false === $cache_value ) {
   363 		if ( false === $cache_value ) {
   363 			$site_ids = $this->get_site_ids();
   364 			$site_ids = $this->get_site_ids();
   364 			if ( $site_ids ) {
   365 			if ( $site_ids ) {
   365 				$this->set_found_sites();
   366 				$this->set_found_sites();
   367 
   368 
   368 			$cache_value = array(
   369 			$cache_value = array(
   369 				'site_ids'    => $site_ids,
   370 				'site_ids'    => $site_ids,
   370 				'found_sites' => $this->found_sites,
   371 				'found_sites' => $this->found_sites,
   371 			);
   372 			);
   372 			wp_cache_add( $cache_key, $cache_value, 'sites' );
   373 			wp_cache_add( $cache_key, $cache_value, 'site-queries' );
   373 		} else {
   374 		} else {
   374 			$site_ids          = $cache_value['site_ids'];
   375 			$site_ids          = $cache_value['site_ids'];
   375 			$this->found_sites = $cache_value['found_sites'];
   376 			$this->found_sites = $cache_value['found_sites'];
   376 		}
   377 		}
   377 
   378 
   378 		if ( $this->found_sites && $this->query_vars['number'] ) {
   379 		if ( $this->found_sites && $this->query_vars['number'] ) {
   379 			$this->max_num_pages = ceil( $this->found_sites / $this->query_vars['number'] );
   380 			$this->max_num_pages = (int) ceil( $this->found_sites / $this->query_vars['number'] );
   380 		}
   381 		}
   381 
   382 
   382 		// If querying for a count only, there's nothing more to do.
   383 		// If querying for a count only, there's nothing more to do.
   383 		if ( $this->query_vars['count'] ) {
   384 		if ( $this->query_vars['count'] ) {
   384 			// $site_ids is actually a count in this case.
   385 			// $site_ids is actually a count in this case.
   385 			return (int) $site_ids;
   386 			return (int) $site_ids;
   386 		}
   387 		}
   387 
   388 
   388 		$site_ids = array_map( 'intval', $site_ids );
   389 		$site_ids = array_map( 'intval', $site_ids );
   389 
   390 
       
   391 		if ( $this->query_vars['update_site_meta_cache'] ) {
       
   392 			wp_lazyload_site_meta( $site_ids );
       
   393 		}
       
   394 
   390 		if ( 'ids' === $this->query_vars['fields'] ) {
   395 		if ( 'ids' === $this->query_vars['fields'] ) {
   391 			$this->sites = $site_ids;
   396 			$this->sites = $site_ids;
   392 
   397 
   393 			return $this->sites;
   398 			return $this->sites;
   394 		}
   399 		}
   395 
   400 
   396 		// Prime site network caches.
   401 		// Prime site network caches.
   397 		if ( $this->query_vars['update_site_cache'] ) {
   402 		if ( $this->query_vars['update_site_cache'] ) {
   398 			_prime_site_caches( $site_ids, $this->query_vars['update_site_meta_cache'] );
   403 			_prime_site_caches( $site_ids, false );
   399 		}
   404 		}
   400 
   405 
   401 		// Fetch full site objects from the primed cache.
   406 		// Fetch full site objects from the primed cache.
   402 		$_sites = array();
   407 		$_sites = array();
   403 		foreach ( $site_ids as $site_id ) {
   408 		foreach ( $site_ids as $site_id ) {
   624 			$this->sql_clauses['where']['search'] = $this->get_search_sql( $this->query_vars['search'], $search_columns );
   629 			$this->sql_clauses['where']['search'] = $this->get_search_sql( $this->query_vars['search'], $search_columns );
   625 		}
   630 		}
   626 
   631 
   627 		$date_query = $this->query_vars['date_query'];
   632 		$date_query = $this->query_vars['date_query'];
   628 		if ( ! empty( $date_query ) && is_array( $date_query ) ) {
   633 		if ( ! empty( $date_query ) && is_array( $date_query ) ) {
   629 			$this->date_query                         = new WP_Date_Query( $date_query, 'registered' );
   634 			$this->date_query = new WP_Date_Query( $date_query, 'registered' );
       
   635 
       
   636 			// Strip leading 'AND'.
   630 			$this->sql_clauses['where']['date_query'] = preg_replace( '/^\s*AND\s*/', '', $this->date_query->get_sql() );
   637 			$this->sql_clauses['where']['date_query'] = preg_replace( '/^\s*AND\s*/', '', $this->date_query->get_sql() );
   631 		}
   638 		}
   632 
   639 
   633 		$join    = '';
   640 		$join    = '';
   634 		$groupby = '';
   641 		$groupby = '';
   644 			}
   651 			}
   645 		}
   652 		}
   646 
   653 
   647 		$where = implode( ' AND ', $this->sql_clauses['where'] );
   654 		$where = implode( ' AND ', $this->sql_clauses['where'] );
   648 
   655 
   649 		$clauses = array( 'fields', 'join', 'where', 'orderby', 'limits', 'groupby' );
   656 		$pieces = array( 'fields', 'join', 'where', 'orderby', 'limits', 'groupby' );
   650 
   657 
   651 		/**
   658 		/**
   652 		 * Filters the site query clauses.
   659 		 * Filters the site query clauses.
   653 		 *
   660 		 *
   654 		 * @since 4.6.0
   661 		 * @since 4.6.0
   655 		 *
   662 		 *
   656 		 * @param string[]      $clauses An associative array of site query clauses.
   663 		 * @param string[]      $clauses {
       
   664 		 *     Associative array of the clauses for the query.
       
   665 		 *
       
   666 		 *     @type string $fields   The SELECT clause of the query.
       
   667 		 *     @type string $join     The JOIN clause of the query.
       
   668 		 *     @type string $where    The WHERE clause of the query.
       
   669 		 *     @type string $orderby  The ORDER BY clause of the query.
       
   670 		 *     @type string $limits   The LIMIT clause of the query.
       
   671 		 *     @type string $groupby  The GROUP BY clause of the query.
       
   672 		 * }
   657 		 * @param WP_Site_Query $query   Current instance of WP_Site_Query (passed by reference).
   673 		 * @param WP_Site_Query $query   Current instance of WP_Site_Query (passed by reference).
   658 		 */
   674 		 */
   659 		$clauses = apply_filters_ref_array( 'sites_clauses', array( compact( $clauses ), &$this ) );
   675 		$clauses = apply_filters_ref_array( 'sites_clauses', array( compact( $pieces ), &$this ) );
   660 
   676 
   661 		$fields  = isset( $clauses['fields'] ) ? $clauses['fields'] : '';
   677 		$fields  = isset( $clauses['fields'] ) ? $clauses['fields'] : '';
   662 		$join    = isset( $clauses['join'] ) ? $clauses['join'] : '';
   678 		$join    = isset( $clauses['join'] ) ? $clauses['join'] : '';
   663 		$where   = isset( $clauses['where'] ) ? $clauses['where'] : '';
   679 		$where   = isset( $clauses['where'] ) ? $clauses['where'] : '';
   664 		$orderby = isset( $clauses['orderby'] ) ? $clauses['orderby'] : '';
   680 		$orderby = isset( $clauses['orderby'] ) ? $clauses['orderby'] : '';
   686 		$this->sql_clauses['from']    = "FROM $wpdb->blogs $join";
   702 		$this->sql_clauses['from']    = "FROM $wpdb->blogs $join";
   687 		$this->sql_clauses['groupby'] = $groupby;
   703 		$this->sql_clauses['groupby'] = $groupby;
   688 		$this->sql_clauses['orderby'] = $orderby;
   704 		$this->sql_clauses['orderby'] = $orderby;
   689 		$this->sql_clauses['limits']  = $limits;
   705 		$this->sql_clauses['limits']  = $limits;
   690 
   706 
   691 		$this->request = "
   707 		// Beginning of the string is on a new line to prevent leading whitespace. See https://core.trac.wordpress.org/ticket/56841.
   692 			{$this->sql_clauses['select']}
   708 		$this->request =
   693 			{$this->sql_clauses['from']}
   709 			"{$this->sql_clauses['select']}
   694 			{$where}
   710 			 {$this->sql_clauses['from']}
   695 			{$this->sql_clauses['groupby']}
   711 			 {$where}
   696 			{$this->sql_clauses['orderby']}
   712 			 {$this->sql_clauses['groupby']}
   697 			{$this->sql_clauses['limits']}
   713 			 {$this->sql_clauses['orderby']}
   698 		";
   714 			 {$this->sql_clauses['limits']}";
   699 
   715 
   700 		if ( $this->query_vars['count'] ) {
   716 		if ( $this->query_vars['count'] ) {
   701 			return (int) $wpdb->get_var( $this->request );
   717 			return (int) $wpdb->get_var( $this->request );
   702 		}
   718 		}
   703 
   719 
   744 	 * @return string Search SQL.
   760 	 * @return string Search SQL.
   745 	 */
   761 	 */
   746 	protected function get_search_sql( $search, $columns ) {
   762 	protected function get_search_sql( $search, $columns ) {
   747 		global $wpdb;
   763 		global $wpdb;
   748 
   764 
   749 		if ( false !== strpos( $search, '*' ) ) {
   765 		if ( str_contains( $search, '*' ) ) {
   750 			$like = '%' . implode( '%', array_map( array( $wpdb, 'esc_like' ), explode( '*', $search ) ) ) . '%';
   766 			$like = '%' . implode( '%', array_map( array( $wpdb, 'esc_like' ), explode( '*', $search ) ) ) . '%';
   751 		} else {
   767 		} else {
   752 			$like = '%' . $wpdb->esc_like( $search ) . '%';
   768 			$like = '%' . $wpdb->esc_like( $search ) . '%';
   753 		}
   769 		}
   754 
   770