From 7b08983ce4c7bbf146dd4f9403627b095b189e6c Mon Sep 17 00:00:00 2001 From: Jake Spurlock Date: Tue, 23 Jun 2020 05:22:39 +0000 Subject: [PATCH] Comments: Ensure the proper comment count and pages for unapproved comments. Previiously, unapproved comments can alter the comment count, returning incorrect page numbers. Fixes #8973. Props GregMulhauser, dd32, ryan, mrmist, hakre, solarissmoke, billerickson, ericlewis, SergeyBiryukov, chriscct7, dossy, lukecavanagh, renggo888, jdorner, matjack1, pento, audrasjb, imath, davidbaumwald, whyisjake. git-svn-id: https://develop.svn.wordpress.org/trunk@48133 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/comment-template.php | 15 +-- src/wp-includes/comment.php | 57 ++++++++++ .../tests/comment/getPageOfComment.php | 107 ++++++++++++++++++ 3 files changed, 169 insertions(+), 10 deletions(-) diff --git a/src/wp-includes/comment-template.php b/src/wp-includes/comment-template.php index f792748a13..2482c0250e 100644 --- a/src/wp-includes/comment-template.php +++ b/src/wp-includes/comment-template.php @@ -1330,6 +1330,7 @@ function wp_comment_form_unfiltered_html_nonce() { * Will not try to get the comments if the post has none. * * @since 1.5.0 + * @since 5.5.0 Removed the need to use the $user_ID global. * * @global WP_Query $wp_query WordPress Query object. * @global WP_Post $post Global post object. @@ -1337,7 +1338,6 @@ function wp_comment_form_unfiltered_html_nonce() { * @global int $id * @global WP_Comment $comment Global comment object. * @global string $user_login - * @global int $user_ID * @global string $user_identity * @global bool $overridden_cpage * @global bool $withcomments @@ -1347,7 +1347,7 @@ function wp_comment_form_unfiltered_html_nonce() { * Default false. */ function comments_template( $file = '/comments.php', $separate_comments = false ) { - global $wp_query, $withcomments, $post, $wpdb, $id, $comment, $user_login, $user_ID, $user_identity, $overridden_cpage; + global $wp_query, $withcomments, $post, $wpdb, $id, $comment, $user_login, $user_identity, $overridden_cpage; if ( ! ( is_single() || is_page() || $withcomments ) || empty( $post ) ) { return; @@ -1396,14 +1396,9 @@ function comments_template( $file = '/comments.php', $separate_comments = false $comment_args['hierarchical'] = false; } - if ( $user_ID ) { - $comment_args['include_unapproved'] = array( $user_ID ); - } else { - $unapproved_email = wp_get_unapproved_comment_author_email(); - - if ( $unapproved_email ) { - $comment_args['include_unapproved'] = array( $unapproved_email ); - } + $include_unapproved = wp_get_include_unapproved_comments_argument(); + if ( $include_unapproved ) { + $comment_args['include_unapproved'] = $include_unapproved; } $per_page = 0; diff --git a/src/wp-includes/comment.php b/src/wp-includes/comment.php index 744af98b9b..b4771df838 100644 --- a/src/wp-includes/comment.php +++ b/src/wp-includes/comment.php @@ -1132,6 +1132,36 @@ function get_page_of_comment( $comment_ID, $args = array() ) { ), ); + $include_unapproved = wp_get_include_unapproved_comments_argument(); + if ( $include_unapproved ) { + $comment_args['include_unapproved'] = $include_unapproved; + } + + /** + * Filters the arguments used to query comments in get_page_of_comment(). + * + * @since 5.5.0 + * + * @see WP_Comment_Query::__construct() + * + * @param array $comment_args { + * Array of WP_Comment_Query arguments. + * + * @type string $type Limit paginated comments to those matching a given type. Accepts 'comment', + * 'trackback', 'pingback', 'pings' (trackbacks and pingbacks), or 'all'. + * Default is 'all'. + * @type int $post_id ID of the post. + * @type string $fields Comment fields to return. + * @type bool $count Whether to return a comment count (true) or array of + * comment objects (false) + * @type string $status Comment status. + * @type int $parent Parent ID of comment to retrieve children of. + * @type array $date_query Date query clauses to limit comments by. See WP_Date_Query. + * @type array $include_unapproved Array of IDs or email addresses whose unapproved comments + * will be included in paginated comments. + * } + */ + $comment_args = apply_filters( 'get_page_of_comment_query_args', $comment_args ); $comment_query = new WP_Comment_Query(); $older_comment_count = $comment_query->query( $comment_args ); @@ -1896,6 +1926,33 @@ function wp_get_unapproved_comment_author_email() { return $commenter_email; } +/** + * Get include unapproved comments query argument. + * + * Used to include unapproved comments of currrent commenters to + * keep them informed their comments were successfully saved. + * + * @since 5.5.0 + * + * @return array The unapproved comments query argument. + */ +function wp_get_include_unapproved_comments_argument() { + $user_id = get_current_user_id(); + $include_unapproved = array(); + + if ( $user_id ) { + $include_unapproved = array( $user_id ); + } else { + $unapproved_email = wp_get_unapproved_comment_author_email(); + + if ( $unapproved_email ) { + $include_unapproved = array( $unapproved_email ); + } + } + + return $include_unapproved; +} + /** * Inserts a comment into the database. * diff --git a/tests/phpunit/tests/comment/getPageOfComment.php b/tests/phpunit/tests/comment/getPageOfComment.php index 5059625660..7a0bd729b3 100644 --- a/tests/phpunit/tests/comment/getPageOfComment.php +++ b/tests/phpunit/tests/comment/getPageOfComment.php @@ -439,4 +439,111 @@ class Tests_Comment_GetPageOfComment extends WP_UnitTestCase { $this->assertEquals( 2, get_page_of_comment( $c3 ) ); } + + /** + * @ticket 8973 + */ + public function test_page_number_when_unapproved_comments_are_included_for_current_commenter() { + $post = self::factory()->post->create(); + $comment_args = array( + 'comment_post_ID' => $post, + 'comment_approved' => 0, + 'comment_author_email' => 'foo@bar.test', + 'comment_author' => 'Foo', + 'comment_author_url' => 'https://bar.test', + ); + + for ( $i = 1; $i < 4; $i++ ) { + self::factory()->comment->create( + array_merge( + $comment_args, + array( + 'comment_date_gmt' => gmdate( 'Y-m-d H:i:s', time() - ( $i * 1000 ) ), + ) + ) + ); + } + + $new_unapproved = self::factory()->comment->create( + $comment_args + ); + + add_filter( 'wp_get_current_commenter', array( $this, 'get_current_commenter' ) ); + + $page = get_page_of_comment( $new_unapproved, array( 'per_page' => 3 ) ); + $comments = get_comments( + array( + 'number' => 3, + 'paged' => $page, + 'post_id' => $post, + 'status' => 'approve', + 'include_unapproved' => array( 'foo@bar.test' ), + 'orderby' => 'comment_date_gmt', + 'order' => 'ASC', + ) + ); + + remove_filter( 'wp_get_current_commenter', array( $this, 'get_current_commenter' ) ); + + $this->assertContains( $new_unapproved, wp_list_pluck( $comments, 'comment_ID' ) ); + } + + /** + * @ticket 8973 + */ + public function test_page_number_when_unapproved_comments_are_included_for_current_user() { + $current_user = get_current_user_id(); + $post = self::factory()->post->create(); + $user = self::factory()->user->create_and_get(); + $comment_args = array( + 'comment_post_ID' => $post, + 'comment_approved' => 0, + 'comment_author_email' => $user->user_email, + 'comment_author' => $user->display_name, + 'comment_author_url' => $user->user_url, + 'user_id' => $user->ID, + ); + + for ( $i = 1; $i < 4; $i++ ) { + self::factory()->comment->create( + array_merge( + $comment_args, + array( + 'comment_date_gmt' => gmdate( 'Y-m-d H:i:s', time() - ( $i * 1000 ) ), + ) + ) + ); + } + + $new_unapproved = self::factory()->comment->create( + $comment_args + ); + + wp_set_current_user( $user->ID ); + + $page = get_page_of_comment( $new_unapproved, array( 'per_page' => 3 ) ); + $comments = get_comments( + array( + 'number' => 3, + 'paged' => $page, + 'post_id' => $post, + 'status' => 'approve', + 'include_unapproved' => array( $user->ID ), + 'orderby' => 'comment_date_gmt', + 'order' => 'ASC', + ) + ); + + $this->assertContains( $new_unapproved, wp_list_pluck( $comments, 'comment_ID' ) ); + + wp_set_current_user( $current_user ); + } + + public function get_current_commenter() { + return array( + 'comment_author_email' => 'foo@bar.test', + 'comment_author' => 'Foo', + 'comment_author_url' => 'https://bar.test', + ); + } }