diff --git a/src/wp-includes/class-wp-query.php b/src/wp-includes/class-wp-query.php index 437c82f1dd7f1..59f87613f3251 100644 --- a/src/wp-includes/class-wp-query.php +++ b/src/wp-includes/class-wp-query.php @@ -737,6 +737,7 @@ public function fill_query_vars( $query_vars ) { * - 'relevance' * - 'RAND(x)' (where 'x' is an integer seed value) * - 'comment_count' + * - 'comment_date' * - 'meta_value' * - 'meta_value_num' * - 'post__in' @@ -1707,6 +1708,7 @@ protected function parse_orderby( $orderby ) { 'ID', 'menu_order', 'comment_count', + 'comment_date', 'rand', 'post__in', 'post_parent__in', @@ -1756,6 +1758,9 @@ protected function parse_orderby( $orderby ) { case 'comment_count': $orderby_clause = "{$wpdb->posts}.{$orderby}"; break; + case 'comment_date': + $orderby_clause = 'ISNULL(wp_query_comments_last.comment_date), wp_query_comments_last.comment_date'; + break; case 'rand': $orderby_clause = 'RAND()'; break; @@ -2488,6 +2493,8 @@ public function get_posts() { $query_vars['order'] = ''; } + $orderby_comment_date = false; + // Order by. if ( empty( $query_vars['orderby'] ) ) { /* @@ -2512,6 +2519,10 @@ public function get_posts() { continue; } + if ( 'comment_date' === $orderby ) { + $orderby_comment_date = true; + } + $orderby_array[] = $parsed . ' ' . $this->parse_order( $order ); } $orderby = implode( ', ', $orderby_array ); @@ -2527,6 +2538,10 @@ public function get_posts() { continue; } + if ( 'comment_date' === $orderby ) { + $orderby_comment_date = true; + } + $orderby_array[] = $parsed; } $orderby = implode( ' ' . $query_vars['order'] . ', ', $orderby_array ); @@ -2539,6 +2554,16 @@ public function get_posts() { } } + if ( $orderby_comment_date ) { + $join .= " LEFT JOIN ( + SELECT comment_post_ID, MAX(comment_date) AS comment_date + FROM {$wpdb->comments} + WHERE comment_approved = '1' + AND comment_type != 'note' + GROUP BY comment_post_ID + ) AS wp_query_comments_last ON ( {$wpdb->posts}.ID = wp_query_comments_last.comment_post_ID )"; + } + // Order search results by relevance only when another "orderby" is not specified in the query. if ( ! empty( $query_vars['s'] ) ) { $search_orderby = ''; diff --git a/tests/phpunit/tests/query/results.php b/tests/phpunit/tests/query/results.php index e9ec173d61dfd..8a97db1f0107d 100644 --- a/tests/phpunit/tests/query/results.php +++ b/tests/phpunit/tests/query/results.php @@ -633,6 +633,87 @@ public function test_query_orderby_post_parent__in_with_order_desc() { $this->assertSame( $expected_returned_array, wp_list_pluck( $posts, 'post_title' ) ); } + /** + * @ticket 11398 + */ + public function test_query_orderby_comment_date() { + $post_ids = self::factory()->post->create_many( + 4, + array( + 'post_date' => '2020-01-01 00:00:00', + ) + ); + + self::factory()->comment->create( + array( + 'comment_post_ID' => $post_ids[0], + 'comment_date' => '2020-01-01 00:00:00', + 'comment_date_gmt' => '2020-01-04 00:00:00', + ) + ); + self::factory()->comment->create( + array( + 'comment_post_ID' => $post_ids[1], + 'comment_date' => '2020-01-02 00:00:00', + 'comment_date_gmt' => '2020-01-02 00:00:00', + ) + ); + self::factory()->comment->create( + array( + 'comment_post_ID' => $post_ids[1], + 'comment_date' => '2020-01-05 00:00:00', + 'comment_date_gmt' => '2020-01-05 00:00:00', + 'comment_approved' => '0', + ) + ); + self::factory()->comment->create( + array( + 'comment_post_ID' => $post_ids[2], + 'comment_date' => '2019-01-01 00:00:00', + 'comment_date_gmt' => '2019-01-01 00:00:00', + ) + ); + self::factory()->comment->create( + array( + 'comment_post_ID' => $post_ids[2], + 'comment_date' => '2020-01-03 00:00:00', + 'comment_date_gmt' => '2020-01-03 00:00:00', + ) + ); + self::factory()->comment->create( + array( + 'comment_post_ID' => $post_ids[3], + 'comment_date' => '2020-01-06 00:00:00', + 'comment_date_gmt' => '2020-01-06 00:00:00', + 'comment_type' => 'note', + ) + ); + + $query_args = array( + 'post__in' => $post_ids, + 'orderby' => 'comment_date', + 'fields' => 'ids', + 'posts_per_page' => -1, + 'ignore_sticky_posts' => true, + ); + + $desc_query = new WP_Query( array_merge( $query_args, array( 'order' => 'DESC' ) ) ); + $asc_query = new WP_Query( array_merge( $query_args, array( 'order' => 'ASC' ) ) ); + $limited_query = new WP_Query( + array_merge( + $query_args, + array( + 'order' => 'DESC', + 'posts_per_page' => 2, + ) + ) + ); + + $this->assertSame( array( $post_ids[2], $post_ids[1], $post_ids[0], $post_ids[3] ), $desc_query->posts ); + $this->assertSame( array( $post_ids[0], $post_ids[1], $post_ids[2], $post_ids[3] ), $asc_query->posts ); + $this->assertSame( array( $post_ids[2], $post_ids[1] ), $limited_query->posts ); + } + /** * @ticket 39055 */