diff --git a/src/wp-includes/comment.php b/src/wp-includes/comment.php index b9d084c997..41a2260503 100644 --- a/src/wp-includes/comment.php +++ b/src/wp-includes/comment.php @@ -2094,7 +2094,24 @@ function wp_update_comment_count_now($post_id) { return false; $old = (int) $post->comment_count; - $new = (int) $wpdb->get_var( $wpdb->prepare("SELECT COUNT(*) FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_approved = '1'", $post_id) ); + + /** + * Filters a post's comment count before it is updated in the database. + * + * @since 4.5.0 + * + * @param int $new The new comment count. Default null. + * @param int $old The old comment count. + * @param int $post_id Post ID. + */ + $new = apply_filters( 'pre_wp_update_comment_count_now', null, $old, $post_id ); + + if ( is_null( $new ) ) { + $new = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_approved = '1'", $post_id ) ); + } else { + $new = (int) $new; + } + $wpdb->update( $wpdb->posts, array('comment_count' => $new), array('ID' => $post_id) ); clean_post_cache( $post ); diff --git a/tests/phpunit/tests/comment/wpUpdateCommentCountNow.php b/tests/phpunit/tests/comment/wpUpdateCommentCountNow.php new file mode 100644 index 0000000000..7e3ed2bcae --- /dev/null +++ b/tests/phpunit/tests/comment/wpUpdateCommentCountNow.php @@ -0,0 +1,52 @@ +assertFalse( wp_update_comment_count_now( 100 ) ); + $this->assertFalse( wp_update_comment_count_now( null ) ); + $this->assertFalse( wp_update_comment_count_now( 0 ) ); + } + + public function test_regular_post_updates_comment_count() { + global $wpdb; + + $post_id = self::factory()->post->create(); + + self::factory()->comment->create_post_comments( $post_id, 1 ); + $this->assertSame( '1', get_comments_number( $post_id ) ); + + $num_queries = $wpdb->num_queries; + $this->assertTrue( wp_update_comment_count_now( $post_id ) ); + $this->assertSame( $num_queries + 2, $wpdb->num_queries ); + + $this->assertSame( '1', get_comments_number( $post_id ) ); + } + + public function test_using_filter_adjusts_comment_count_without_an_additional_database_query() { + global $wpdb; + + add_filter( 'pre_wp_update_comment_count_now', array( $this, '_return_100' ) ); + + $post_id = self::factory()->post->create(); + + self::factory()->comment->create_post_comments( $post_id, 1 ); + $this->assertSame( '100', get_comments_number( $post_id ) ); + + $num_queries = $wpdb->num_queries; + $this->assertTrue( wp_update_comment_count_now( $post_id ) ); + // Only one query is made instead of two. + $this->assertSame( $num_queries + 1, $wpdb->num_queries ); + + $this->assertSame( '100', get_comments_number( $post_id ) ); + + remove_filter( 'pre_wp_update_comment_count_now', array( $this, '_return_100' ) ); + } +}