diff --git a/src/wp-includes/comment-template.php b/src/wp-includes/comment-template.php index ac843243e9..f4c904bc88 100644 --- a/src/wp-includes/comment-template.php +++ b/src/wp-includes/comment-template.php @@ -1876,6 +1876,27 @@ function wp_list_comments( $args = array(), $comments = null ) { */ $r = apply_filters( 'wp_list_comments_args', $r ); + /* + * If 'page' or 'per_page' has been passed, and does not match what's in $wp_query, + * perform a separate comment query and allow Walker_Comment to paginate. + */ + if ( is_singular() && ( $r['page'] || $r['per_page'] ) ) { + $current_cpage = get_query_var( 'cpage' ); + if ( ! $current_cpage ) { + $current_cpage = 'newest' === get_option( 'default_comments_page' ) ? 1 : $wp_query->max_num_comment_pages; + } + + $current_per_page = get_query_var( 'comments_per_page' ); + if ( $r['page'] != $current_cpage || $r['per_page'] != $current_per_page ) { + $comments = get_comments( array( + 'post_id' => get_queried_object_id(), + 'orderby' => 'comment_date_gmt', + 'order' => 'ASC', + 'status' => 'all', + ) ); + } + } + // Figure out what comments we'll be looping through ($_comments) if ( null !== $comments ) { $comments = (array) $comments; diff --git a/tests/phpunit/tests/comment/wpListComments.php b/tests/phpunit/tests/comment/wpListComments.php new file mode 100644 index 0000000000..84f6e4c517 --- /dev/null +++ b/tests/phpunit/tests/comment/wpListComments.php @@ -0,0 +1,113 @@ +post->create(); + + $comments = array(); + $now = time(); + for ( $i = 0; $i <= 5; $i++ ) { + $comments[] = self::factory()->comment->create( array( + 'comment_post_ID' => $p, + 'comment_date_gmt' => date( 'Y-m-d H:i:s', $now - $i ), + 'comment_author' => 'Commenter ' . $i, + ) ); + } + + update_option( 'page_comments', true ); + update_option( 'comments_per_page', 2 ); + + $this->go_to( get_permalink( $p ) ); + + // comments_template() populates $wp_query->comments + get_echo( 'comments_template' ); + + $found = wp_list_comments( array( + 'page' => 2, + 'echo' => false, + ) ); + + preg_match_all( '|id="comment\-([0-9]+)"|', $found, $matches ); + + $this->assertEqualSets( array( $comments[2], $comments[3] ), $matches[1] ); + } + + /** + * @ticket 35175 + */ + public function test_should_respect_per_page_param() { + $p = self::factory()->post->create(); + + $comments = array(); + $now = time(); + for ( $i = 0; $i <= 5; $i++ ) { + $comments[] = self::factory()->comment->create( array( + 'comment_post_ID' => $p, + 'comment_date_gmt' => date( 'Y-m-d H:i:s', $now - $i ), + 'comment_author' => 'Commenter ' . $i, + ) ); + } + + update_option( 'page_comments', true ); + update_option( 'comments_per_page', 2 ); + + $this->go_to( get_permalink( $p ) ); + + // comments_template() populates $wp_query->comments + get_echo( 'comments_template' ); + + $found = wp_list_comments( array( + 'per_page' => 3, + 'echo' => false, + ) ); + + preg_match_all( '|id="comment\-([0-9]+)"|', $found, $matches ); + + $this->assertEqualSets( array( $comments[0], $comments[1], $comments[2] ), $matches[1] ); + } + + /** + * @ticket 35175 + */ + public function test_should_respect_reverse_top_level_param() { + $p = self::factory()->post->create(); + + $comments = array(); + $now = time(); + for ( $i = 0; $i <= 5; $i++ ) { + $comments[] = self::factory()->comment->create( array( + 'comment_post_ID' => $p, + 'comment_date_gmt' => date( 'Y-m-d H:i:s', $now - $i ), + 'comment_author' => 'Commenter ' . $i, + ) ); + } + + update_option( 'page_comments', true ); + update_option( 'comments_per_page', 2 ); + + $this->go_to( get_permalink( $p ) ); + + // comments_template() populates $wp_query->comments + get_echo( 'comments_template' ); + + $found1 = wp_list_comments( array( + 'reverse_top_level' => true, + 'echo' => false, + ) ); + preg_match_all( '|id="comment\-([0-9]+)"|', $found1, $matches ); + $this->assertSame( array( $comments[0], $comments[1] ), array_map( 'intval', $matches[1] ) ); + + $found2 = wp_list_comments( array( + 'reverse_top_level' => false, + 'echo' => false, + ) ); + preg_match_all( '|id="comment\-([0-9]+)"|', $found2, $matches ); + $this->assertSame( array( $comments[1], $comments[0] ), array_map( 'intval', $matches[1] ) ); + } +}