diff --git a/README b/README
deleted file mode 100644
index 020453c..0000000
--- a/README
+++ /dev/null
@@ -1,25 +0,0 @@
-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.
-
-Example usage:
-
-$query = new WP_Query_Multisite( array('post_type' => 'post' ) );
-while($query->have_posts()) : $query->the_post();
- echo $blog_id . get_the_title() . "
";
-endwhile;
-wp_reset_postdata();
-
-To modify what sites are queried, create a 'sites' element 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.
-
-EX:
-
-$args = array(
- 'post_type' => 'post',
- 'sites' => array(
- 'sites__in' => array( 1, 2, 3, 5)
- )
-);
-$query = new WP_Query_Multisite( $args );
-while($query->have_posts()) : $query->the_post();
- echo $blog_id . get_the_title() . "
";
-endwhile;
-wp_reset_postdata();
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..ca32ba0
--- /dev/null
+++ b/README.md
@@ -0,0 +1,44 @@
+# WordPress Query Multisite
+
+This is a custom version of [WP_Query_Multisite](https://github.com/ericandrewlewis/WP_Query_Multisite), by [ericandrewlewis](https://github.com/ericandrewlewis), to support multisite post queries but without changing the class declaration, we will use the good ol' **WP_Query**. Just by entering the custom query var **multisite => 1** on your query args and your query is now global.
+
+-----------------
+
+## Example usage
+
+```php
+$query = new WP_Query( array('multisite' => '1' ) );
+while($query->have_posts()) : $query->the_post();
+ echo $blog_id . get_the_title() . "
";
+endwhile;
+wp_reset_postdata();
+```
+
+To modify what sites are queried, create a 'sites' element 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.
+
+```php
+$args = array(
+ 'multisite' => 1,
+ 'sites__in' => array( 1, 2, 3, 5)
+);
+$query = new WP_Query( $args );
+while($query->have_posts()) : $query->the_post();
+ echo $blog_id . get_the_title() . "
";
+endwhile;
+wp_reset_postdata();
+```
+
+### Automatic multisite search example
+
+On your functions.php:
+
+```php
+include_once(TEMPLATEPATH . '/path/to/multisite-query.php');
+
+function my_multisite_search($query) {
+ if(!is_admin() && $query->is_main_query() && $query->is_search) {
+ $query->set('multisite', 1);
+ }
+}
+add_action('pre_get_posts', 'my_multisite_search');
+```
\ No newline at end of file
diff --git a/index.php b/index.php
index 328d192..2369319 100644
--- a/index.php
+++ b/index.php
@@ -1,100 +1,123 @@
args = $args;
- $this->parse_multisite_args();
- $this->add_filters();
- $this->query($args);
- $this->remove_filters();
+class WP_Query_Multisite {
- }
-
- function parse_multisite_args() {
- global $wpdb;
-
- $site_IDs = $wpdb->get_col( "select blog_id from $wpdb->blogs" );
-
- if ( isset( $this->args['sites']['sites__not_in'] ) )
- foreach($site_IDs as $key => $site_ID )
- if (in_array($site_ID, $this->args['sites']['sites__not_in']) ) unset($site_IDs[$key]);
-
- if ( isset( $this->args['sites']['sites__in'] ) )
- foreach($site_IDs as $key => $site_ID )
- if ( ! in_array($site_ID, $this->args['sites']['sites__in']) )
- unset($site_IDs[$key]);
-
-
- $site_IDs = array_values($site_IDs);
- $this->sites_to_query = $site_IDs;
+ function __construct() {
+ add_filter('query_vars', array($this, 'query_vars'));
+ add_action('pre_get_posts', array($this, 'pre_get_posts'), 100);
+ add_filter('posts_clauses', array($this, 'posts_clauses'), 10, 2);
+ add_filter('posts_request', array($this, 'posts_request'), 10, 2);
+ add_action('the_post', array($this, 'the_post'));
+ add_action('loop_end', array($this, 'loop_end'));
}
- function add_filters() {
-
- add_filter('posts_request', array(&$this, 'create_and_unionize_select_statements') );
- add_filter('posts_fields', array(&$this, 'add_site_ID_to_posts_fields') );
- add_action('the_post', array(&$this, 'switch_to_blog_while_in_loop'));
-
+ function query_vars($vars) {
+ $vars[] = 'multisite';
+ $vars[] = 'sites__not_in';
+ $vars[] = 'sites__in';
+ return $vars;
}
- function remove_filters() {
- remove_filter('posts_request', array(&$this, 'create_and_unionize_select_statements') );
- remove_filter('posts_fields', array(&$this, 'add_site_ID_to_posts_fields') );
+ function pre_get_posts($query) {
+ if($query->get('multisite')) {
+
+ global $wpdb, $blog_id;
+
+ $this->loop_end = false;
+ $this->blog_id = $blog_id;
+
+ $site_IDs = $wpdb->get_col( "select blog_id from $wpdb->blogs" );
+
+ if ( $query->get('sites__not_in') )
+ foreach($site_IDs as $key => $site_ID )
+ if (in_array($site_ID, $query->get('sites__not_in')) ) unset($site_IDs[$key]);
+
+ if ( $query->get('sites__in') )
+ foreach($site_IDs as $key => $site_ID )
+ if ( ! in_array($site_ID, $query->get('sites__in')) )
+ unset($site_IDs[$key]);
+
+ $site_IDs = array_values($site_IDs);
+
+ $this->sites_to_query = $site_IDs;
+ }
}
- function create_and_unionize_select_statements($sql) {
- global $wpdb;
-
- $root_site_db_prefix = $wpdb->prefix;
-
- $page = $this->args['paged'] ? $this->args['paged'] : 1;
- $posts_per_page = $this->args['posts_per_page'] ? $this->args['posts_per_page'] : 10;
-
- foreach ($this->sites_to_query as $key => $site_ID) :
-
- switch_to_blog($site_ID);
-
- $new_sql_select = str_replace($root_site_db_prefix, $wpdb->prefix, $sql);
- $new_sql_select = preg_replace("/ LIMIT ([0-9]+), ".$posts_per_page."/", "", $new_sql_select);
- $new_sql_select = str_replace("SQL_CALC_FOUND_ROWS ", "", $new_sql_select);
- $new_sql_select = str_replace("# AS site_ID", "'$site_ID' AS site_ID", $new_sql_select);
- $new_sql_select = preg_replace( '/ORDER BY ([A-Za-z0-9_.]+)/', "", $new_sql_select);
- $new_sql_select = str_replace(array("DESC", "ASC"), "", $new_sql_select);
-
- $new_sql_selects[] = $new_sql_select;
- restore_current_blog();
-
- endforeach;
-
- if ( $posts_per_page > 0 ) {
- $skip = ( $page * $posts_per_page ) - $posts_per_page;
- $limit = "LIMIT $skip, $posts_per_page";
- } else {
- $limit = '';
- }
- $orderby = "tables.post_date DESC";
- $new_sql = "SELECT SQL_CALC_FOUND_ROWS tables.* FROM ( " . implode(" UNION ", $new_sql_selects) . ") tables ORDER BY $orderby " . $limit;
-
- return $new_sql;
+ function posts_clauses($clauses, $query) {
+ if($query->get('multisite')) {
+ global $wpdb;
+
+ // Start new mysql selection to replace wp_posts on posts_request hook
+ $this->ms_select = array();
+
+ $root_site_db_prefix = $wpdb->prefix;
+ foreach($this->sites_to_query as $site_ID) {
+
+ switch_to_blog($site_ID);
+
+ $ms_select = $clauses['join'] . ' WHERE 1=1 '. $clauses['where'];
+
+ if($clauses['groupby'])
+ $ms_select .= ' GROUP BY ' . $clauses['groupby'];
+
+ $ms_select = str_replace($root_site_db_prefix, $wpdb->prefix, $ms_select);
+ $ms_select = " SELECT $wpdb->posts.*, '$site_ID' as site_ID FROM $wpdb->posts $ms_select ";
+
+ $this->ms_select[] = $ms_select;
+
+ restore_current_blog();
+
+ }
+
+ // Clear join, where and groupby to populate with parsed ms select on posts_request hook;
+ $clauses['join'] = '';
+ $clauses['where'] = '';
+ $clauses['groupby'] = '';
+
+ // Orderby for tables (not wp_posts)
+ $clauses['orderby'] = str_replace($wpdb->posts, 'tables', $clauses['orderby']);
+
+ }
+ return $clauses;
}
-
- function add_site_ID_to_posts_fields($sql) {
- $sql_statements[] = $sql;
- $sql_statements[] = "# AS site_ID";
- return implode(', ', $sql_statements);
+
+ function posts_request($sql, $query) {
+
+ if($query->get('multisite')) {
+
+ global $wpdb;
+
+ // Clean up remanescent WHERE request
+ $sql = str_replace('WHERE 1=1', '', $sql);
+
+ // Multisite request
+ $sql = str_replace("$wpdb->posts.* FROM $wpdb->posts", 'tables.* FROM ( ' . implode(" UNION ", $this->ms_select) . ' ) tables', $sql);
+
+ }
+
+ return $sql;
}
-
- function switch_to_blog_while_in_loop($post) {
+
+ function the_post($post) {
global $blog_id;
- if($post->site_ID && $blog_id != $post->site_ID )
+
+ if( isset( $this->loop_end ) && !$this->loop_end && $post->site_ID && $blog_id !== $post->site_ID) {
switch_to_blog($post->site_ID);
- else
- restore_current_blog();
+ }
+
+ }
+
+ function loop_end($query) {
+ global $switched;
+ if($query->get('multisite')) {
+ $this->loop_end = true;
+ if($switched) {
+ switch_to_blog($this->blog_id);
+ }
+ }
}
}
+new WP_Query_Multisite();
+
?>