[wp-trac] [WordPress Trac] #31355: Custom hierarchical post type 404s when `get_queried_object` is called too early
WordPress Trac
noreply at wordpress.org
Tue Feb 17 03:30:21 UTC 2015
#31355: Custom hierarchical post type 404s when `get_queried_object` is called too
early
--------------------------+-----------------------------
Reporter: gradyetc | Owner:
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Query | Version: 3.0
Severity: normal | Keywords:
Focuses: |
--------------------------+-----------------------------
I uncovered some confusing behavior while debugging a recent plugin issue
-- a hierarchical custom post type was 404'ing unexpectedly. I tracked the
problem down to the usage of `is_singular()` in a `parse_query` callback.
== Steps to Reproduce ==
1. Enable pretty permalinks
2. Register a hierarchical custom post type
3. Hook in to the `parse_query` hook and call `get_queried_object()` or
any function that sets `$query->queried_object_id`, e.g.:
{{{
<?php
function custom_parse_query( $query ) {
// Will be NULL
$post = get_queried_object();
// Will throw PHP Notice and return false
if ( $query->is_singular( 'foo' ) ) {
// Whip up some custom query magic
}
}
add_filter( 'parse_query', 'custom_parse_query' );
}}}
4. Get 404s for all singular requests for that post type
Root cause is special handling of `queried_object` / `queried_object_id`
for single page requests in
[https://github.com/WordPress/WordPress/blob/master/wp-
includes/query.php#L1772-L1777 WP_Query#parse_query] and
[https://github.com/WordPress/WordPress/blob/master/wp-
includes/query.php#L2604-L2606 WP_Query#get_posts].
I searched for warnings about using conditional tags inside `WP_Query`
hook callbacks (e.g. `parse_query`, `pre_get_posts`, etc.) and found this
in [http://codex.wordpress.org/Conditional_Tags the Codex page on
conditional tags]:
Warning: You can only use conditional query tags after the
posts_selection action hook in WordPress (the wp action hook is the first
one through which you can use these conditionals). For themes, this means
the conditional tag will never work properly if you are using it in the
body of functions.php, i.e. outside of a function.
However: if you have a reference to the query object (for example,
from within the parse_query or pre_get_posts hooks), you can use the
WP_Query conditional methods (eg: $query->is_search())
Which is misleading IMHO; while some of them work (`is_archive()`,
`is_tax()`), `is_singular()` and other single post-related checks will not
until `WP_Query#get_posts` has finished and the queried object can be
determined.
Some thoughts...
* A quick fix would be to unset `queried_post_id` in
`WP_Query#get_queried_post()` if it was called too early.
* A better approach might be to calculate singular request IDs earlier so
that conditional checks would return meaningful results in query hook
callbacks. If we're willing to make the extra query to determine the
queried page in `WP_Query#parse_query` (via `get_page_by_path()`), why not
do the same for all post types?
* Otherwise, we should update the docs to clarify the reality:
`$query->is_single()`, `$query->is_singular()`, `$query->is_page()` and
`$query->is_attachment()` should not be used in callbacks for
`parse_query`, `pre_get_posts`, etc.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/31355>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list