Skip to content

Commit 3d9af96

Browse files
committed
Extend media_type parameter to support filtering by multiple media types in the WP REST Attachments Controller. Updated related tests to verify functionality and ensure backward compatibility.
1 parent 897a277 commit 3d9af96

File tree

2 files changed

+132
-130
lines changed

2 files changed

+132
-130
lines changed

src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public function register_routes() {
7070
* prepares for WP_Query.
7171
*
7272
* @since 4.7.0
73-
* @since 6.9.0 Added the `media_types` parameter to filter by multiple media types.
73+
* @since 6.9.0 Extends the `media_type` parameter to support filtering by multiple media types.
7474
*
7575
* @param array $prepared_args Optional. Array of prepared arguments. Default empty array.
7676
* @param WP_REST_Request $request Optional. Request to prepare items for.
@@ -85,20 +85,22 @@ protected function prepare_items_query( $prepared_args = array(), $request = nul
8585

8686
$media_types = $this->get_media_types();
8787

88-
if ( ! empty( $request['media_type'] ) && isset( $media_types[ $request['media_type'] ] ) ) {
89-
$query_args['post_mime_type'] = $media_types[ $request['media_type'] ];
90-
}
88+
if ( ! empty( $request['media_type'] ) ) {
89+
if ( is_array( $request['media_type'] ) ) {
90+
$mime_types_query = array();
9191

92-
if ( empty( $query_args['post_mime_type'] ) && ! empty( $request['media_types'] ) && is_array( $request['media_types'] ) ) {
93-
$mime_types_query = array();
92+
foreach ( $request['media_type'] as $request_media_type ) {
93+
if ( isset( $media_types[ $request_media_type ] ) ) {
94+
$mime_types_query = array_merge( $mime_types_query, $media_types[ $request_media_type ] );
95+
}
96+
}
9497

95-
foreach ( $request['media_types'] as $media_type ) {
96-
if ( isset( $media_types[ $media_type ] ) ) {
97-
$mime_types_query[] = $media_type;
98+
$query_args['post_mime_type'] = $mime_types_query;
99+
} else {
100+
if ( isset( $media_types[ $request['media_type'] ] ) ) {
101+
$query_args['post_mime_type'] = $media_types[ $request['media_type'] ];
98102
}
99103
}
100-
101-
$query_args['post_mime_type'] = $mime_types_query;
102104
}
103105

104106
if ( ! empty( $request['mime_type'] ) ) {
@@ -1291,7 +1293,7 @@ public static function get_filename_from_disposition( $disposition_header ) {
12911293
* Retrieves the query params for collections of attachments.
12921294
*
12931295
* @since 4.7.0
1294-
* @since 6.9.0 Adds the `media_types` parameter to filter by multiple media types.
1296+
* @since 6.9.0 Extends the `media_type` parameter to support filtering by multiple media types.
12951297
*
12961298
* @return array Query parameters for the attachment collection as an array.
12971299
*/
@@ -1303,18 +1305,19 @@ public function get_collection_params() {
13031305

13041306
$params['media_type'] = array(
13051307
'default' => null,
1306-
'description' => __( 'Limit result set to attachments of a particular media type.' ),
1307-
'type' => 'string',
1308-
'enum' => $media_types,
1309-
);
1310-
1311-
$params['media_types'] = array(
1312-
'default' => null,
1313-
'description' => __( 'Limit result set to an array of media types.' ),
1314-
'type' => 'array',
1315-
'items' => array(
1316-
'type' => 'string',
1317-
'enum' => $media_types,
1308+
'description' => __( 'Limit result set to attachments of a particular media type or media types.' ),
1309+
'oneOf' => array(
1310+
array(
1311+
'type' => 'string',
1312+
'enum' => $media_types,
1313+
),
1314+
array(
1315+
'type' => 'array',
1316+
'items' => array(
1317+
'type' => 'string',
1318+
'enum' => $media_types,
1319+
),
1320+
),
13181321
),
13191322
);
13201323

tests/phpunit/tests/rest-api/rest-attachments-controller.php

Lines changed: 105 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ class WP_Test_REST_Attachments_Controller extends WP_Test_REST_Post_Type_Control
4747
*/
4848
private static $test_audio_file;
4949

50-
5150
/**
5251
* @var array The recorded posts query clauses.
5352
*/
@@ -271,7 +270,6 @@ public function test_registered_query_params() {
271270
'exclude',
272271
'include',
273272
'media_type',
274-
'media_types',
275273
'mime_type',
276274
'modified_after',
277275
'modified_before',
@@ -297,7 +295,8 @@ public function test_registered_query_params() {
297295
'audio',
298296
'text',
299297
);
300-
$this->assertSameSets( $media_types, $data['endpoints'][0]['args']['media_type']['enum'] );
298+
$this->assertSameSets( $media_types, $data['endpoints'][0]['args']['media_type']['oneOf'][0]['enum'] );
299+
$this->assertSameSets( $media_types, $data['endpoints'][0]['args']['media_type']['oneOf'][1]['items']['enum'] );
301300
}
302301

303302
public function test_registered_get_item_params() {
@@ -448,6 +447,109 @@ public function test_get_items_media_type() {
448447
$this->assertSame( $id1, $data[0]['id'] );
449448
}
450449

450+
/**
451+
* Test that the `media_type` array parameter filters the response by multiple media types.
452+
*
453+
* @ticket 64046
454+
*/
455+
public function test_get_items_with_media_types() {
456+
$video_id = self::factory()->attachment->create_object(
457+
self::$test_video_file,
458+
0,
459+
array(
460+
'post_mime_type' => 'video/mp4',
461+
'post_excerpt' => 'A sample caption',
462+
)
463+
);
464+
465+
$audio_id = self::factory()->attachment->create_object(
466+
self::$test_audio_file,
467+
0,
468+
array(
469+
'post_mime_type' => 'audio/mpeg',
470+
'post_excerpt' => 'A sample caption',
471+
)
472+
);
473+
474+
$image_id = self::factory()->attachment->create_object(
475+
self::$test_file,
476+
0,
477+
array(
478+
'post_mime_type' => 'image/jpeg',
479+
'post_excerpt' => 'A sample caption',
480+
)
481+
);
482+
483+
$request = new WP_REST_Request( 'GET', '/wp/v2/media' );
484+
$request->set_param( 'media_type', array( 'audio', 'video' ) );
485+
$response = rest_get_server()->dispatch( $request );
486+
$this->assertCount( 2, $response->get_data() );
487+
$this->assertContains( $video_id, wp_list_pluck( $response->get_data(), 'id' ), 'Video ID not found in response for [audio, video]' );
488+
$this->assertContains( $audio_id, wp_list_pluck( $response->get_data(), 'id' ), 'Audio ID not found in response for [audio, video]' );
489+
490+
$request = new WP_REST_Request( 'GET', '/wp/v2/media' );
491+
$request->set_param( 'media_type', array( 'image' ) );
492+
$response = rest_get_server()->dispatch( $request );
493+
$this->assertCount( 1, $response->get_data() );
494+
$this->assertContains( $image_id, wp_list_pluck( $response->get_data(), 'id' ), 'Image ID not found in response for [image]' );
495+
496+
$request = new WP_REST_Request( 'GET', '/wp/v2/media' );
497+
$request->set_param( 'media_type', array( 'image', 'audio' ) );
498+
$response = rest_get_server()->dispatch( $request );
499+
$this->assertCount( 2, $response->get_data() );
500+
$this->assertContains( $image_id, wp_list_pluck( $response->get_data(), 'id' ), 'Image ID not found in response for [image, audio]' );
501+
$this->assertContains( $audio_id, wp_list_pluck( $response->get_data(), 'id' ), 'Audio ID not found in response for [image, audio]' );
502+
503+
$request = new WP_REST_Request( 'GET', '/wp/v2/media' );
504+
$request->set_param( 'media_type', array( 'image', 'video', 'audio' ) );
505+
$response = rest_get_server()->dispatch( $request );
506+
$this->assertCount( 3, $response->get_data() );
507+
$this->assertContains( $image_id, wp_list_pluck( $response->get_data(), 'id' ), 'Image ID not found in response for [image, video, audio]' );
508+
$this->assertContains( $video_id, wp_list_pluck( $response->get_data(), 'id' ), 'Video ID not found in response for [image, video, audio]' );
509+
$this->assertContains( $audio_id, wp_list_pluck( $response->get_data(), 'id' ), 'Audio ID not found in response for [image, video, audio]' );
510+
}
511+
512+
/**
513+
* Test that the `media_type` string parameter filters the response by a single media type even
514+
* where there are multiple media types.
515+
*
516+
* @ticket 64046
517+
*/
518+
public function test_get_items_with_media_type_and_media_types() {
519+
self::factory()->attachment->create_object(
520+
self::$test_video_file,
521+
0,
522+
array(
523+
'post_mime_type' => 'video/mp4',
524+
'post_excerpt' => 'A sample caption',
525+
)
526+
);
527+
528+
self::factory()->attachment->create_object(
529+
self::$test_audio_file,
530+
0,
531+
array(
532+
'post_mime_type' => 'audio/mpeg',
533+
'post_excerpt' => 'A sample caption',
534+
)
535+
);
536+
537+
$image_id = self::factory()->attachment->create_object(
538+
self::$test_file,
539+
0,
540+
array(
541+
'post_mime_type' => 'image/jpeg',
542+
'post_excerpt' => 'A sample caption',
543+
)
544+
);
545+
546+
$request = new WP_REST_Request( 'GET', '/wp/v2/media' );
547+
$request->set_param( 'media_type', 'image' );
548+
$response = rest_get_server()->dispatch( $request );
549+
$this->assertCount( 1, $response->get_data() );
550+
$this->assertContains( $image_id, wp_list_pluck( $response->get_data(), 'id' ), 'Image ID not found in response' );
551+
}
552+
451553
public function test_get_items_mime_type() {
452554
$id1 = self::factory()->attachment->create_object(
453555
self::$test_file,
@@ -2670,107 +2772,4 @@ public function test_upload_svg_image() {
26702772

26712773
$this->assertTrue( $result );
26722774
}
2673-
2674-
/**
2675-
* Test that the `media_types` parameter filters the response by multiple media types.
2676-
*
2677-
* @ticket 64046
2678-
*/
2679-
public function test_get_items_with_media_types() {
2680-
$video_id = self::factory()->attachment->create_object(
2681-
self::$test_video_file,
2682-
0,
2683-
array(
2684-
'post_mime_type' => 'video/mp4',
2685-
'post_excerpt' => 'A sample caption',
2686-
)
2687-
);
2688-
2689-
$audio_id = self::factory()->attachment->create_object(
2690-
self::$test_audio_file,
2691-
0,
2692-
array(
2693-
'post_mime_type' => 'audio/mpeg',
2694-
'post_excerpt' => 'A sample caption',
2695-
)
2696-
);
2697-
2698-
$image_id = self::factory()->attachment->create_object(
2699-
self::$test_file,
2700-
0,
2701-
array(
2702-
'post_mime_type' => 'image/jpeg',
2703-
'post_excerpt' => 'A sample caption',
2704-
)
2705-
);
2706-
2707-
$request = new WP_REST_Request( 'GET', '/wp/v2/media' );
2708-
$request->set_param( 'media_types', array( 'audio', 'video' ) );
2709-
$response = rest_get_server()->dispatch( $request );
2710-
$this->assertCount( 2, $response->get_data() );
2711-
$this->assertContains( $video_id, wp_list_pluck( $response->get_data(), 'id' ), 'Video ID not found in response for [audio, video]' );
2712-
$this->assertContains( $audio_id, wp_list_pluck( $response->get_data(), 'id' ), 'Audio ID not found in response for [audio, video]' );
2713-
2714-
$request = new WP_REST_Request( 'GET', '/wp/v2/media' );
2715-
$request->set_param( 'media_types', array( 'image' ) );
2716-
$response = rest_get_server()->dispatch( $request );
2717-
$this->assertCount( 1, $response->get_data() );
2718-
$this->assertContains( $image_id, wp_list_pluck( $response->get_data(), 'id' ), 'Image ID not found in response for [image]' );
2719-
2720-
$request = new WP_REST_Request( 'GET', '/wp/v2/media' );
2721-
$request->set_param( 'media_types', array( 'image', 'audio' ) );
2722-
$response = rest_get_server()->dispatch( $request );
2723-
$this->assertCount( 2, $response->get_data() );
2724-
$this->assertContains( $image_id, wp_list_pluck( $response->get_data(), 'id' ), 'Image ID not found in response for [image, audio]' );
2725-
$this->assertContains( $audio_id, wp_list_pluck( $response->get_data(), 'id' ), 'Audio ID not found in response for [image, audio]' );
2726-
2727-
$request = new WP_REST_Request( 'GET', '/wp/v2/media' );
2728-
$request->set_param( 'media_types', array( 'image', 'video', 'audio' ) );
2729-
$response = rest_get_server()->dispatch( $request );
2730-
$this->assertCount( 3, $response->get_data() );
2731-
$this->assertContains( $image_id, wp_list_pluck( $response->get_data(), 'id' ), 'Image ID not found in response for [image, video, audio]' );
2732-
$this->assertContains( $video_id, wp_list_pluck( $response->get_data(), 'id' ), 'Video ID not found in response for [image, video, audio]' );
2733-
$this->assertContains( $audio_id, wp_list_pluck( $response->get_data(), 'id' ), 'Audio ID not found in response for [image, video, audio]' );
2734-
}
2735-
2736-
/**
2737-
* Test that the `media_type` parameter overrides the `media_types` parameter.
2738-
*
2739-
* @ticket 64046
2740-
*/
2741-
public function test_get_items_with_media_type_and_media_types() {
2742-
self::factory()->attachment->create_object(
2743-
self::$test_video_file,
2744-
0,
2745-
array(
2746-
'post_mime_type' => 'video/mp4',
2747-
'post_excerpt' => 'A sample caption',
2748-
)
2749-
);
2750-
2751-
self::factory()->attachment->create_object(
2752-
self::$test_audio_file,
2753-
0,
2754-
array(
2755-
'post_mime_type' => 'audio/mpeg',
2756-
'post_excerpt' => 'A sample caption',
2757-
)
2758-
);
2759-
2760-
$image_id = self::factory()->attachment->create_object(
2761-
self::$test_file,
2762-
0,
2763-
array(
2764-
'post_mime_type' => 'image/jpeg',
2765-
'post_excerpt' => 'A sample caption',
2766-
)
2767-
);
2768-
2769-
$request = new WP_REST_Request( 'GET', '/wp/v2/media' );
2770-
$request->set_param( 'media_types', array( 'audio', 'video' ) );
2771-
$request->set_param( 'media_type', 'image' );
2772-
$response = rest_get_server()->dispatch( $request );
2773-
$this->assertCount( 1, $response->get_data() );
2774-
$this->assertContains( $image_id, wp_list_pluck( $response->get_data(), 'id' ), 'Image ID not found in response' );
2775-
}
27762775
}

0 commit comments

Comments
 (0)