WP_Post conversion overwrites object changes on the_posts filter

Description

I started testing with WP 3.5 beta 3 and the plugin I maintain (podPress). The plugin extends the array $this->posts via the filter the_posts (wp-includes/query.php - function get_posts()). It adds keys and values. But the array_map() command which has been added with the ​Changeset 22011

$this->posts = array_map( 'get_post', $this->posts );

sets the $this->posts array back to the content it had contained before the filter. It retrogrades the_posts filter in my case and the content of $this->posts after array_map() seems to be the same as before the filter.

Is it possible to move the array_map() command some lines up or the filter down?

Change History (23)

Could you describe what you mean by "The plugin extends the array $this->posts via the filter the_posts"? Some code would be great. I don't see how this sets the posts back, unless the objects themselves are being changed.

The filter data from the wp_postmeta table. The data is used for multiple purposes by the plugin e.g to add additional elements to the RSS and ATOM feeds or to the posts on web page.
The functions which should do this use the global variable $post. But the new line of code reduces the data to the default key+value pairs.

Modifying the post object also won't play nice with caching. We ran into this issue a lot with WordPress.com VIP code once we merged WP_Post into WP.com. We came to the conclusion that modifying the post object to add additional fields wasn't a good idea (and that's probably correct) however it's certainly a regression of sorts.

Howdy! I spent some time figuring out how all of this works, doesn't seem to be caused by [22011] from what I see. The problem is because of the behavior of get_post, which is supposed to retrieve a fresh post from cache if filter is (but was not) raw.

The behavior was copied into WP_Post but with the current implementation of WP_Query, the cache exists for all posts, before get_instance is called, so the sanitize_post inside get_instance is never called (within a WP_Query scenario). The 3.4 scenario used to explicitly call sanitize_post, but 3.5 relies on get_post instead. So in 3.4, after a successful query, every post in the posts array will have its filter set to raw, whereas 3.5 keeps it blank, causing WP_Post::filter to call get_instance over and over again (because the cached version has no filter either).

I'm not sure this is the only problem, and I'm pretty sure 22448.diff​ is not the best solution, but it does make sure that when retrieved, a fresh post is always sanitized, meaning WP_Post::filter can not run the get_instance routine unless the filter has been explicitly changed to something other than raw. 22448.unit-tests.diff​ adds some tests, covers adding more posts via the_posts filter, and adding custom data using the_posts filter, as initially described in this ticket.

The modifications suggested in 22448.diff solving the problem. The $this->posts array which gets modified via the the_posts filter hook stays the same passing the line $this->posts = array_map( 'get_post', $this->posts );
in the /wp-includes/query.php file.