WP_Query must convert posts to WP_Post objects after filters are run
|Reported by:||nacin||Owned by:||ryan|
WP_Query sets all found posts to WP_Post objects with this:
if ( $this->posts ) $this->posts = array_map( 'get_post', $this->posts );
This takes place before the post_results and the_posts filters, which may actually set new posts. One use case would be to set posts from cache (which may still be stdClass objects) after bypassing the original query using the posts_request or post_request_ids filters (which is why we needed to add if ( $this->posts ) to begin with).
For more, see the advanced post caching plugin, a newer version of which is running on WP.com. The symptom they saw there is the queried object ends up an stdClass, and then in nav-menu-template.php — _wp_menu_item_classes_by_context(), specifically — $queried_object->ancestors is assumed to be an array. In reality, it will be null, as the stdClass object has no magic. This generates a warning.
#14426 was just re-opened for similar gotchas.
The solution: WP_Query must convert posts to WP_Post objects after filters are run. This second call could even only run when filters are not suppressed, I imagine.