Make WordPress Core

Changeset 54771 for trunk


Ignore:
Timestamp:
11/09/2022 12:57:02 AM (2 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.
Fixes #56948.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-query.php

    r54768 r54771  
    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
  • trunk/src/wp-includes/post.php

    r54712 r54771  
    74627462 */
    74637463function update_post_author_caches( $posts ) {
     7464    /*
     7465     * cache_users() is a pluggable function so is not available prior
     7466     * to the `plugins_loaded` hook firing. This is to ensure against
     7467     * fatal errors when the function is not available.
     7468     */
     7469    if ( ! function_exists( 'cache_users' ) ) {
     7470        return;
     7471    }
     7472
    74647473    $author_ids = wp_list_pluck( $posts, 'post_author' );
    74657474    $author_ids = array_map( 'absint', $author_ids );
  • trunk/tests/phpunit/tests/query/cacheResults.php

    r54685 r54771  
    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.