Make WordPress Core

Changeset 54784 for branches/6.1


Ignore:
Timestamp:
11/10/2022 02:20:47 AM (4 years ago)
Author:
peterwilsoncc
Message:

Query: Prevent ID only queries erroring when starting the loop.

Ensure only full post objects are passed to update_post_author_caches() when called within WP_Query::the_post(). This prevents an error when starting the Loop for Queries initiated with a subset of fields or IDs only.

Props konyoldeath, dd32, lozula, TimothyBlynJacobs, spacedmonkey, mxbclang, peterwilsoncc.
Merges [54771] to the 6.1 branch.
Fixes #56948.

Location:
branches/6.1
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branches/6.1

  • branches/6.1/src/wp-includes/class-wp-query.php

    r54781 r54784  
    35873587
    35883588                if ( ! $this->in_the_loop ) {
    3589                         update_post_author_caches( $this->posts );
     3589                        // Only prime the post cache for queries limited to the ID field.
     3590                        $post_ids = array_filter( $this->posts, 'is_numeric' );
     3591                        // Exclude any falsey values, such as 0.
     3592                        $post_ids = array_filter( $post_ids );
     3593                        if ( $post_ids ) {
     3594                                _prime_post_caches( $post_ids, $this->query_vars['update_post_term_cache'], $this->query_vars['update_post_meta_cache'] );
     3595                        }
     3596                        $post_objects = array_map( 'get_post', $this->posts );
     3597                        update_post_author_caches( $post_objects );
    35903598                }
    35913599
  • branches/6.1/src/wp-includes/post.php

    r54783 r54784  
    74797479 */
    74807480function update_post_author_caches( $posts ) {
     7481        /*
     7482         * cache_users() is a pluggable function so is not available prior
     7483         * to the `plugins_loaded` hook firing. This is to ensure against
     7484         * fatal errors when the function is not available.
     7485         */
     7486        if ( ! function_exists( 'cache_users' ) ) {
     7487                return;
     7488        }
     7489
    74817490        $author_ids = wp_list_pluck( $posts, 'post_author' );
    74827491        $author_ids = array_map( 'absint', $author_ids );
  • branches/6.1/tests/phpunit/tests/query/cacheResults.php

    r54692 r54784  
    12111211                );
    12121212        }
     1213
     1214        /**
     1215         * Ensure starting the loop warms the author cache.
     1216         *
     1217         * @since 6.1.1
     1218         * @ticket 56948
     1219         *
     1220         * @covers WP_Query::the_post
     1221         *
     1222         * @dataProvider data_author_cache_warmed_by_the_loop
     1223         *
     1224         * @param string $fields Query fields.
     1225         */
     1226        public function test_author_cache_warmed_by_the_loop( $fields ) {
     1227                // Update post author for the parent post.
     1228                self::factory()->post->update_object( self::$pages[0], array( 'post_author' => self::$author_id ) );
     1229
     1230                self::factory()->post->create(
     1231                        array(
     1232                                'post_author' => self::$author_id,
     1233                                'post_parent' => self::$pages[0],
     1234                                'post_type'   => 'page',
     1235                        )
     1236                );
     1237
     1238                $query_1 = new WP_Query(
     1239                        array(
     1240                                'post_type' => 'page',
     1241                                'fields'    => $fields,
     1242                                'author'    => self::$author_id,
     1243                        )
     1244                );
     1245
     1246                // Start the loop.
     1247                $start_loop_queries = get_num_queries();
     1248                $query_1->the_post();
     1249                $num_loop_queries = get_num_queries() - $start_loop_queries;
     1250                $this->assertSame( 2, $num_loop_queries, 'Unexpected number of queries while initializing the loop.' );
     1251
     1252                $start_author_queries = get_num_queries();
     1253                get_user_by( 'ID', self::$author_id );
     1254                $num_author_queries = get_num_queries() - $start_author_queries;
     1255                $this->assertSame( 0, $num_author_queries, 'Author cache is not warmed by the loop.' );
     1256        }
     1257
     1258        /**
     1259         * Data provider for test_author_cache_warmed_by_the_loop
     1260         *
     1261         * @return array[]
     1262         */
     1263        public function data_author_cache_warmed_by_the_loop() {
     1264                return array(
     1265                        'fields: empty' => array( '' ),
     1266                        'fields: all'   => array( 'all' ),
     1267                        'fields: ids'   => array( 'ids' ),
     1268                        /*
     1269                         * `id=>parent` is untested pending the resolution of an existing bug.
     1270                         * See https://core.trac.wordpress.org/ticket/56992
     1271                         */
     1272                );
     1273        }
    12131274}
Note: See TracChangeset for help on using the changeset viewer.