From 82c76faedc99549843f10509e16d22c566ed64a6 Mon Sep 17 00:00:00 2001 From: adamsilverstein Date: Sun, 14 Sep 2025 12:58:52 -0600 Subject: [PATCH 01/13] Comments REST endpoint - support for multiple status values --- .../rest-api/endpoints/class-wp-rest-comments-controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php index a0b68759f9942..7a3824ca7080e 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php @@ -1681,7 +1681,7 @@ public function get_collection_params() { 'default' => 'approve', 'description' => __( 'Limit result set to comments assigned a specific status. Requires authorization.' ), 'sanitize_callback' => 'sanitize_key', - 'type' => 'string', + 'type' => array( 'string', 'array' ), 'validate_callback' => 'rest_validate_request_arg', ); From 1fc983f88631c0b0d119265f5cd09c836f5e8424 Mon Sep 17 00:00:00 2001 From: adamsilverstein Date: Sun, 14 Sep 2025 13:59:14 -0600 Subject: [PATCH 02/13] =?UTF-8?q?Add=20tests=20for=20getting=20comments=20?= =?UTF-8?q?by=20status,=20statuses=20or=20=E2=80=98all=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rest-api/rest-comments-controller.php | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/tests/phpunit/tests/rest-api/rest-comments-controller.php b/tests/phpunit/tests/rest-api/rest-comments-controller.php index 0bfe4e778d870..ada28ab985dd6 100644 --- a/tests/phpunit/tests/rest-api/rest-comments-controller.php +++ b/tests/phpunit/tests/rest-api/rest-comments-controller.php @@ -119,6 +119,7 @@ public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) { array( 'comment_content' => "Comment {$i}", 'comment_post_ID' => self::$post_id, + 'status' => ( rand( 0, 100 ) % 2 === 0 ) ? 'approve' : 'hold', ) ); } @@ -224,6 +225,70 @@ public function test_get_items() { $this->assertCount( self::$total_comments, $comments ); } + /** + * Test getting items of a specific status. + */ + public function test_get_items_by_status() { + $request = new WP_REST_Request( 'GET', '/wp/v2/comments' ); + $request->set_param( 'status', 'approve' ); + + $response = rest_get_server()->dispatch( $request ); + $this->assertSame( 200, $response->get_status() ); + + $q = new WP_Comment_Query(); + $found = $q->query( + array( + 'status' => 'approve', + ) + ); + + $comments = $response->get_data(); + $this->assertCount( $found, $comments ); + } + + /** + * Test getting comments of all statuses. + */ + public function test_get_items_by_all_status() { + $request = new WP_REST_Request( 'GET', '/wp/v2/comments' ); + $request->set_param( 'status', 'all' ); + + $response = rest_get_server()->dispatch( $request ); + $this->assertSame( 200, $response->get_status() ); + + $q = new WP_Comment_Query(); + $found = $q->query( + array( + 'status' => 'all', + ) + ); + + $comments = $response->get_data(); + $this->assertCount( $found, $comments ); + } + + /** + * Test getting items of multiple statuses. + */ + public function test_get_items_by_multiple_status() { + $request = new WP_REST_Request( 'GET', '/wp/v2/comments' ); + $request->set_param( 'status', array( 'approve', 'hold' ) ); + + $response = rest_get_server()->dispatch( $request ); + $this->assertSame( 200, $response->get_status() ); + + $q = new WP_Comment_Query(); + $found = $q->query( + array( + 'status' => array( 'approve', 'hold' ), + ) + ); + + $comments = $response->get_data(); + $this->assertCount( $found, $comments ); + + } + /** * @ticket 38692 */ From 4ee6fe84ae2ae6b67cbd81e897d92d10180cc314 Mon Sep 17 00:00:00 2001 From: adamsilverstein Date: Sun, 14 Sep 2025 14:00:38 -0600 Subject: [PATCH 03/13] spacing fixes for linter --- tests/phpunit/tests/rest-api/rest-comments-controller.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/phpunit/tests/rest-api/rest-comments-controller.php b/tests/phpunit/tests/rest-api/rest-comments-controller.php index ada28ab985dd6..70aff9a1345bc 100644 --- a/tests/phpunit/tests/rest-api/rest-comments-controller.php +++ b/tests/phpunit/tests/rest-api/rest-comments-controller.php @@ -235,7 +235,7 @@ public function test_get_items_by_status() { $response = rest_get_server()->dispatch( $request ); $this->assertSame( 200, $response->get_status() ); - $q = new WP_Comment_Query(); + $q = new WP_Comment_Query(); $found = $q->query( array( 'status' => 'approve', @@ -256,7 +256,7 @@ public function test_get_items_by_all_status() { $response = rest_get_server()->dispatch( $request ); $this->assertSame( 200, $response->get_status() ); - $q = new WP_Comment_Query(); + $q = new WP_Comment_Query(); $found = $q->query( array( 'status' => 'all', @@ -277,7 +277,7 @@ public function test_get_items_by_multiple_status() { $response = rest_get_server()->dispatch( $request ); $this->assertSame( 200, $response->get_status() ); - $q = new WP_Comment_Query(); + $q = new WP_Comment_Query(); $found = $q->query( array( 'status' => array( 'approve', 'hold' ), @@ -286,7 +286,6 @@ public function test_get_items_by_multiple_status() { $comments = $response->get_data(); $this->assertCount( $found, $comments ); - } /** From bdd5a6d8204b6cddb1b3fefde25a95568d5cf16c Mon Sep 17 00:00:00 2001 From: adamsilverstein Date: Sun, 14 Sep 2025 14:13:10 -0600 Subject: [PATCH 04/13] Use count --- .../phpunit/tests/rest-api/rest-comments-controller.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/phpunit/tests/rest-api/rest-comments-controller.php b/tests/phpunit/tests/rest-api/rest-comments-controller.php index 70aff9a1345bc..7da163d73503d 100644 --- a/tests/phpunit/tests/rest-api/rest-comments-controller.php +++ b/tests/phpunit/tests/rest-api/rest-comments-controller.php @@ -227,6 +227,8 @@ public function test_get_items() { /** * Test getting items of a specific status. + * + * @ticket 99999 */ public function test_get_items_by_status() { $request = new WP_REST_Request( 'GET', '/wp/v2/comments' ); @@ -239,6 +241,7 @@ public function test_get_items_by_status() { $found = $q->query( array( 'status' => 'approve', + 'count' => true, ) ); @@ -248,6 +251,8 @@ public function test_get_items_by_status() { /** * Test getting comments of all statuses. + * + * @ticket 99999 */ public function test_get_items_by_all_status() { $request = new WP_REST_Request( 'GET', '/wp/v2/comments' ); @@ -260,6 +265,7 @@ public function test_get_items_by_all_status() { $found = $q->query( array( 'status' => 'all', + 'count' => true, ) ); @@ -269,6 +275,8 @@ public function test_get_items_by_all_status() { /** * Test getting items of multiple statuses. + * + * @ticket 99999 */ public function test_get_items_by_multiple_status() { $request = new WP_REST_Request( 'GET', '/wp/v2/comments' ); @@ -281,6 +289,7 @@ public function test_get_items_by_multiple_status() { $found = $q->query( array( 'status' => array( 'approve', 'hold' ), + 'count' => true, ) ); From b878d8be612f1c6b478a89bff044dddb4abca058 Mon Sep 17 00:00:00 2001 From: adamsilverstein Date: Sun, 14 Sep 2025 23:15:01 -0600 Subject: [PATCH 05/13] Complete tests for status field --- .../rest-api/rest-comments-controller.php | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/tests/phpunit/tests/rest-api/rest-comments-controller.php b/tests/phpunit/tests/rest-api/rest-comments-controller.php index 7da163d73503d..a87106342f45b 100644 --- a/tests/phpunit/tests/rest-api/rest-comments-controller.php +++ b/tests/phpunit/tests/rest-api/rest-comments-controller.php @@ -227,14 +227,15 @@ public function test_get_items() { /** * Test getting items of a specific status. - * - * @ticket 99999 */ public function test_get_items_by_status() { + wp_set_current_user( self::$admin_id ); + $request = new WP_REST_Request( 'GET', '/wp/v2/comments' ); $request->set_param( 'status', 'approve' ); - + $request->set_param( 'per_page', self::$per_page ); $response = rest_get_server()->dispatch( $request ); + $this->assertSame( 200, $response->get_status() ); $q = new WP_Comment_Query(); @@ -246,19 +247,21 @@ public function test_get_items_by_status() { ); $comments = $response->get_data(); + $this->assertCount( $found, $comments ); } /** * Test getting comments of all statuses. - * - * @ticket 99999 */ public function test_get_items_by_all_status() { + wp_set_current_user( self::$admin_id ); + $request = new WP_REST_Request( 'GET', '/wp/v2/comments' ); $request->set_param( 'status', 'all' ); - + $request->set_param( 'per_page', self::$per_page ); $response = rest_get_server()->dispatch( $request ); + $this->assertSame( 200, $response->get_status() ); $q = new WP_Comment_Query(); @@ -275,12 +278,13 @@ public function test_get_items_by_all_status() { /** * Test getting items of multiple statuses. - * - * @ticket 99999 */ public function test_get_items_by_multiple_status() { + wp_set_current_user( self::$admin_id ); + $request = new WP_REST_Request( 'GET', '/wp/v2/comments' ); $request->set_param( 'status', array( 'approve', 'hold' ) ); + $request->set_param( 'per_page', self::$per_page ); $response = rest_get_server()->dispatch( $request ); $this->assertSame( 200, $response->get_status() ); From f435d93c1d813ec0e39dc472037c7591bbdc9b2b Mon Sep 17 00:00:00 2001 From: adamsilverstein Date: Sun, 14 Sep 2025 23:32:51 -0600 Subject: [PATCH 06/13] update wp-api-generated --- tests/qunit/fixtures/wp-api-generated.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/qunit/fixtures/wp-api-generated.js b/tests/qunit/fixtures/wp-api-generated.js index 6626758a8a9dc..bc5048a232504 100644 --- a/tests/qunit/fixtures/wp-api-generated.js +++ b/tests/qunit/fixtures/wp-api-generated.js @@ -10335,7 +10335,10 @@ mockedApiResponse.Schema = { "status": { "default": "approve", "description": "Limit result set to comments assigned a specific status. Requires authorization.", - "type": "string", + "type": [ + "string", + "array" + ], "required": false }, "type": { From 7b22c3915459576233a10ae05147902ca0200268 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Mon, 15 Sep 2025 08:44:06 -0600 Subject: [PATCH 07/13] Update tests/phpunit/tests/rest-api/rest-comments-controller.php Co-authored-by: Pascal Birchler --- tests/phpunit/tests/rest-api/rest-comments-controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/rest-api/rest-comments-controller.php b/tests/phpunit/tests/rest-api/rest-comments-controller.php index a87106342f45b..462e0efd5f32d 100644 --- a/tests/phpunit/tests/rest-api/rest-comments-controller.php +++ b/tests/phpunit/tests/rest-api/rest-comments-controller.php @@ -119,7 +119,7 @@ public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) { array( 'comment_content' => "Comment {$i}", 'comment_post_ID' => self::$post_id, - 'status' => ( rand( 0, 100 ) % 2 === 0 ) ? 'approve' : 'hold', + 'status' => ( $i % 2 === 0 ) ? 'approve' : 'hold', ) ); } From 6225ae603f99f6b0d88a9f933bc0adee3e355a0b Mon Sep 17 00:00:00 2001 From: adamsilverstein Date: Mon, 15 Sep 2025 08:47:17 -0600 Subject: [PATCH 08/13] hello yoda my old friend --- tests/phpunit/tests/rest-api/rest-comments-controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/rest-api/rest-comments-controller.php b/tests/phpunit/tests/rest-api/rest-comments-controller.php index 462e0efd5f32d..f826fefbe4ebf 100644 --- a/tests/phpunit/tests/rest-api/rest-comments-controller.php +++ b/tests/phpunit/tests/rest-api/rest-comments-controller.php @@ -119,7 +119,7 @@ public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) { array( 'comment_content' => "Comment {$i}", 'comment_post_ID' => self::$post_id, - 'status' => ( $i % 2 === 0 ) ? 'approve' : 'hold', + 'status' => ( 0 === $i % 2 ) ? 'approve' : 'hold', ) ); } From f121b3e3d930f221e5324168a75f28c0e23acaef Mon Sep 17 00:00:00 2001 From: adamsilverstein Date: Mon, 15 Sep 2025 15:26:44 -0600 Subject: [PATCH 09/13] API handles strings automatically when array type given --- .../rest-api/endpoints/class-wp-rest-comments-controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php index 7a3824ca7080e..13cd7c139f499 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php @@ -1681,7 +1681,7 @@ public function get_collection_params() { 'default' => 'approve', 'description' => __( 'Limit result set to comments assigned a specific status. Requires authorization.' ), 'sanitize_callback' => 'sanitize_key', - 'type' => array( 'string', 'array' ), + 'type' => 'array', 'validate_callback' => 'rest_validate_request_arg', ); From 5fba5f6031f335b9fdee23a1e2e7ac74e1292d8e Mon Sep 17 00:00:00 2001 From: adamsilverstein Date: Mon, 15 Sep 2025 15:36:18 -0600 Subject: [PATCH 10/13] Handle multiple status sanitization --- .../class-wp-rest-comments-controller.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php index 13cd7c139f499..871856c0190e9 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php @@ -1680,7 +1680,7 @@ public function get_collection_params() { $query_params['status'] = array( 'default' => 'approve', 'description' => __( 'Limit result set to comments assigned a specific status. Requires authorization.' ), - 'sanitize_callback' => 'sanitize_key', + 'sanitize_callback' => 'sanitize_comment_statuses', 'type' => 'array', 'validate_callback' => 'rest_validate_request_arg', ); @@ -1928,4 +1928,16 @@ protected function check_is_comment_content_allowed( $prepared_comment ) { */ return '' !== $check['comment_content']; } + + /** + * Sanitize a single comment status or a list of comment statuses with `sanitize_key`. + * + * @since 6.8.0 + * @param string|array $statuses Comment status or array of comment statuses. + * @return array Sanitized array of comment statuses. + */ + public function sanitize_comment_statuses( $statuses ) { + $statuses = wp_parse_list( $statuses ); + return array_unique( array_map( 'sanitize_key', $statuses ) ); + } } From 1ee7a86641699fcc8808ae8d9ee656ef07057253 Mon Sep 17 00:00:00 2001 From: adamsilverstein Date: Mon, 15 Sep 2025 16:59:58 -0600 Subject: [PATCH 11/13] Add additional tests --- .../class-wp-rest-comments-controller.php | 2 +- .../rest-api/rest-comments-controller.php | 69 +++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php index 871856c0190e9..b33ef539505d7 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php @@ -1680,7 +1680,7 @@ public function get_collection_params() { $query_params['status'] = array( 'default' => 'approve', 'description' => __( 'Limit result set to comments assigned a specific status. Requires authorization.' ), - 'sanitize_callback' => 'sanitize_comment_statuses', + 'sanitize_callback' => array( $this, 'sanitize_comment_statuses' ), 'type' => 'array', 'validate_callback' => 'rest_validate_request_arg', ); diff --git a/tests/phpunit/tests/rest-api/rest-comments-controller.php b/tests/phpunit/tests/rest-api/rest-comments-controller.php index f826fefbe4ebf..44df920a4cd2a 100644 --- a/tests/phpunit/tests/rest-api/rest-comments-controller.php +++ b/tests/phpunit/tests/rest-api/rest-comments-controller.php @@ -227,6 +227,8 @@ public function test_get_items() { /** * Test getting items of a specific status. + * + * @ticket 63982 */ public function test_get_items_by_status() { wp_set_current_user( self::$admin_id ); @@ -253,6 +255,8 @@ public function test_get_items_by_status() { /** * Test getting comments of all statuses. + * + * @ticket 63982 */ public function test_get_items_by_all_status() { wp_set_current_user( self::$admin_id ); @@ -278,6 +282,8 @@ public function test_get_items_by_all_status() { /** * Test getting items of multiple statuses. + * + * @ticket 63982 */ public function test_get_items_by_multiple_status() { wp_set_current_user( self::$admin_id ); @@ -301,6 +307,69 @@ public function test_get_items_by_multiple_status() { $this->assertCount( $found, $comments ); } + /** + * Test sanization of the status parameter. + * + * @ticket 63982 + * + * @dataProvider data_get_items_by_status_sanitize + */ + public function test_get_items_by_status_sanitize( $key, $expected ) { + wp_set_current_user( self::$admin_id ); + + // Create a post with the test status. + $params = array( + 'post' => self::$post_id, + 'author_name' => 'Comic Book Guy', + 'author_email' => 'cbg@androidsdungeon.com', + 'author_url' => 'http://androidsdungeon.com', + 'content' => 'Worst Comment Ever!', + 'status' => $key, + ); + + $request = new WP_REST_Request( 'POST', '/wp/v2/comments' ); + $request->add_header( 'Content-Type', 'application/json' ); + $request->set_body( wp_json_encode( $params ) ); + + $response = rest_get_server()->dispatch( $request ); + $this->assertSame( 201, $response->get_status() ); + + $comment = $response->get_data(); + + $this->assertEquals( $expected, $comment['status'] ); + } + + /** + * Data provider. + * + * @return array + */ + public function data_get_items_by_status_sanitize() { + return array( + 'an empty string key' => array( + 'key' => '', + 'expected' => 'hold', + ), + 'a lowercase key with commas' => array( + 'key' => 'howdy,admin', + 'expected' => 'hold', + ), + 'a lowercase key with commas' => array( + 'key' => 'HOWDY,ADMIN', + 'expected' => 'hold', + ), + 'a mixed case key with commas' => array( + 'key' => 'HoWdY,aDmIn', + 'expected' => 'hold', + ), + 'a string with unicode' => array( + 'key' => array( 'howdy admin', 'another-value' ), + 'expected' => 'hold', + ), + ); + } + + /** * @ticket 38692 */ From 3bf31216cb3117fc0337232419f7d9002aefe954 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Tue, 16 Sep 2025 09:20:51 -0600 Subject: [PATCH 12/13] Update src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php Co-authored-by: Mukesh Panchal --- .../rest-api/endpoints/class-wp-rest-comments-controller.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php index b33ef539505d7..41eefb96484c8 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php @@ -1932,7 +1932,8 @@ protected function check_is_comment_content_allowed( $prepared_comment ) { /** * Sanitize a single comment status or a list of comment statuses with `sanitize_key`. * - * @since 6.8.0 + * @since 6.9.0 + * * @param string|array $statuses Comment status or array of comment statuses. * @return array Sanitized array of comment statuses. */ From f210ce5a612498f5fa3a7380c2432a410d7e5053 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Thu, 18 Sep 2025 08:51:25 -0600 Subject: [PATCH 13/13] Update tests/phpunit/tests/rest-api/rest-comments-controller.php Co-authored-by: Mukesh Panchal --- tests/phpunit/tests/rest-api/rest-comments-controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/rest-api/rest-comments-controller.php b/tests/phpunit/tests/rest-api/rest-comments-controller.php index 44df920a4cd2a..9572327c34fbd 100644 --- a/tests/phpunit/tests/rest-api/rest-comments-controller.php +++ b/tests/phpunit/tests/rest-api/rest-comments-controller.php @@ -363,7 +363,7 @@ public function data_get_items_by_status_sanitize() { 'expected' => 'hold', ), 'a string with unicode' => array( - 'key' => array( 'howdy admin', 'another-value' ), + 'key' => array( 'howdy admin', 'another-value' ), 'expected' => 'hold', ), );