Ensure that non-default pagination values work in `wp_list_comments()`.

Prior to 4.4, it was possible to pass 'page' and 'per_page' values to
`wp_list_comments()` that do not match the corresponding global query vars.
This ability was lost in 4.4 with the refactor of how `comments_template()`
queries for comments; when the main comment query started fetching only the
comments that ought to appear on a page, instead of all of a post's comments,
it became impossible for the comment walker to select comments corresponding to
custom pagination parameters. See #8071.

We restore the previous behavior by (a) detecting when a 'page' or 'per_page'
parameter has been passed to `wp_list_comments()` that does not match the
corresponding query vars (so that the desired comments will not be found in
`$wp_query`), and if so, then (b) querying for all of the post's comments and
passing them to the comment walker for pagination, as was the case before 4.4.

Props boonebgorges, smerriman.
Fixes #35175.

git-svn-id: https://develop.svn.wordpress.org/trunk@36157 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Boone Gorges 2016-01-03 02:02:59 +00:00
parent d47319710c
commit 1b8c0d611a
2 changed files with 134 additions and 0 deletions

View File

@ -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;

View File

@ -0,0 +1,113 @@
<?php
/**
* @group comment
*/
class Tests_Comment_WpListComments extends WP_UnitTestCase {
/**
* @ticket 35175
*/
public function test_should_respect_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(
'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] ) );
}
}