diff --git a/bin/install-wp-tests.sh b/bin/install-wp-tests.sh old mode 100644 new mode 100755 diff --git a/includes/classes/Indexable/Post/QueryIntegration.php b/includes/classes/Indexable/Post/QueryIntegration.php index 288c270309..2ab1f82466 100644 --- a/includes/classes/Indexable/Post/QueryIntegration.php +++ b/includes/classes/Indexable/Post/QueryIntegration.php @@ -51,7 +51,7 @@ public function __construct() { add_action( 'loop_end', array( $this, 'maybe_restore_blog' ), 10, 1 ); // Properly switch to blog if necessary - add_action( 'the_post', array( $this, 'maybe_switch_to_blog' ), 10, 1 ); + add_action( 'the_post', array( $this, 'maybe_switch_to_blog' ), 10, 2 ); // Sets the correct value for found_posts add_filter( 'found_posts', array( $this, 'found_posts' ), 10, 2 ); @@ -131,12 +131,21 @@ public function get_switched() { } /** - * Switch to the correct site if the post site id is different than the actual one + * Switch to the correct site if the post site id is different than the actual one. * - * @param WP_Post $post Post object + * Note: This function can bring a performance penalty in multisites with a high number of sites. + * + * @param WP_Post $post Post object + * @param WP_Query $query WP_Query instance. If null, the global query will be used. * @since 0.9 + * @since 3.6.2 `$query` parameter added. */ - public function maybe_switch_to_blog( $post ) { + public function maybe_switch_to_blog( $post, $query = null ) { + global $wp_query; + if ( ! $query ) { + $query = $wp_query; + } + if ( ! is_multisite() ) { // @codeCoverageIgnoreStart return; @@ -154,9 +163,15 @@ public function maybe_switch_to_blog( $post ) { $this->switched = $post->site_id; - remove_action( 'the_post', array( $this, 'maybe_switch_to_blog' ), 10, 1 ); + remove_action( 'the_post', array( $this, 'maybe_switch_to_blog' ), 10, 2 ); setup_postdata( $post ); - add_action( 'the_post', array( $this, 'maybe_switch_to_blog' ), 10, 1 ); + add_action( 'the_post', array( $this, 'maybe_switch_to_blog' ), 10, 2 ); + + if ( $this->switched && ! $query->in_the_loop ) { + restore_current_blog(); + + $this->switched = false; + } } } diff --git a/tests/php/indexables/TestPost.php b/tests/php/indexables/TestPost.php index 89e86a20b9..190df3c958 100644 --- a/tests/php/indexables/TestPost.php +++ b/tests/php/indexables/TestPost.php @@ -5983,14 +5983,22 @@ public function testMaybeSwitchToBlog() { // test the function. Try accessing the 2nd post from the 1st blog. $query_integration = new \ElasticPress\Indexable\Post\QueryIntegration(); + // This should not switch to the 2nd site because the query is not in the loop. + $query_integration->maybe_switch_to_blog( $blog_2_post, $query ); + + $this->assertFalse( $query_integration->get_switched() ); + + // To switch sites the query must be in the loop. + $query->in_the_loop = true; + // This should switch to the 2nd site. - $query_integration->maybe_switch_to_blog( $blog_2_post ); + $query_integration->maybe_switch_to_blog( $blog_2_post, $query ); $this->assertSame( $blog_2_post->site_id, $query_integration->get_switched() ); // Now we're in "switched" mode, try getting the post from the // 1st site, should switch back. - $query_integration->maybe_switch_to_blog( $blog_1_post ); + $query_integration->maybe_switch_to_blog( $blog_1_post, $query ); $this->assertSame( $blog_1_post->site_id, $query_integration->get_switched() );