From 1faea185144a95e8d7eb498eafdb156d483a65e8 Mon Sep 17 00:00:00 2001 From: himanshupathak95 Date: Mon, 7 Jul 2025 14:13:39 +0530 Subject: [PATCH 1/4] Media: support multiple media types and MIME types in attachments query --- .../class-wp-rest-attachments-controller.php | 45 +++++++++++++------ 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php index 589e0e2ccec17..9e95a807f1511 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php @@ -82,17 +82,31 @@ protected function prepare_items_query( $prepared_args = array(), $request = nul $query_args['post_status'] = 'inherit'; } - $media_types = $this->get_media_types(); + $all_mime_types = array(); + $media_types = $this->get_media_types(); - if ( ! empty( $request['media_type'] ) && isset( $media_types[ $request['media_type'] ] ) ) { - $query_args['post_mime_type'] = $media_types[ $request['media_type'] ]; + if ( ! empty( $request['media_type'] ) ) { + $media_type_input = is_array( $request['media_type'] ) + ? $request['media_type'] + : explode( ',', $request['media_type'] ); + + foreach ( array_map( 'trim', $media_type_input ) as $type ) { + if ( isset( $media_types[ $type ] ) ) { + $all_mime_types = array_merge( $all_mime_types, $media_types[ $type ] ); + } + } } if ( ! empty( $request['mime_type'] ) ) { - $parts = explode( '/', $request['mime_type'] ); - if ( isset( $media_types[ $parts[0] ] ) && in_array( $request['mime_type'], $media_types[ $parts[0] ], true ) ) { - $query_args['post_mime_type'] = $request['mime_type']; - } + $mime_type_input = is_array( $request['mime_type'] ) + ? $request['mime_type'] + : explode( ',', $request['mime_type'] ); + + $all_mime_types = array_merge( $all_mime_types, array_map( 'trim', $mime_type_input ) ); + } + + if ( ! empty( $all_mime_types ) ) { + $query_args['post_mime_type'] = array_values( array_unique( $all_mime_types ) ); } // Filter query clauses to include filenames. @@ -1285,19 +1299,24 @@ public function get_collection_params() { $params = parent::get_collection_params(); $params['status']['default'] = 'inherit'; $params['status']['items']['enum'] = array( 'inherit', 'private', 'trash' ); - $media_types = $this->get_media_types(); $params['media_type'] = array( 'default' => null, - 'description' => __( 'Limit result set to attachments of a particular media type.' ), - 'type' => 'string', - 'enum' => array_keys( $media_types ), + 'description' => __( 'Limit result set to attachments of particular media types.' ), + 'type' => array( 'string', 'array' ), + 'items' => array( + 'type' => 'string', + 'enum' => array_keys( $this->get_media_types() ), + ), ); $params['mime_type'] = array( 'default' => null, - 'description' => __( 'Limit result set to attachments of a particular MIME type.' ), - 'type' => 'string', + 'description' => __( 'Limit result set to attachments of particular MIME types.' ), + 'type' => array( 'string', 'array' ), + 'items' => array( + 'type' => 'string', + ), ); return $params; From f242f5e5f031101f8da1049bdddb9cda8ad87606 Mon Sep 17 00:00:00 2001 From: himanshupathak95 Date: Tue, 8 Jul 2025 13:59:43 +0530 Subject: [PATCH 2/4] Tests: Add tests for multiple media types support in attachments query --- .../rest-api/rest-attachments-controller.php | 71 ++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/tests/phpunit/tests/rest-api/rest-attachments-controller.php b/tests/phpunit/tests/rest-api/rest-attachments-controller.php index d065238b8beb7..73791f476cc80 100644 --- a/tests/phpunit/tests/rest-api/rest-attachments-controller.php +++ b/tests/phpunit/tests/rest-api/rest-attachments-controller.php @@ -267,7 +267,7 @@ public function test_registered_query_params() { 'audio', 'text', ); - $this->assertSameSets( $media_types, $data['endpoints'][0]['args']['media_type']['enum'] ); + $this->assertSameSets( $media_types, $data['endpoints'][0]['args']['media_type']['items']['enum'] ); } public function test_registered_get_item_params() { @@ -441,6 +441,75 @@ public function test_get_items_mime_type() { $this->assertSame( $id1, $data[0]['id'] ); } + /** + * Test multiple media types support with various input formats. + * + * @ticket 63668 + */ + public function test_get_items_multiple_media_types() { + $image_id = self::factory()->attachment->create_object( + self::$test_file, + 0, + array( + 'post_mime_type' => 'image/jpeg', + ) + ); + + $video_id = self::factory()->attachment->create_object( + self::$test_file, + 0, + array( + 'post_mime_type' => 'video/mp4', + ) + ); + + $audio_id = self::factory()->attachment->create_object( + self::$test_file, + 0, + array( + 'post_mime_type' => 'audio/mpeg', + ) + ); + + $request = new WP_REST_Request( 'GET', '/wp/v2/media' ); + + // Test single media type + $request->set_param( 'media_type', 'image' ); + $response = rest_get_server()->dispatch( $request ); + $data = $response->get_data(); + $this->assertCount( 1, $data ); + $this->assertSame( $image_id, $data[0]['id'] ); + + // Test multiple media types with comma-separated string + $request->set_param( 'media_type', 'image,video' ); + $response = rest_get_server()->dispatch( $request ); + $data = $response->get_data(); + $this->assertCount( 2, $data ); + $ids = wp_list_pluck( $data, 'id' ); + $this->assertContains( $image_id, $ids ); + $this->assertContains( $video_id, $ids ); + $this->assertNotContains( $audio_id, $ids ); + + // Test multiple media types with array format + $request->set_param( 'media_type', array( 'image', 'video', 'audio' ) ); + $response = rest_get_server()->dispatch( $request ); + $data = $response->get_data(); + $this->assertCount( 3, $data ); + $ids = wp_list_pluck( $data, 'id' ); + $this->assertContains( $image_id, $ids ); + $this->assertContains( $video_id, $ids ); + $this->assertContains( $audio_id, $ids ); + + // Test invalid media type mixed with valid ones + $request->set_param( 'media_type', 'image,invalid,video' ); + $response = rest_get_server()->dispatch( $request ); + $data = $response->get_data(); + $this->assertCount( 2, $data ); + $ids = wp_list_pluck( $data, 'id' ); + $this->assertContains( $image_id, $ids ); + $this->assertContains( $video_id, $ids ); + } + public function test_get_items_parent() { $post_id = self::factory()->post->create( array( 'post_title' => 'Test Post' ) ); $attachment_id = self::factory()->attachment->create_object( From ff916339d3179cc8967f4e8ff6a0db7e2937eb6c Mon Sep 17 00:00:00 2001 From: himanshupathak95 Date: Tue, 8 Jul 2025 14:01:58 +0530 Subject: [PATCH 3/4] Tests: Add test for multiple MIME types support and combination with media types in attachments query --- .../rest-api/rest-attachments-controller.php | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/tests/phpunit/tests/rest-api/rest-attachments-controller.php b/tests/phpunit/tests/rest-api/rest-attachments-controller.php index 73791f476cc80..cbf52bc118b84 100644 --- a/tests/phpunit/tests/rest-api/rest-attachments-controller.php +++ b/tests/phpunit/tests/rest-api/rest-attachments-controller.php @@ -510,6 +510,84 @@ public function test_get_items_multiple_media_types() { $this->assertContains( $video_id, $ids ); } + /** + * Test multiple MIME types support and combination with media types. + * + * @ticket 63668 + */ + public function test_get_items_multiple_mime_types_and_combination() { + $jpeg_id = self::factory()->attachment->create_object( + self::$test_file, + 0, + array( + 'post_mime_type' => 'image/jpeg', + ) + ); + + $png_id = self::factory()->attachment->create_object( + self::$test_file2, + 0, + array( + 'post_mime_type' => 'image/png', + ) + ); + + $mp4_id = self::factory()->attachment->create_object( + self::$test_file, + 0, + array( + 'post_mime_type' => 'video/mp4', + ) + ); + + $pdf_id = self::factory()->attachment->create_object( + self::$test_file, + 0, + array( + 'post_mime_type' => 'application/pdf', + ) + ); + + $request = new WP_REST_Request( 'GET', '/wp/v2/media' ); + + // Test single MIME type + $request->set_param( 'mime_type', 'image/jpeg' ); + $response = rest_get_server()->dispatch( $request ); + $data = $response->get_data(); + $this->assertCount( 1, $data ); + $this->assertSame( $jpeg_id, $data[0]['id'] ); + + // Test multiple MIME types with comma-separated string + $request->set_param( 'mime_type', 'image/jpeg,image/png' ); + $response = rest_get_server()->dispatch( $request ); + $data = $response->get_data(); + $this->assertCount( 2, $data ); + $ids = wp_list_pluck( $data, 'id' ); + $this->assertContains( $jpeg_id, $ids ); + $this->assertContains( $png_id, $ids ); + + // Test multiple MIME types with array format + $request->set_param( 'mime_type', array( 'image/jpeg', 'video/mp4' ) ); + $response = rest_get_server()->dispatch( $request ); + $data = $response->get_data(); + $this->assertCount( 2, $data ); + $ids = wp_list_pluck( $data, 'id' ); + $this->assertContains( $jpeg_id, $ids ); + $this->assertContains( $mp4_id, $ids ); + + // Test multiple media types with multiple MIME types + $request->set_param( 'media_type', 'image,video' ); + $request->set_param( 'mime_type', 'application/pdf' ); + $response = rest_get_server()->dispatch( $request ); + $data = $response->get_data(); + $this->assertCount( 4, $data ); + $ids = wp_list_pluck( $data, 'id' ); + $this->assertContains( $jpeg_id, $ids ); + $this->assertContains( $png_id, $ids ); + $this->assertContains( $mp4_id, $ids ); + $this->assertContains( $pdf_id, $ids ); + } + public function test_get_items_parent() { $post_id = self::factory()->post->create( array( 'post_title' => 'Test Post' ) ); $attachment_id = self::factory()->attachment->create_object( From 5fe24dd3d11af8a5bd9be3f2e7b0e97eaf63e090 Mon Sep 17 00:00:00 2001 From: himanshupathak95 Date: Tue, 8 Jul 2025 14:13:40 +0530 Subject: [PATCH 4/4] Fix linting --- .../rest-api/rest-attachments-controller.php | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/phpunit/tests/rest-api/rest-attachments-controller.php b/tests/phpunit/tests/rest-api/rest-attachments-controller.php index cbf52bc118b84..df0bd04e630ce 100644 --- a/tests/phpunit/tests/rest-api/rest-attachments-controller.php +++ b/tests/phpunit/tests/rest-api/rest-attachments-controller.php @@ -472,18 +472,18 @@ public function test_get_items_multiple_media_types() { ); $request = new WP_REST_Request( 'GET', '/wp/v2/media' ); - + // Test single media type $request->set_param( 'media_type', 'image' ); $response = rest_get_server()->dispatch( $request ); - $data = $response->get_data(); + $data = $response->get_data(); $this->assertCount( 1, $data ); $this->assertSame( $image_id, $data[0]['id'] ); // Test multiple media types with comma-separated string $request->set_param( 'media_type', 'image,video' ); $response = rest_get_server()->dispatch( $request ); - $data = $response->get_data(); + $data = $response->get_data(); $this->assertCount( 2, $data ); $ids = wp_list_pluck( $data, 'id' ); $this->assertContains( $image_id, $ids ); @@ -493,7 +493,7 @@ public function test_get_items_multiple_media_types() { // Test multiple media types with array format $request->set_param( 'media_type', array( 'image', 'video', 'audio' ) ); $response = rest_get_server()->dispatch( $request ); - $data = $response->get_data(); + $data = $response->get_data(); $this->assertCount( 3, $data ); $ids = wp_list_pluck( $data, 'id' ); $this->assertContains( $image_id, $ids ); @@ -503,7 +503,7 @@ public function test_get_items_multiple_media_types() { // Test invalid media type mixed with valid ones $request->set_param( 'media_type', 'image,invalid,video' ); $response = rest_get_server()->dispatch( $request ); - $data = $response->get_data(); + $data = $response->get_data(); $this->assertCount( 2, $data ); $ids = wp_list_pluck( $data, 'id' ); $this->assertContains( $image_id, $ids ); @@ -549,18 +549,18 @@ public function test_get_items_multiple_mime_types_and_combination() { ); $request = new WP_REST_Request( 'GET', '/wp/v2/media' ); - + // Test single MIME type $request->set_param( 'mime_type', 'image/jpeg' ); $response = rest_get_server()->dispatch( $request ); - $data = $response->get_data(); + $data = $response->get_data(); $this->assertCount( 1, $data ); $this->assertSame( $jpeg_id, $data[0]['id'] ); // Test multiple MIME types with comma-separated string $request->set_param( 'mime_type', 'image/jpeg,image/png' ); $response = rest_get_server()->dispatch( $request ); - $data = $response->get_data(); + $data = $response->get_data(); $this->assertCount( 2, $data ); $ids = wp_list_pluck( $data, 'id' ); $this->assertContains( $jpeg_id, $ids ); @@ -569,7 +569,7 @@ public function test_get_items_multiple_mime_types_and_combination() { // Test multiple MIME types with array format $request->set_param( 'mime_type', array( 'image/jpeg', 'video/mp4' ) ); $response = rest_get_server()->dispatch( $request ); - $data = $response->get_data(); + $data = $response->get_data(); $this->assertCount( 2, $data ); $ids = wp_list_pluck( $data, 'id' ); $this->assertContains( $jpeg_id, $ids ); @@ -579,7 +579,7 @@ public function test_get_items_multiple_mime_types_and_combination() { $request->set_param( 'media_type', 'image,video' ); $request->set_param( 'mime_type', 'application/pdf' ); $response = rest_get_server()->dispatch( $request ); - $data = $response->get_data(); + $data = $response->get_data(); $this->assertCount( 4, $data ); $ids = wp_list_pluck( $data, 'id' ); $this->assertContains( $jpeg_id, $ids );