Make WordPress Core

Opened 4 months ago

Closed 5 weeks ago

Last modified 5 weeks ago

#63668 closed enhancement (fixed)

Media / REST API: Support specifying multiple media types or mime types when listing media

Reported by: talldanwp's profile talldanwp Owned by: ramonopoly's profile ramonopoly
Milestone: 6.9 Priority: normal
Severity: normal Version: trunk
Component: REST API Keywords: has-patch changes-requested has-unit-tests dev-feedback
Focuses: rest-api Cc:

Description

Currently the REST API's media endpoint has a limitation that a user can only specify one media type or mime type to filter the results when listing media.

See https://developer.wordpress.org/rest-api/reference/media/#arguments.

It'd be useful though if a user of the API could specify more than one of 'image', 'video', 'audio' as an example to get a mixed collection of results.

An example use case for this - the block editor's inserter has a media tab, and at the bottom of that tab there's an 'Open Media Library' button that shows a media modal with images, video and audio all at once. Currently it wouldn't be possible to create a REST API driven version of this UI without using filters to change how the REST API works.


Implementation

I had a look into how this might be implemented. The REST controller for attachments (media) expands the media type into a post_mime_type query param for WP_Query:
https://github.com/WordPress/wordpress-develop/blob/7170a0b91e082c80e0f287f9e61683f359a2619f/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php#L87-L96

WP_Query uses the wp_post_mime_type_where function to handle this param, and the definition shows it can handle multiple mime type:
https://github.com/WordPress/wordpress-develop/blob/7170a0b91e082c80e0f287f9e61683f359a2619f/src/wp-includes/post.php#L3663-L3709

When a user specifies a single media_type currently, this is often expanded into multiple mime types - image will support image/jpeg, image/png etc, so I don't think adding the functionality would be a technically difficult, but I appreciate feedback on anything I might have missed.

A question for me is whether using the existing media_type option for this purpose is ok.

It may also be good to consider whether multiple mime_types can also be supported at the same time.

Attachments (1)

63668.patch (3.1 KB) - added by abcd95 4 months ago.

Download all attachments as: .zip

Change History (23)

@abcd95
4 months ago

#1 @abcd95
4 months ago

Thanks @talldanwp, for the ticket.

I agree with the proposal and think this case should be considered and included.

I have tried to implement the functionality where it works with both comma-separated strings (e.g., media_type=image,video) and arrays, while remaining fully backward-compatible with existing requests.

Any better approaches are always welcome.

#2 @talldanwp
4 months ago

  • Keywords has-patch needs-unit-tests added

Thanks for the speedy patch @abcd95! I'm at the end of my day, so haven't had a chance to test it, but the first thing that comes to mind is that it'd be great to add unit tests. I think that will be needed anyway for the patch to be accepted.

It's interesting (and clever) the way the patch allows both the media_type and mime_type options to be used together or interchangeably. That part might need some extra documentation too.

If you want to wait for further feedback on the approach before making further changes (from REST or Media maintainers), that's fine too.

#3 @abcd95
4 months ago

Thanks @talldanwp, for replying.

it'd be great to add unit tests.

Yes, I am working on that as well and will be adding that shortly.

If you want to wait for further feedback on the approach before making further changes (from REST or Media maintainers), that's fine too.

Absolutely, I will be waiting for other contributors to scrutinize the patch and get the best out of it.

#4 follow-up: @nikunj8866
4 months ago

  • Keywords changes-requested added

Test Report

Patch tested: https://core.trac.wordpress.org/attachment/ticket/63668/63668.patch

Steps to Test

  1. Start a local wordpress-devlop instance with the patch applied.
  2. Run REST API endpoint http://localhost:8889/wp-json/wp/v2/media?media_type=video,image in the browser with multiple media_type.
  3. Run REST API endpoint http://localhost:8889/wp-json/wp/v2/media?mime_type=image/png,image/jpeg in browser with multiple mime_type.

Expected Results

When running the test(s):

  • ✅ The API returns media items filtered by the media_type or mime_type query with multiple comma-separated values.

Environment

  • WordPress: 6.9-alpha-60093-src
  • PHP: 8.2.28
  • Server: nginx/1.29.0
  • Database: mysqli (Server: 8.4.5 / Client: mysqlnd 8.2.28)
  • Browser: Chrome 138.0.0.0
  • OS: Windows 10/11
  • Theme: Twenty Twenty-Five 1.2
  • MU Plugins: None activated
  • Plugins:
    • Amazon S3 Email Testing 1.0.0
    • Hello Dolly 1.7.2
    • Test Reports 1.2.0
    • WP Mail Logging 1.14.0

Actual Results

Additional Notes

🐞 Bug Identified: When running the endpoint http://localhost:8889/wp-json/wp/v2/media?mime_type=video/mp4, the API returns all media items instead of filtering to just video/mp4 items(https://prnt.sc/uPL2rMgESFUx).

This appears to be an existing issue in the REST API's handling of the mime_type query parameter. It may not be related directly to the current patch but could potentially be addressed or handled as part of the same ticket for completeness.

Conclusion

✅ The current patch works well for media_type filtering.
⚠️ There's an outstanding bug with mime_type filtering that could be worth addressing in the same context.

This ticket was mentioned in PR #9211 on WordPress/wordpress-develop by @abcd95.


4 months ago
#5

  • Keywords has-unit-tests added; needs-unit-tests removed

Trac ticket: https://core.trac.wordpress.org/ticket/63668

This patch enhances the REST API media endpoint to allow filtering by multiple values for the media_type and mime_type parameters. This enables more flexible queries, such as requesting images and videos in a single API call.

The implementation supports both comma-separated strings and arrays for input, while maintaining full backward compatibility. Unit tests are included to cover the new functionality and edge cases.

#6 in reply to: ↑ 4 @abcd95
4 months ago

Replying to nikunj8866:

🐞 Bug Identified: When running the endpoint http://localhost:8889/wp-json/wp/v2/media?mime_type=video/mp4, the API returns all media items instead of filtering to just video/mp4 items(https://prnt.sc/uPL2rMgESFUx).

Thanks @nikunj8866, for testing this out.

However, my testing results were slightly different.
I have .mp4, .mov, .png, and .mp3 files in the media library.

When I request - http://localhost:8889/wp-json/wp/v2/media?mime_type=video/mp4, then I get the expected results, which is a single item - .mp4 file and not all the items.

Here is a screencast of the same - video

Could you please maybe checkout the PR and test to see if you're getting the expected results or not.

#7 follow-up: @nikunj8866
4 months ago

@abcd95 I just wanted to confirm, did you include a comma(,) at the end of the URL, like http://localhost:8889/wp-json/wp/v2/media?mime_type=video/mp4,?

#8 in reply to: ↑ 7 @abcd95
4 months ago

Replying to nikunj8866:

@abcd95 I just wanted to confirm, did you include a comma(,) at the end of the URL, like http://localhost:8889/wp-json/wp/v2/media?mime_type=video/mp4,?

Thanks @nikunj8866, I think I missed this.

The behaviour here, fetching all items, is expected according to the implementation before and after the patch. It is because (I think) whenever we apply some filter on the query, and the filter turns out to be invalid/broken, the query bypasses the filter and fetches items based on the rest of the non-broken/valid filters. As we can see here, all the items are fetched in an orderly manner since that filter is valid.

So while the implementation mandates this behaviour, we can still debate this (as you mentioned in your test report) whether to return an empty set of results for invalid filters through this PR or handle this separately.

#9 @ankitkumarshah
4 months ago

Test Report

Description

This report validates that filtering media works as expected.

Patch tested: https://github.com/WordPress/wordpress-develop/pull/9211

Environment

  • WordPress: 6.9-alpha-60093-src
  • PHP: 8.2.28
  • Server: nginx/1.27.4
  • Database: mysqli (Server: 8.0.41 / Client: mysqlnd 8.2.28)
  • Browser: Chrome 138.0.0.0
  • OS: macOS
  • Theme: Twenty Twenty-Five 1.2
  • MU Plugins:
    • Hello World 1.0
    • Test Plugin
  • Plugins:
    • Gutenberg 19.6.1
    • Test Reports 1.2.0

Actual Results

  1. ✅ The API supports filtering media items using the media_type and mime_type query parameters, allowing multiple values separated by commas.

Supplemental Artifacts

Media:

https://i.postimg.cc/LmTbV266/image.png

Video:

Before:
https://ppgtp1rtd3.ufs.sh/f/TnWMEUzoUd85aQF0qoImzZxcBId59uq2CDo3beNvrnYfPHSs
After:
https://ppgtp1rtd3.ufs.sh/f/TnWMEUzoUd85MmbhPHcQDdEGq0Xo6St7iP2avnAyuxYhNHFT

#10 @nikunj8866
4 months ago

  • Keywords dev-feedback added

Thanks @abcd95

I've checked the URL http://localhost:8889/wp-json/wp/v2/media?media_type=video, and can confirm that it doesn’t break. It returns the expected results filtered by the video media type.

So ideally, the behavior should be consistent in such cases as well. Whether we address this within the scope of this ticket or handle it separately is something worth considering.

#11 @ramonopoly
6 weeks ago

#64046 was marked as a duplicate.

@ramonopoly commented on PR #9211:


6 weeks ago
#12

Also needs to update the API fixtures in tests/qunit/fixtures/wp-api-generated.js by running the WP_Test_REST_Schema_Initialization test, e.g.,

npm run test:php -- --filter WP_Test_REST_Schema_Initialization

That should get the tests passing.

@ramonopoly commented on PR #9211:


6 weeks ago
#13

@himanshupathak95 If you don't mind, I'd like to push this forward. I'll move your changes over to https://github.com/WordPress/wordpress-develop/pull/10054 and give you props.

This ticket was mentioned in PR #10054 on WordPress/wordpress-develop by @ramonopoly.


6 weeks ago
#14

This patch carries on from https://github.com/WordPress/wordpress-develop/pull/9211

This patch enhances the REST API media endpoint to allow filtering by multiple values for the media_type and mime_type parameters. This enables more flexible queries, such as requesting images and videos in a single API call.

The implementation supports both comma-separated strings and arrays for input, while maintaining full backward compatibility. Unit tests are included to cover the new functionality and edge cases.

Additionally, this patch add further tests to check that requests containing both media_type and mime_type values return as expected.

Trac ticket: https://core.trac.wordpress.org/ticket/63668

Props to @himanshupathak95

### Testing

npm run test:php -- --filter WP_Test_REST_Attachments_Controller

@ramonopoly commented on PR #9211:


6 weeks ago
#15

Pulling across your work to https://github.com/WordPress/wordpress-develop/pull/10054 so we can get it moving.

Thank you!

@ramonopoly commented on PR #10054:


6 weeks ago
#16

I've based this PR on work over in https://github.com/WordPress/wordpress-develop/pull/9211

I think it's ready for another look - the base functionality hasn't changed, except for the additional feature of being able to filter by multiple mime types AND multiple media types or a combination of both.

@andrewserong commented on PR #10054:


6 weeks ago
#17

This is still testing well for me 👍
Just left a question about whether or not we should be including all the mime types in an enum or go with a simple string type in the collection params, but other than that it's looking good to me!

@andrewserong commented on PR #10054:


5 weeks ago
#18

This is still looking good to me after the latest changes 👍

@ramonopoly commented on PR #10054:


5 weeks ago
#19

Thanks @andrewserong! I'll let it settle a day or two then merge in it.

#20 @ramonopoly
5 weeks ago

  • Owner set to ramonopoly
  • Resolution set to fixed
  • Status changed from new to closed

In 60917:

Attachments REST API endpoint: add support for filtering attachments by multiple media types

This patch enhances the REST API media endpoint to allow filtering by multiple values for the media_type and mime_type parameters. String, comma-separated values and array are supported.

Props abcd95, ramonopoly, andrewserong, mukesh27, adamsilverstein, timothyblynjacobs, swissspidy.

Fixes #63668.

@ramonopoly commented on PR #10054:


5 weeks ago
#21

Committed in r60917

#22 @ramonopoly
5 weeks ago

  • Milestone changed from Awaiting Review to 6.9
  • Version changed from 4.7 to trunk
Note: See TracTickets for help on using tickets.