Make WordPress Core

Opened 11 years ago

Last modified 4 years ago

#27015 new defect (bug)

WP_Query::get_queried_object() does not always work in 'pre_get_posts'

Reported by: bcworkz's profile bcworkz Owned by:
Milestone: Future Release Priority: normal
Severity: normal Version: 3.8
Component: Query Keywords: has-patch needs-unit-tests needs-refresh
Focuses: Cc:

Description (last modified by SergeyBiryukov)

Related: #26627
The referenced ticket fixes the situation for categories. Inline docs indicate the method returns objects for the following query types: category, tag, taxonomy, posts page, single post, page, author.

Some of these work, some do not. This became apparent from the forums:
http://wordpress.org/support/topic/get_queried_object-no-longer-working-with-pre_get_posts-and-pretty-permalinks/
Props jeich

Test setup.
Trunk at r27067 used. (and 3.7 for regression check)
Default setup of fresh install except for the following as plugin:

  • Hook 'pre_get_posts' and dump get_queried_object return if it is_main_query
  • Add custom taxonomy and associate with posts
  • Register CPT

Change permalink setting to complete CPT rewrite registration

Also modify the DB as follows to test various query types:

  • Add a tag to the Hello World post.
  • Add a custom taxonomy term to the Hello World post.
  • Add a CPT post

The site was browsed through various pages using the default (none) permalink, then the month and name permalink. The result of getting a queried object was recorded:

no permalink month and name
uncategorized category stdClass object stdClass object
tag archive NULL NULL
taxonomy term archive stdClass object stdClass object
CPT archive stdClass object stdClass object
single post NULL NULL
single CPT NULL NULL
page NULL WP_Post object
author archive WP_User object False
posts page WP_Post object WP_Post object

NULLs indicate failure of get_queried_object(). Except for tag archive, all NULLs returned are due to regression prior to 3.7. Why the tag archive failed in 3.8 is unclear, but the proposed patch addresses this issue as well as all other NULL returns.

For those that don't know, the reason for different results with pretty permalinks enabled is different query vars are defined when rewrite rules are applied. The default no pretty permalinks does not use rewrite rules and the query vars can only be what is parsed from the request.

Attachments (7)

27015.patch (2.4 KB) - added by bcworkz 11 years ago.
is_category.patch (479 bytes) - added by tivnet 11 years ago.
get_queried_object may be NULL in is_category
27015.2.patch (1.8 KB) - added by bcworkz 11 years ago.
Refreshed after Trac#27362
27015.3.patch (2.8 KB) - added by mattonomics 11 years ago.
27015.tests.patch (30.4 KB) - added by mattonomics 11 years ago.
27015.tests.2.patch (30.1 KB) - added by mattonomics 11 years ago.
Cleaned up unit test formatting.
27015.diff (33.1 KB) - added by wonderboymusic 11 years ago.

Download all attachments as: .zip

Change History (23)

@bcworkz
11 years ago

#1 @bcworkz
11 years ago

  • Keywords has-patch added

Almost forgot!

@tivnet
11 years ago

get_queried_object may be NULL in is_category

#2 @tivnet
11 years ago

To reproduce the error that my patch fixes:
Call is_category('example') within a pre_get_posts action, and go to a non-existing URL.

#3 follow-up: @SergeyBiryukov
11 years ago

  • Description modified (diff)
  • Version changed from trunk to 3.8

Related: #20519, #21394.

#4 in reply to: ↑ 3 ; follow-up: @bcworkz
11 years ago

Replying to tivnet:

To reproduce the error that my patch fixes:
Call is_category('example') within a pre_get_posts action, and go to a non-existing URL.

Are you sure this is the correct place for this patch? This ticket is for get_queried_object() issues. You are addressing issues with is_category(). They are obviously related, but I believe yours is a separate issue. This ticket is trying to resolve many cases where get_queried_object() inappropriately returns NULL. Even if this issue is fixed, there will be cases where NULL is properly returned, such as your condition.

To clarify reproducing your error, people need to make a non-existing category request, any non-existing URL will not necessarily do it. And have WP_DEBUG set to true of course.

Replying to SergeyBiryukov:

Description modified (diff)

Thx Sergey! Frustrating seeing one's errors and not being able to do anything about it.

#5 in reply to: ↑ 4 @tivnet
11 years ago

Replying to bcworkz:
No, I am not 100% sure. I started submitting a new ticket, and Trac suggested to look at this one.
I guess, if I make a separate ticket, there will be a "duplicate of" notice.

@SergeyBiryukov : should I make a separate issue? Thank you!

@bcworkz
11 years ago

Refreshed after Trac#27362

#6 @bcworkz
11 years ago

Refreshed after #27362 fixed tag portion. The single post, page, CPT and author archive issues remain.

#7 @wonderboymusic
11 years ago

  • Keywords needs-unit-tests added
  • Milestone changed from Awaiting Review to 4.0

bcworkz, thanks for the report, will definitely review this

#8 @mattonomics
11 years ago

@wonderboymusic @bcworkz I've been working on this for about a day and a half. I've fixed up an issue or two with the patch and am writing out the (many, many) unit tests. Should have something in the next day or so.

I should note that while pre_get_posts is the action in the title of this ticket, the appropriate action to test all of this on would be parse_query. That is the first point at which everything should be working as expected.

@mattonomics
11 years ago

Cleaned up unit test formatting.

#9 @wonderboymusic
11 years ago

27015.diff combines the patches and makes the errors go away when the entire suite runs.

The logic in this block $this->get( 'pagename' ) || $this->get( 'name' ) is producing null for $this->queried_object and $this->queried_object_id.

So, in your tests, make sure you are checking for not empty for those values.

#10 @wonderboymusic
11 years ago

  • Keywords needs-refresh added
  • Milestone changed from 4.0 to Future Release

If this can be made pristine soon, might be possible for 4.0 - currently, the patch explodes

This ticket was mentioned in Slack in #core by helen. View the logs.


10 years ago

This ticket was mentioned in Slack in #core by swissspidy. View the logs.


8 years ago

#13 @motherofdragons
8 years ago

after active woocommerce 3.1.1,on static page wiht get_header() and get_footer(),the page got the same error.
all the solutions didn't work.
so I add below code in \wp-includes\class-wp-query.php
just after:

$page_obj = $this->get_queried_object();

my code:

if(empty($page_obj)) return false;

the error went away.I don't know if there is any other effect ,hope somebody can fix this bug later.

my wordpress version is :4.7.4

Last edited 8 years ago by motherofdragons (previous) (diff)

This ticket was mentioned in Slack in #core by xkungfu. View the logs.


8 years ago

#15 @SergeyBiryukov
4 years ago

#51829 was marked as a duplicate.

#16 @oglekler
4 years ago

I stumbled on the same notice. The notice appeared when wp-blog-header.php calls wp() function.

I've used filter 'pre_get_posts' for products in condition:

( is_shop() || is_front_page() )

and both functions call 'is_page()' which results in $page_obj is not an object.

I solved this for myself by reordered conditions in the if statement checking

isset( $query->query['post_type'] )

first.

Note: See TracTickets for help on using tickets.