From d211ad45b12721b98aa7bdeb69174920110fc477 Mon Sep 17 00:00:00 2001 From: spacedmonkey Date: Thu, 21 Sep 2023 19:34:18 +0000 Subject: [PATCH] Query: Improved handling of filtered queries in WP_Query. The `WP_Query` class enables developers to customize queries using filters like `posts_fields_request`, `posts_request`, and `the_posts`, which can modify both the queried fields and retrieved post objects. In some cases with these filters, incomplete or invalid post objects lacking essential data may arise. To address this, if any of these filters are active during a query, the `get_posts` method now avoids caching post objects with the usual `update_post_caches` function call, opting for a call to `_prime_post_caches` instead. This may occasionally trigger new database queries to prime the post data cache. While this enhancement may result in rare additional database queries, it ensures that invalid post objects aren't cached, prioritizing data consistency and integrity in filtered query scenarios. Props saulirajala, spacedmonkey, flixos90, mukesh27, peterwilsoncc. Fixes #58599. Built from https://develop.svn.wordpress.org/trunk@56656 git-svn-id: http://core.svn.wordpress.org/trunk@56168 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/class-wp-query.php | 14 +++++++++++--- wp-includes/version.php | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/wp-includes/class-wp-query.php b/wp-includes/class-wp-query.php index 458b7898c2..3833a7a5a5 100644 --- a/wp-includes/class-wp-query.php +++ b/wp-includes/class-wp-query.php @@ -3270,10 +3270,11 @@ class WP_Query { return $post_parents; } + $is_unfiltered_query = $old_request == $this->request && "{$wpdb->posts}.*" === $fields; + if ( null === $this->posts ) { $split_the_query = ( - $old_request == $this->request - && "{$wpdb->posts}.*" === $fields + $is_unfiltered_query && ( wp_using_ext_object_cache() || ( ! empty( $limits ) && $q['posts_per_page'] < 500 ) @@ -3337,6 +3338,8 @@ class WP_Query { $this->posts = array_map( 'get_post', $this->posts ); } + $unfiltered_posts = $this->posts; + if ( $q['cache_results'] && $id_query_is_cacheable && ! $cache_found ) { $post_ids = wp_list_pluck( $this->posts, 'ID' ); @@ -3529,7 +3532,12 @@ class WP_Query { $this->posts = array_map( 'get_post', $this->posts ); if ( $q['cache_results'] ) { - update_post_caches( $this->posts, $post_type, $q['update_post_term_cache'], $q['update_post_meta_cache'] ); + if ( $is_unfiltered_query && $unfiltered_posts === $this->posts ) { + update_post_caches( $this->posts, $post_type, $q['update_post_term_cache'], $q['update_post_meta_cache'] ); + } else { + $post_ids = wp_list_pluck( $this->posts, 'ID' ); + _prime_post_caches( $post_ids, $q['update_post_term_cache'], $q['update_post_meta_cache'] ); + } } /** @var WP_Post */ diff --git a/wp-includes/version.php b/wp-includes/version.php index 6707e420de..7c8e34c749 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -16,7 +16,7 @@ * * @global string $wp_version */ -$wp_version = '6.4-alpha-56655'; +$wp_version = '6.4-alpha-56656'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.