[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