Make WordPress Core

Changeset 53036


Ignore:
Timestamp:
03/31/2022 09:07:02 AM (4 years ago)
Author:
spacedmonkey
Message:

Comments: Improve performance of the wp_count_comments function.

Improve performance of the wp_count_comments function by replacing a complex query with multiple calls to the get_comments function. Passing the count parameter to the get_comments function results in a simple
count query that returns quickly. Using get_comments also means that query is cached and run through filters.

Props FolioVision, markjaquith, nacin, ryan, coffee2code, wonderboymusic, ComputerGuru, jb510, SergeyBiryukov, Znuff, Rahe, uday17035, spacedmonkey, peterwilsoncc.
Fixes #19901.

Location:
trunk
Files:
2 edited

Legend:

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

    r52707 r53036  
    384384        $post_id = (int) $post_id;
    385385
    386         $where = '';
    387         if ( $post_id > 0 ) {
    388                 $where = $wpdb->prepare( 'WHERE comment_post_ID = %d', $post_id );
    389         }
    390 
    391         $totals = (array) $wpdb->get_results(
    392                 "
    393                 SELECT comment_approved, COUNT( * ) AS total
    394                 FROM {$wpdb->comments}
    395                 {$where}
    396                 GROUP BY comment_approved
    397         ",
    398                 ARRAY_A
    399         );
    400 
    401386        $comment_count = array(
    402387                'approved'            => 0,
     
    409394        );
    410395
    411         foreach ( $totals as $row ) {
    412                 switch ( $row['comment_approved'] ) {
    413                         case 'trash':
    414                                 $comment_count['trash'] = $row['total'];
    415                                 break;
    416                         case 'post-trashed':
    417                                 $comment_count['post-trashed'] = $row['total'];
    418                                 break;
    419                         case 'spam':
    420                                 $comment_count['spam']            = $row['total'];
    421                                 $comment_count['total_comments'] += $row['total'];
    422                                 break;
    423                         case '1':
    424                                 $comment_count['approved']        = $row['total'];
    425                                 $comment_count['total_comments'] += $row['total'];
    426                                 $comment_count['all']            += $row['total'];
    427                                 break;
    428                         case '0':
    429                                 $comment_count['awaiting_moderation'] = $row['total'];
    430                                 $comment_count['total_comments']     += $row['total'];
    431                                 $comment_count['all']                += $row['total'];
    432                                 break;
    433                         default:
    434                                 break;
    435                 }
    436         }
     396        $args = array(
     397                'count'                     => true,
     398                'update_comment_meta_cache' => false,
     399        );
     400        if ( $post_id > 0 ) {
     401                $args['post_id'] = $post_id;
     402        }
     403        $mapping       = array(
     404                'approved'            => 'approve',
     405                'awaiting_moderation' => 'hold',
     406                'spam'                => 'spam',
     407                'trash'               => 'trash',
     408                'post-trashed'        => 'post-trashed',
     409        );
     410        $comment_count = array();
     411        foreach ( $mapping as $key => $value ) {
     412                $comment_count[ $key ] = get_comments( array_merge( $args, array( 'status' => $value ) ) );
     413        }
     414
     415        $comment_count['all']            = $comment_count['approved'] + $comment_count['awaiting_moderation'];
     416        $comment_count['total_comments'] = $comment_count['all'] + $comment_count['spam'];
    437417
    438418        return array_map( 'intval', $comment_count );
  • trunk/tests/phpunit/tests/comment/getCommentCount.php

    r47526 r53036  
    1212                $this->assertSame( 0, $count['post-trashed'] );
    1313                $this->assertSame( 0, $count['total_comments'] );
     14                $this->assertSame( 0, $count['all'] );
    1415        }
    1516
     
    9899                $this->assertSame( 0, $count['total_comments'] );
    99100        }
     101
     102        /**
     103         * @ticket 19901
     104         *
     105         * @covers ::get_comment_count
     106         */
     107        public function test_get_comment_count_validate_cache_comment_deleted() {
     108
     109                $comment_id = self::factory()->comment->create();
     110
     111                $count = get_comment_count();
     112
     113                $this->assertSame( 1, $count['total_comments'] );
     114
     115                wp_delete_comment( $comment_id, true );
     116
     117                $count = get_comment_count();
     118
     119                $this->assertSame( 0, $count['total_comments'] );
     120        }
     121
     122        /**
     123         * @ticket 19901
     124         *
     125         * @covers ::get_comment_count
     126         */
     127        public function test_get_comment_count_validate_cache_post_deleted() {
     128
     129                $post_id = self::factory()->post->create();
     130
     131                $comment_id = self::factory()->comment->create(
     132                        array(
     133                                'comment_post_ID' => $post_id,
     134                        )
     135                );
     136
     137                $count = get_comment_count( $post_id );
     138
     139                $this->assertSame( 1, $count['total_comments'] );
     140
     141                wp_delete_post( $post_id, true );
     142
     143                $count = get_comment_count( $post_id );
     144
     145                $this->assertSame( 0, $count['total_comments'] );
     146        }
     147
     148        /**
     149         * @ticket 19901
     150         *
     151         * @covers ::get_comment_count
     152         */
     153        public function test_get_comment_count_validate_cache_comment_status() {
     154                $comment_id = self::factory()->comment->create();
     155
     156                $count = get_comment_count();
     157
     158                $this->assertSame( 1, $count['approved'] );
     159                $this->assertSame( 0, $count['trash'] );
     160                $this->assertSame( 1, $count['total_comments'] );
     161
     162                wp_set_comment_status( $comment_id, 'trash' );
     163
     164                $count = get_comment_count();
     165
     166                $this->assertSame( 0, $count['approved'] );
     167                $this->assertSame( 1, $count['trash'] );
     168                $this->assertSame( 0, $count['total_comments'] );
     169        }
    100170}
Note: See TracChangeset for help on using the changeset viewer.