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.

Merges [36157] to the 4.4 branch.

Props boonebgorges, smerriman.
Fixes #35175.


git-svn-id: https://develop.svn.wordpress.org/branches/4.4@36158 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Boone Gorges 2016-01-03 02:06:04 +00:00
parent 40c4a410cf
commit 361b83bf86
2 changed files with 134 additions and 0 deletions

View File

@ -1925,6 +1925,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] ) );
}
}