Opened 2 years ago
Last modified 6 weeks ago
#56992 new defect (bug)
The Loop displays incorrect data for queries started with `fields => 'id=>parent'`.
Reported by: | peterwilsoncc | Owned by: | |
---|---|---|---|
Milestone: | 6.8 | Priority: | normal |
Severity: | normal | Version: | 3.1 |
Component: | Query | Keywords: | has-patch has-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 (3)
This ticket was mentioned in PR #7985 on WordPress/wordpress-develop by @juzar.
6 weeks ago
#1
- Keywords has-patch has-unit-tests added; needs-patch needs-unit-tests removed
#2
@
6 weeks ago
@peterwilsoncc, Yes the global post object set is wrong if used ids=>parent
for fields, it creates an empty WP_Post object and assigns that to the global post.
I have fixed the issue in this PR: https://github.com/WordPress/wordpress-develop/pull/7985
with unit test added as above.
The next_post function assumes a WP_Post object, which isn't always the case. When a standard object with ID and parent is provided, setup_postdata creates an empty WP_Post object with just the ID.
This PR resolves the issue by passing only the post ID from next_post when the object is not a WP_Post.
Trac ticket: https://core.trac.wordpress.org/ticket/56992