├── README.md └── index.php /README.md: -------------------------------------------------------------------------------- 1 | `WP_Query_Multisite` is a subclass of `WP_Query`, WordPress' post querying class. The class does everything behind the scenes, so the only change you make to query multisite is the in the class declaration expression. 2 | 3 | 4 | Example usage: 5 | 6 | ```php 7 | $query = new WP_Query_Multisite( array( 'post_type' => 'post' ) ); 8 | 9 | while( $query->have_posts() ) : $query->the_post(); 10 | echo $blog_id . get_the_title() . "
"; 11 | endwhile; 12 | 13 | wp_reset_postdata(); 14 | ``` 15 | 16 | To modify what sites are queried, create a `sites` key in the `$args` in the constructor parameter, with a sub-element of either `sites__in` or `sites__not_in`, which will be an `array` similar to `posts__in` in the `WP_Query` object. 17 | 18 | Example usage: 19 | 20 | ```php 21 | $args = array( 22 | 'post_type' => 'post', 23 | 'sites' => array( 24 | 'sites__in' => array( 1, 2, 3, 5 ) 25 | ) 26 | ); 27 | 28 | $query = new WP_Query_Multisite( $args ); 29 | 30 | while( $query->have_posts() ) : $query->the_post(); 31 | echo $blog_id . get_the_title() . "
"; 32 | endwhile; 33 | 34 | wp_reset_postdata(); 35 | ``` 36 | 37 | # Alternative 38 | We do want to suggest that this [version / fork](https://github.com/miguelpeixe/WP_Query_Multisite) uses `pre_get_post` and may be a better solution for you. This way you can keep using the good 'ol `WP_Query` without editing any theme files. 39 | [https://github.com/miguelpeixe/WP_Query_Multisite](https://github.com/miguelpeixe/WP_Query_Multisite) 40 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | args = $args; 10 | $this->parse_multisite_args(); 11 | $this->add_filters(); 12 | $this->query($args); 13 | $this->remove_filters(); 14 | 15 | } 16 | 17 | function parse_multisite_args() { 18 | global $wpdb; 19 | 20 | $site_IDs = $wpdb->get_col( "select blog_id from $wpdb->blogs" ); 21 | 22 | if ( isset( $this->args['sites']['sites__not_in'] ) ) 23 | foreach($site_IDs as $key => $site_ID ) 24 | if (in_array($site_ID, $this->args['sites']['sites__not_in']) ) unset($site_IDs[$key]); 25 | 26 | if ( isset( $this->args['sites']['sites__in'] ) ) 27 | foreach($site_IDs as $key => $site_ID ) 28 | if ( ! in_array($site_ID, $this->args['sites']['sites__in']) ) 29 | unset($site_IDs[$key]); 30 | 31 | 32 | $site_IDs = array_values($site_IDs); 33 | $this->sites_to_query = $site_IDs; 34 | } 35 | 36 | function add_filters() { 37 | 38 | add_filter('posts_request', array(&$this, 'create_and_unionize_select_statements') ); 39 | add_filter('posts_fields', array(&$this, 'add_site_ID_to_posts_fields') ); 40 | add_action('the_post', array(&$this, 'switch_to_blog_while_in_loop')); 41 | add_action('loop_end', array(&$this, 'restore_current_blog_after_loop')); 42 | 43 | } 44 | function remove_filters() { 45 | remove_filter('posts_request', array(&$this, 'create_and_unionize_select_statements') ); 46 | remove_filter('posts_fields', array(&$this, 'add_site_ID_to_posts_fields') ); 47 | 48 | } 49 | 50 | function create_and_unionize_select_statements( $sql ) { 51 | global $wpdb; 52 | 53 | $root_site_db_prefix = $wpdb->prefix; 54 | 55 | $page = isset( $this->args['paged'] ) ? $this->args['paged'] : 1; 56 | $posts_per_page = isset( $this->args['posts_per_page'] ) ? $this->args['posts_per_page'] : 10; 57 | $s = ( isset( $this->args['s'] ) ) ? $this->args['s'] : false; 58 | 59 | foreach ($this->sites_to_query as $key => $site_ID) : 60 | 61 | switch_to_blog( $site_ID ); 62 | 63 | $new_sql_select = str_replace($root_site_db_prefix, $wpdb->prefix, $sql); 64 | $new_sql_select = preg_replace("/ LIMIT ([0-9]+), ".$posts_per_page."/", "", $new_sql_select); 65 | $new_sql_select = str_replace("SQL_CALC_FOUND_ROWS ", "", $new_sql_select); 66 | $new_sql_select = str_replace("# AS site_ID", "'$site_ID' AS site_ID", $new_sql_select); 67 | $new_sql_select = preg_replace( '/ORDER BY ([A-Za-z0-9_.]+)/', "", $new_sql_select); 68 | $new_sql_select = str_replace(array("DESC", "ASC"), "", $new_sql_select); 69 | 70 | if( $s ){ 71 | $new_sql_select = str_replace("LIKE '%{$s}%' , wp_posts.post_date", "", $new_sql_select); //main site id 72 | $new_sql_select = str_replace("LIKE '%{$s}%' , wp_{$site_ID}_posts.post_date", "", $new_sql_select); // all other sites 73 | } 74 | 75 | $new_sql_selects[] = $new_sql_select; 76 | restore_current_blog(); 77 | 78 | endforeach; 79 | 80 | if ( $posts_per_page > 0 ) { 81 | $skip = ( $page * $posts_per_page ) - $posts_per_page; 82 | $limit = "LIMIT $skip, $posts_per_page"; 83 | } else { 84 | $limit = ''; 85 | } 86 | $orderby = "tables.post_date DESC"; 87 | $new_sql = "SELECT SQL_CALC_FOUND_ROWS tables.* FROM ( " . implode(" UNION ", $new_sql_selects) . ") tables ORDER BY $orderby " . $limit; 88 | 89 | return $new_sql; 90 | } 91 | 92 | function add_site_ID_to_posts_fields( $sql ) { 93 | $sql_statements[] = $sql; 94 | $sql_statements[] = "# AS site_ID"; 95 | return implode(', ', $sql_statements); 96 | } 97 | 98 | function switch_to_blog_while_in_loop( $post ) { 99 | global $blog_id; 100 | if($post->site_ID && $blog_id != $post->site_ID ) 101 | switch_to_blog($post->site_ID); 102 | else 103 | restore_current_blog(); 104 | } 105 | 106 | function restore_current_blog_after_loop() { 107 | restore_current_blog(); 108 | } 109 | } 110 | 111 | --------------------------------------------------------------------------------