Query: Allow plugins to supply post results instead of having WP_Query fetch them from the database.

Returning a non-null value from the new `posts_pre_query` filter will cause
`WP_Query` to skip its database query, so that posts data can be provided from
elsewhere. This is useful in cases where post data may be mirrored in a
separate location, such as an external search application.

Developers should note that the `WP_Query` properties generally used to
calculate pagination - specifically, `found_posts` and `max_num_pages`, which
are determined by default in `set_found_posts()` - must be provided explicitly
when using the `posts_pre_query` filter; since `WP_Query` will not be
contacting the database, it will have no access to `SELECT FOUND_ROWS()`.
The `WP_Query` instance is passed to `posts_pre_query` by reference, so that
these properties can be set manually if needed.

Props jpdavoutian, tlovett1.
Fixes #36687.

git-svn-id: https://develop.svn.wordpress.org/trunk@37692 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Boone Gorges
2016-06-14 01:59:25 +00:00
parent 3132836080
commit becae4f492
2 changed files with 87 additions and 37 deletions

View File

@@ -388,4 +388,28 @@ class Tests_Post_Query extends WP_UnitTestCase {
$actual_posts = $q->get_posts();
$this->assertEqualSets( $requested, $actual_posts );
}
/**
* @ticket 36687
*/
public function test_posts_pre_query_filter_should_bypass_database_query() {
global $wpdb;
add_filter( 'posts_pre_query', array( __CLASS__, 'filter_posts_pre_query' ) );
$num_queries = $wpdb->num_queries;
$q = new WP_Query( array(
'fields' => 'ids',
'no_found_rows' => true,
) );
remove_filter( 'posts_pre_query', array( __CLASS__, 'filter_posts_pre_query' ) );
$this->assertSame( $num_queries, $wpdb->num_queries );
$this->assertSame( array( 12345 ), $q->posts );
}
public static function filter_posts_pre_query( $posts ) {
return array( 12345 );
}
}