Make WordPress Core

Opened 19 months ago

#56992 new defect (bug)

The Loop displays incorrect data for queries started with `fields => 'id=>parent'`.

Reported by: peterwilsoncc's profile peterwilsoncc Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 3.1
Component: Query Keywords: needs-patch needs-unit-tests
Focuses: Cc:

Description

Using the Loop on custom WP_Query objects started with fields => 'id=>parent' will set the global post object incorrectly. Instead of containing all data, the global post object will only contain the post's ID and parent fields. All other fields are the default value.

The following test demonstrates the issue:

<?php
public function test_the_loop_when_querying_post_parents_only() {
        $parent = self::factory()->post->create( array( 'post_type' => 'page' ) );
        $child  = self::factory()->post->create( array( 'post_type' => 'page', 'post_parent' => $parent ) );

        $query = new WP_Query(
                array(
                        'fields'    => 'id=>parent',
                        'post_type' => 'page',
                        'page_id'   => $child,
                )
        );

        $query->the_post();
        $global_post   = get_post( null, ARRAY_A );
        $specific_post = get_post( $child, ARRAY_A );

        $this->assertEqualSetsWithIndex( $global_post, $specific_post );
}

The cause of the error is within WP_Query::next_post() which assumes the WP_Query::$posts property contains full post objects which isn't nessesarily the cause if a sub-set of fields is requested. See the source code.

Due to #56948 the test above will currently throw an error on trunk but it will demonstrate the problem if you check out the 6.0 branch.

I suspect this has been an issue since the fields parameter was introduced in #14777 for version 3.1 but I am unable to test that far back due to PHP versions I have available on my local config.

Change History (0)

Note: See TracTickets for help on using tickets.