Skip to content

get_queried_object is not always working #53

@david-binda

Description

@david-binda

In bd00339 a code allowing WP_Query::get_posts() repeated call was introduced, but the WP_Query::get_posts() is not strictly idempotent, as there is some backward compatibility related logic and what's more, some query variable evaluation and modification logic which is changing the query_vars property of the class.

Eg.: passing author_name query variable leads to setting author query variable which is then used for determining the get_queried_object. See https://core.trac.wordpress.org/browser/tags/4.7/src/wp-includes/class-wp-query.php#L2121

Example failing code:

$my_query = new WP_Query( array( 'author_name' => 'existing-user-slug', 'es' => true ) );
$my_query->get_queried_object(); // Returns `false`.

vs.

$my_query = new WP_Query( array( 'author_name' => 'existing-user-slug', ) );
$my_query->get_queried_object(); // Returns author object.

Also, calling WP_Query::get_posts() multiple times, or even creating a new WP_Query object while passing query args to the constructor and then calling WP_Query::get_post() leads to performance issues in certain cases caused by unnecessarily complex SQL queries - due to the backward compatibility logic.

Again, an example:

$my_query = new WP_Query(
    array(
        'posts_per_page' => 10
        'cat' => $some_category_term_id, // This is a legacy query arg which gets extended in WP_Query::get_posts() function.
    )
);
$my_query = $latest_posts_query->get_posts(); // This triggers the `WP_Query::get_posts` again, but with moar query variables than just `cat` - those were backfilled during the `$my_query`'s object construction

Once the WP_Query::get_posts() have been called, either directly or through the constructor of the WP_Query when query args were passed to it, the array of posts should be accessed via WP_Query's posts property - as it 1) saves a SQL query 2) returns the expected set of posts

@mboynes I wonder, do you have any valid use case for calling WP_Query::get_posts() twice or is that just an edge case the plugin covers as developers do sometimes do that, not knowing all the consequences?

I'm asking as in my humble opinion a proper fix for non-working get_queried_objct would not be to whitelisting some query variables which are dynamically set, but not resetting those at all. Thoughts?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions