Make WordPress Core

Changeset 34599


Ignore:
Timestamp:
09/26/2015 04:01:05 PM (9 years ago)
Author:
boonebgorges
Message:

Improve post field lazyloading for comments.

[34583] modified comment queries so that all post fields are no longer loaded
by default. Instead, they are loaded only when requested on individual comment
objects. This changeset improves that flow:

  • WP_Comment magic methods __isset() and __get() should only load the post when a post field is being requested.
  • The new update_comment_post_cache argument for WP_Comment_Query allows developers to specify that, when comments are queried, all of the posts matching those comments should be loaded into cache with a single DB hit. This parameter defaults to false, since typical comment queries are linked to a single post.

Fixes #27571.

Location:
trunk
Files:
4 edited

Legend:

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

    r34561 r34599  
    139139     * @since 4.4.0 `$parent__in` and `$parent__not_in` were added.
    140140     * @since 4.4.0 Order by `comment__in` was added. `$update_comment_meta_cache`, `$no_found_rows`,
    141      *              and `$hierarchical` were added.
     141     *              `$hierarchical`, and `$update_comment_post_cache` were added.
    142142     * @access public
    143143     *
     
    239239     *     @type bool         $update_comment_meta_cache Whether to prime the metadata cache for found comments.
    240240     *                                                   Default true.
     241     *     @type bool         $update_comment_post_cache Whether to prime the cache for comment posts.
     242     *                                                   Default false.
    241243     * }
    242244     */
     
    282284            'hierarchical' => false,
    283285            'update_comment_meta_cache' => true,
     286            'update_comment_post_cache' => false,
    284287        );
    285288
     
    413416                $_comments[] = $_comment;
    414417            }
     418        }
     419
     420        // Prime comment post caches.
     421        if ( $this->query_vars['update_comment_post_cache'] ) {
     422            $comment_post_ids = array();
     423            foreach ( $_comments as $_comment ) {
     424                $comment_post_ids[] = $_comment->comment_post_ID;
     425            }
     426
     427            _prime_post_caches( $comment_post_ids, false, false );
    415428        }
    416429
  • trunk/src/wp-includes/class-wp-comment.php

    r34595 r34599  
    158158     */
    159159    protected $children;
     160
     161    /**
     162     * Post fields.
     163     *
     164     * @since 4.4.0
     165     * @access protected
     166     * @var array
     167     */
     168    protected $post_fields = array( 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_excerpt', 'post_status', 'comment_status', 'ping_status', 'post_name', 'to_ping', 'pinged', 'post_modified', 'post_modified_gmt', 'post_content_filtered', 'post_parent', 'guid', 'menu_order', 'post_type', 'post_mime_type', 'comment_count' );
    160169
    161170    /**
     
    323332
    324333    /**
    325      * Whether a comment has post from which to retrieve magic properties
    326      *
    327      * @since 4.4.0
    328      * @access public
    329      *
    330      * @param string $name
     334     * Check whether a non-public property is set.
     335     *
     336     * If `$name` matches a post field, the comment post will be loaded and the post's value checked.
     337     *
     338     * @since 4.4.0
     339     * @access public
     340     *
     341     * @param string $name Property name.
    331342     * @return bool
    332343     */
    333344    public function __isset( $name ) {
    334         if (
    335             0 === (int) $this->comment_post_ID
    336             || property_exists( $this, $name )
    337         ) {
    338             return;
    339         }
    340 
    341         $post = get_post( $this->comment_post_ID );
    342         if ( $post ) {
     345        if ( in_array( $name, $this->post_fields ) && 0 !== (int) $this->comment_post_ID ) {
     346            $post = get_post( $this->comment_post_ID );
    343347            return property_exists( $post, $name );
    344348        }
     
    346350
    347351    /**
    348      * Magic getter for $post properties
     352     * Magic getter.
     353     *
     354     * If `$name` matches a post field, the comment post will be loaded and the post's value returned.
    349355     *
    350356     * @since 4.4.0
     
    355361     */
    356362    public function __get( $name ) {
    357         $post = get_post( $this->comment_post_ID );
    358         if ( $post ) {
     363        if ( in_array( $name, $this->post_fields ) ) {
     364            $post = get_post( $this->comment_post_ID );
    359365            return $post->$name;
    360366        }
  • trunk/tests/phpunit/tests/comment.php

    r34546 r34599  
    340340        $this->assertEquals( array( $c3 ), array_values( wp_list_pluck( $children[ $c2 ]->get_children(), 'comment_ID' ) ) );
    341341    }
     342
     343    /**
     344     * @group 27571
     345     */
     346    public function test_post_properties_should_be_lazyloaded() {
     347        $p = $this->factory->post->create();
     348
     349        $c = $this->factory->comment->create( array( 'comment_post_ID' => $p ) );
     350
     351        $post = get_post( $p );
     352        $comment = get_comment( $c );
     353
     354        $post_fields = array( 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_excerpt', 'post_status', 'comment_status', 'ping_status', 'post_name', 'to_ping', 'pinged', 'post_modified', 'post_modified_gmt', 'post_content_filtered', 'post_parent', 'guid', 'menu_order', 'post_type', 'post_mime_type', 'comment_count' );
     355
     356        foreach ( $post_fields as $pf ) {
     357            $this->assertTrue( isset( $comment->$pf ), $pf );
     358            $this->assertSame( $post->$pf, $comment->$pf, $pf );
     359        }
     360    }
    342361}
  • trunk/tests/phpunit/tests/comment/query.php

    r34569 r34599  
    21092109        $this->assertEqualSets( array(), array_values( wp_list_pluck( $q->comments[ $c1 ]->get_child( $c2 )->get_children( $args ), 'comment_ID' ) ) );
    21102110    }
     2111
     2112    /**
     2113     * @ticket 27571
     2114     */
     2115    public function test_update_comment_post_cache_should_be_disabled_by_default() {
     2116        global $wpdb;
     2117
     2118        $p = $this->factory->post->create();
     2119        $c = $this->factory->comment->create( array( 'comment_post_ID' => $p ) );
     2120
     2121        $q = new WP_Comment_Query( array(
     2122            'post_ID' => $p,
     2123        ) );
     2124
     2125        $num_queries = $wpdb->num_queries;
     2126        $this->assertTrue( isset( $q->comments[0]->post_name ) );
     2127        $this->assertSame( $num_queries + 1, $wpdb->num_queries );
     2128    }
     2129
     2130    /**
     2131     * @ticket 27571
     2132     */
     2133    public function test_should_respect_update_comment_post_cache_true() {
     2134        global $wpdb;
     2135
     2136        $p = $this->factory->post->create();
     2137        $c = $this->factory->comment->create( array( 'comment_post_ID' => $p ) );
     2138
     2139        $q = new WP_Comment_Query( array(
     2140            'post_ID' => $p,
     2141            'update_comment_post_cache' => true,
     2142        ) );
     2143
     2144        $num_queries = $wpdb->num_queries;
     2145        $this->assertTrue( isset( $q->comments[0]->post_name ) );
     2146        $this->assertSame( $num_queries, $wpdb->num_queries );
     2147    }
    21112148}
Note: See TracChangeset for help on using the changeset viewer.