Make WordPress Core

Ticket #36487: 36487.diff

File 36487.diff, 4.9 KB (added by boonebgorges, 8 years ago)
  • src/wp-includes/class-wp-comment-query.php

    diff --git src/wp-includes/class-wp-comment-query.php src/wp-includes/class-wp-comment-query.php
    index 190bc2d..f67447a 100644
    class WP_Comment_Query { 
    742742                        }
    743743                }
    744744
    745                 if ( $this->query_vars['hierarchical'] && ! $this->query_vars['parent'] ) {
    746                         $this->query_vars['parent'] = 0;
     745                $parent = $this->query_vars['parent'];
     746                if ( $this->query_vars['hierarchical'] && ! $parent ) {
     747                        $parent = 0;
    747748                }
    748749
    749                 if ( '' !== $this->query_vars['parent'] ) {
    750                         $this->sql_clauses['where']['parent'] = $wpdb->prepare( 'comment_parent = %d', $this->query_vars['parent'] );
     750                if ( '' !== $parent ) {
     751                        $this->sql_clauses['where']['parent'] = $wpdb->prepare( 'comment_parent = %d', $parent );
    751752                }
    752753
    753754                if ( is_array( $this->query_vars['user_id'] ) ) {
    class WP_Comment_Query { 
    941942                        }
    942943                }
    943944
     945                $key = md5( serialize( wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) ) ) );
     946                $last_changed = wp_cache_get( 'last_changed', 'comment' );
     947                if ( ! $last_changed ) {
     948                        $last_changed = microtime();
     949                        wp_cache_set( 'last_changed', $last_changed, 'comment' );
     950                }
     951
    944952                // Fetch an entire level of the descendant tree at a time.
    945953                $level = 0;
    946954                do {
    947                         $parent_ids = $levels[ $level ];
    948                         if ( ! $parent_ids ) {
    949                                 break;
     955                        // Parent-child relationships may be cached. Only query for those that are not.
     956                        $child_ids = $uncached_parent_ids = array();
     957                        $_parent_ids = $levels[ $level ];
     958                        foreach ( $_parent_ids as $parent_id ) {
     959                                $cache_key = "get_comment_child_ids:$parent_id:$key:$last_changed";
     960                                $parent_child_ids = wp_cache_get( $cache_key, 'comment' );
     961                                if ( false !== $parent_child_ids ) {
     962                                        $child_ids += $parent_child_ids;
     963                                } else {
     964                                        $uncached_parent_ids[] = $parent_id;
     965                                }
    950966                        }
    951967
    952                         $where = 'WHERE ' . $_where . ' AND comment_parent IN (' . implode( ',', array_map( 'intval', $parent_ids ) ) . ')';
    953                         $comment_ids = $wpdb->get_col( "{$this->sql_clauses['select']} {$this->sql_clauses['from']} {$where} {$this->sql_clauses['groupby']} ORDER BY comment_date_gmt ASC, comment_ID ASC" );
     968                        if ( $uncached_parent_ids ) {
     969                                $where = 'WHERE ' . $_where . ' AND comment_parent IN (' . implode( ',', array_map( 'intval', $uncached_parent_ids ) ) . ')';
     970                                $level_comments = $wpdb->get_results( "SELECT $wpdb->comments.comment_ID, $wpdb->comments.comment_parent {$this->sql_clauses['from']} {$where} {$this->sql_clauses['groupby']} ORDER BY comment_date_gmt ASC, comment_ID ASC" );
     971
     972                                // Cache parent-child relationships.
     973                                $parent_map = array_fill_keys( $uncached_parent_ids, array() );
     974                                foreach ( $level_comments as $level_comment ) {
     975                                        $parent_map[ $level_comment->comment_parent ][] = $level_comment->comment_ID;
     976                                        $child_ids[] = $level_comment->comment_ID;
     977                                }
     978
     979                                foreach ( $parent_map as $parent_id => $children ) {
     980                                        $cache_key = "get_comment_child_ids:$parent_id:$key:$last_changed";
     981                                        wp_cache_set( $cache_key, $children, 'comment' );
     982                                }
     983                        }
    954984
    955985                        $level++;
    956                         $levels[ $level ] = $comment_ids;
    957                 } while ( $comment_ids );
     986                        $levels[ $level ] = $child_ids;
     987                } while ( $child_ids );
    958988
    959989                // Prime comment caches for non-top-level comments.
    960990                $descendant_ids = array();
  • tests/phpunit/tests/comment/query.php

    diff --git tests/phpunit/tests/comment/query.php tests/phpunit/tests/comment/query.php
    index 30973ce..dda29e6 100644
    class Tests_Comment_Query extends WP_UnitTestCase { 
    24302430                $clauses['where'] .= $wpdb->prepare( ' AND comment_ID != %d AND comment_ID != %d', $this->to_exclude[0], $this->to_exclude[1] );
    24312431                return $clauses;
    24322432        }
     2433
     2434        /**
     2435         * @ticket 36487
     2436         */
     2437        public function test_cache_should_be_hit_when_querying_descendants() {
     2438                global $wpdb;
     2439
     2440                $p = self::factory()->post->create();
     2441                $comment_1 = self::factory()->comment->create( array(
     2442                        'comment_post_ID' => $p,
     2443                        'comment_approved' => '1',
     2444                ) );
     2445                $comment_2 = self::factory()->comment->create( array(
     2446                        'comment_post_ID' => $p,
     2447                        'comment_approved' => '1',
     2448                        'comment_parent' => $comment_1,
     2449                ) );
     2450                $comment_3 = self::factory()->comment->create( array(
     2451                        'comment_post_ID' => $p,
     2452                        'comment_approved' => '1',
     2453                        'comment_parent' => $comment_1,
     2454                ) );
     2455                $comment_4 = self::factory()->comment->create( array(
     2456                        'comment_post_ID' => $p,
     2457                        'comment_approved' => '1',
     2458                        'comment_parent' => $comment_2,
     2459                ) );
     2460
     2461                $q1 = new WP_Comment_Query( array(
     2462                        'post_id' => $p,
     2463                        'hierarchical' => true,
     2464                ) );
     2465                $q1_ids = wp_list_pluck( $q1->comments, 'comment_ID' );
     2466
     2467                $num_queries = $wpdb->num_queries;
     2468                $q2 = new WP_Comment_Query( array(
     2469                        'post_id' => $p,
     2470                        'hierarchical' => true,
     2471                ) );
     2472                $q2_ids = wp_list_pluck( $q2->comments, 'comment_ID' );
     2473
     2474                $this->assertEqualSets( $q1_ids, $q2_ids );
     2475                $this->assertSame( $num_queries, $wpdb->num_queries );
     2476        }
     2477
    24332478        /**
    24342479         * @ticket 27571
    24352480         */