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; diff --git a/tests/phpunit/tests/rest-api/rest-attachments-controller.php b/tests/phpunit/tests/rest-api/rest-attachments-controller.php index d065238b8beb7..df0bd04e630ce 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,153 @@ 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 ); + } + + /** + * 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(