diff --git a/src/wp-includes/class-wp-comment.php b/src/wp-includes/class-wp-comment.php index 7225539d10..ab6bf14b55 100644 --- a/src/wp-includes/class-wp-comment.php +++ b/src/wp-includes/class-wp-comment.php @@ -227,22 +227,61 @@ final class WP_Comment { * @since 4.4.0 * @access public * - * @param string $format Return value format. 'tree' for a hierarchical tree, 'flat' for a flattened array. - * Default 'tree'. + * @param array $args { + * Array of arguments used to pass to get_comments() and determine format. + * + * @type string $format Return value format. 'tree' for a hierarchical tree, 'flat' for a flattened array. + * Default 'tree'. + * @type string $status Comment status to limit results by. Accepts 'hold' (`comment_status=0`), + * 'approve' (`comment_status=1`), 'all', or a custom comment status. + * Default 'all'. + * @type string $hierarchical Whether to include comment descendants in the results. + * 'threaded' returns a tree, with each comment's children + * stored in a `children` property on the `WP_Comment` object. + * 'flat' returns a flat array of found comments plus their children. + * Pass `false` to leave out descendants. + * The parameter is ignored (forced to `false`) when `$fields` is 'ids' or 'counts'. + * Accepts 'threaded', 'flat', or false. Default: 'threaded'. + * @type string|array $orderby Comment status or array of statuses. To use 'meta_value' + * or 'meta_value_num', `$meta_key` must also be defined. + * To sort by a specific `$meta_query` clause, use that + * clause's array key. Accepts 'comment_agent', + * 'comment_approved', 'comment_author', + * 'comment_author_email', 'comment_author_IP', + * 'comment_author_url', 'comment_content', 'comment_date', + * 'comment_date_gmt', 'comment_ID', 'comment_karma', + * 'comment_parent', 'comment_post_ID', 'comment_type', + * 'user_id', 'comment__in', 'meta_value', 'meta_value_num', + * the value of $meta_key, and the array keys of + * `$meta_query`. Also accepts false, an empty array, or + * 'none' to disable `ORDER BY` clause. + * } * @return array Array of `WP_Comment` objects. */ - public function get_children( $format = 'tree' ) { + public function get_children( $args = array() ) { + $defaults = array( + 'format' => 'tree', + 'status' => 'all', + 'hierarchical' => 'threaded', + 'orderby' => '', + ); + + $_args = wp_parse_args( $args, $defaults ); + $_args['parent'] = $this->comment_ID; + if ( is_null( $this->children ) ) { - $this->children = get_comments( array( - 'parent' => $this->comment_ID, - 'hierarchical' => 'threaded', - ) ); + $this->children = get_comments( $_args ); } - if ( 'flat' === $format ) { + if ( 'flat' === $_args['format'] ) { $children = array(); foreach ( $this->children as $child ) { - $children = array_merge( $children, array( $child ), $child->get_children( 'flat' ) ); + $child_args = $_args; + $child_args['format'] = 'flat'; + // get_children() resets this value automatically. + unset( $child_args['parent'] ); + + $children = array_merge( $children, array( $child ), $child->get_children( $child_args ) ); } } else { $children = $this->children; diff --git a/src/wp-includes/comment-template.php b/src/wp-includes/comment-template.php index b3ba1aea48..5146c9f908 100644 --- a/src/wp-includes/comment-template.php +++ b/src/wp-includes/comment-template.php @@ -1307,7 +1307,11 @@ function comments_template( $file = '/comments.php', $separate_comments = false // Trees must be flattened before they're passed to the walker. $comments_flat = array(); foreach ( $_comments as $_comment ) { - $comments_flat = array_merge( $comments_flat, array( $_comment ), $_comment->get_children( 'flat' ) ); + $comments_flat = array_merge( $comments_flat, array( $_comment ), $_comment->get_children( array( + 'format' => 'flat', + 'status' => $comment_args['status'], + 'orderby' => $comment_args['orderby'] + ) ) ); } /** diff --git a/tests/phpunit/tests/comment/query.php b/tests/phpunit/tests/comment/query.php index 24060d7a59..420036ca2e 100644 --- a/tests/phpunit/tests/comment/query.php +++ b/tests/phpunit/tests/comment/query.php @@ -2023,23 +2023,89 @@ class Tests_Comment_Query extends WP_UnitTestCase { 'comment_parent' => $c5, ) ); - $q = new WP_Comment_Query( array( - 'post_id' => $this->post_id, + $args = array( 'hierarchical' => 'threaded', 'orderby' => 'comment_ID', 'order' => 'ASC', + ); + + $query_args = array_merge( $args, array( + 'post_id' => $this->post_id, ) ); + $q = new WP_Comment_Query( $query_args ); + // Top-level comments. $this->assertEqualSets( array( $c1, $c5 ), array_values( wp_list_pluck( $q->comments, 'comment_ID' ) ) ); // Direct descendants of $c1. - $this->assertEqualSets( array( $c2, $c4 ), array_values( wp_list_pluck( $q->comments[ $c1 ]->get_children(), 'comment_ID' ) ) ); + $this->assertEqualSets( array( $c2, $c4 ), array_values( wp_list_pluck( $q->comments[ $c1 ]->get_children( $args ), 'comment_ID' ) ) ); // Direct descendants of $c2. - $this->assertEqualSets( array( $c3 ), array_values( wp_list_pluck( $q->comments[ $c1 ]->get_child( $c2 )->get_children(), 'comment_ID' ) ) ); + $this->assertEqualSets( array( $c3 ), array_values( wp_list_pluck( $q->comments[ $c1 ]->get_child( $c2 )->get_children( $args ), 'comment_ID' ) ) ); // Direct descendants of $c5. - $this->assertEqualSets( array( $c6 ), array_values( wp_list_pluck( $q->comments[ $c5 ]->get_children(), 'comment_ID' ) ) ); + $this->assertEqualSets( array( $c6 ), array_values( wp_list_pluck( $q->comments[ $c5 ]->get_children( $args ), 'comment_ID' ) ) ); + } + + /** + * @ticket 8071 + */ + public function test_hierarchical_threaded_approved() { + $c1 = $this->factory->comment->create( array( + 'comment_post_ID' => $this->post_id, + 'comment_approved' => '1', + ) ); + + $c2 = $this->factory->comment->create( array( + 'comment_post_ID' => $this->post_id, + 'comment_approved' => '1', + 'comment_parent' => $c1, + ) ); + + $c3 = $this->factory->comment->create( array( + 'comment_post_ID' => $this->post_id, + 'comment_approved' => '0', + 'comment_parent' => $c2, + ) ); + + $c4 = $this->factory->comment->create( array( + 'comment_post_ID' => $this->post_id, + 'comment_approved' => '1', + 'comment_parent' => $c1, + ) ); + + $c5 = $this->factory->comment->create( array( + 'comment_post_ID' => $this->post_id, + 'comment_approved' => '1', + ) ); + + $this->factory->comment->create( array( + 'comment_post_ID' => $this->post_id, + 'comment_approved' => '1', + 'comment_parent' => $c5, + ) ); + + $args = array( + 'hierarchical' => 'threaded', + 'status' => 'approve', + 'orderby' => 'comment_ID', + 'order' => 'ASC', + ); + + $query_args = array_merge( $args, array( + 'post_id' => $this->post_id, + ) ); + + $q = new WP_Comment_Query( $query_args ); + + // Top-level comments. + $this->assertEqualSets( array( $c1, $c5 ), array_values( wp_list_pluck( $q->comments, 'comment_ID' ) ) ); + + // Direct descendants of $c1. + $this->assertEqualSets( array( $c2, $c4 ), array_values( wp_list_pluck( $q->comments[ $c1 ]->get_children( $args ), 'comment_ID' ) ) ); + + // Direct descendants of $c2. + $this->assertEqualSets( array(), array_values( wp_list_pluck( $q->comments[ $c1 ]->get_child( $c2 )->get_children( $args ), 'comment_ID' ) ) ); } }