-
Notifications
You must be signed in to change notification settings - Fork 29
Description
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?