REST API: Avoid duplicated query in post collections.

Avoid duplicated query when retrieving empty posts collections by adding a check if the page is more than 1. 

Props furi3r, gdetassigny, TimothyBlynJacobs, spacedmonkey. 
Fixes #55677.



git-svn-id: https://develop.svn.wordpress.org/trunk@53498 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Jonny Harris
2022-06-14 12:40:29 +00:00
parent a067d588c3
commit 219927c11b
3 changed files with 64 additions and 7 deletions

View File

@@ -388,7 +388,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
$page = (int) $query_args['paged'];
$total_posts = $posts_query->found_posts;
if ( $total_posts < 1 ) {
if ( $total_posts < 1 && $page > 1 ) {
// Out-of-bounds, run the query again without LIMIT for total count.
unset( $query_args['paged'] );

View File

@@ -29,6 +29,11 @@ class WP_Test_REST_Attachments_Controller extends WP_Test_REST_Post_Type_Control
*/
private $test_file2;
/**
* @var array The recorded posts query clauses.
*/
protected $posts_clauses;
public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
self::$superadmin_id = $factory->user->create(
array(
@@ -85,6 +90,19 @@ class WP_Test_REST_Attachments_Controller extends WP_Test_REST_Post_Type_Control
$orig_file2 = DIR_TESTDATA . '/images/codeispoetry.png';
$this->test_file2 = get_temp_dir() . 'codeispoetry.png';
copy( $orig_file2, $this->test_file2 );
add_filter( 'rest_pre_dispatch', array( $this, 'wpSetUpBeforeRequest' ), 10, 3 );
add_filter( 'posts_clauses', array( $this, 'save_posts_clauses' ), 10, 2 );
}
public function wpSetUpBeforeRequest( $result ) {
$this->posts_clauses = array();
return $result;
}
public function save_posts_clauses( $clauses ) {
$this->posts_clauses[] = $clauses;
return $clauses;
}
public function tear_down() {
@@ -619,6 +637,48 @@ class WP_Test_REST_Attachments_Controller extends WP_Test_REST_Post_Type_Control
$this->assertSame( $id2, $data[0]['id'] );
}
/**
* @ticket 55677
*/
public function test_get_items_avoid_duplicated_count_query_if_no_items() {
$request = new WP_REST_Request( 'GET', '/wp/v2/media' );
$request->set_param( 'media_type', 'video' );
$response = rest_get_server()->dispatch( $request );
$this->assertCount( 1, $this->posts_clauses );
$headers = $response->get_headers();
$this->assertSame( 0, $headers['X-WP-Total'] );
$this->assertSame( 0, $headers['X-WP-TotalPages'] );
}
/**
* @ticket 55677
*/
public function test_get_items_with_empty_page_runs_count_query_after() {
$this->factory->attachment->create_object(
$this->test_file,
0,
array(
'post_date' => '2022-06-12T00:00:00Z',
'post_mime_type' => 'image/jpeg',
'post_excerpt' => 'A sample caption',
)
);
$request = new WP_REST_Request( 'GET', '/wp/v2/media' );
$request->set_param( 'media_type', 'image' );
$request->set_param( 'page', 2 );
$response = rest_get_server()->dispatch( $request );
$this->assertCount( 2, $this->posts_clauses );
$this->assertErrorResponse( 'rest_post_invalid_page_number', $response, 400 );
}
public function test_get_item() {
$attachment_id = $this->factory->attachment->create_object(
$this->test_file,

View File

@@ -1385,8 +1385,7 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
$response = rest_get_server()->dispatch( $request );
$this->assertCount( 0, $response->get_data() );
// FIXME Since this request returns zero posts, the query is executed twice.
$this->assertCount( 2, $this->posts_clauses );
$this->assertCount( 1, $this->posts_clauses );
$this->posts_clauses = array_slice( $this->posts_clauses, 0, 1 );
$this->assertPostsWhere( " AND {posts}.ID IN (0) AND {posts}.post_type = 'post' AND (({posts}.post_status = 'publish'))" );
@@ -1417,8 +1416,7 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
$response = rest_get_server()->dispatch( $request );
$this->assertCount( 0, $response->get_data() );
// FIXME Since this request returns zero posts, the query is executed twice.
$this->assertCount( 2, $this->posts_clauses );
$this->assertCount( 1, $this->posts_clauses );
$this->posts_clauses = array_slice( $this->posts_clauses, 0, 1 );
$this->assertPostsWhere( " AND {posts}.ID IN (0) AND {posts}.post_type = 'post' AND (({posts}.post_status = 'publish'))" );
@@ -1436,8 +1434,7 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
$response = rest_get_server()->dispatch( $request );
$this->assertCount( 0, $response->get_data() );
// FIXME Since this request returns zero posts, the query is executed twice.
$this->assertCount( 2, $this->posts_clauses );
$this->assertCount( 1, $this->posts_clauses );
$this->posts_clauses = array_slice( $this->posts_clauses, 0, 1 );
$this->assertPostsWhere( " AND {posts}.ID IN (0) AND {posts}.post_type = 'post' AND (({posts}.post_status = 'publish'))" );