[wp-trac] [WordPress Trac] #65330: REST API: Allow a single sideloaded file to be registered under multiple image sizes
WordPress Trac
noreply at wordpress.org
Fri May 22 23:29:25 UTC 2026
#65330: REST API: Allow a single sideloaded file to be registered under multiple
image sizes
-----------------------------+--------------------------------------
Reporter: adamsilverstein | Owner: adamsilverstein
Type: enhancement | Status: assigned
Priority: normal | Milestone: 7.1
Component: General | Version:
Severity: normal | Keywords: has-patch has-unit-tests
Focuses: |
-----------------------------+--------------------------------------
Part of the client-side media processing feature being re-introduced for
7.1 (see #64919, originally #62243). Builds on #65329 (deferring sideload
metadata writes to the finalize endpoint).
When client-side media processing is enabled, the editor generates each
registered image sub-size in the browser and sideloads it to the
attachment. Several registered sizes frequently resolve to the **same**
dimensions (identical width, height, and crop). Generating and uploading a
separate file for each of those sizes is wasteful: it produces duplicate
files on disk and one HTTP request per size.
The client now groups sizes that share dimensions, uploads a single file,
and registers it under every matching size name. This ticket adds the REST
API support for that.
== Proposed change ==
* The sideload endpoint's `image_size` parameter and the finalize
endpoint's `sub_sizes[].image_size` property now accept **a string or an
array of strings**.
* `sideload_item()` returns the shared sub-size payload (dimensions, file,
mime type, filesize) when given an array. `finalize_item()` then writes
that one file into `metadata['sizes']` under each size name in the array,
in the single metadata write introduced in #65329.
* Arrays only ever carry regular sub-sizes. The special `original` and
`scaled` keys remain scalar, since they map to single, distinct files.
== Validation ==
The size names are validated per-item with a `validate_callback` rather
than a schema `enum`:
* `rest_is_array()` treats a scalar string as a single-element list (via
`wp_parse_list()`), so a `('string', 'array')` multi-type alone cannot
enforce an enum.
* The callback checks each item against the current list of registered
sizes (`wp_get_registered_image_subsizes()` plus `original`, `scaled`, and
`full`). Reading the list at validation time (rather than route-
registration time) means sizes registered later, for example via
`add_image_size()`, are accepted. The previous static `$valid_image_sizes`
array computed in `register_routes()` is removed.
* Invalid or non-string items are rejected with `rest_not_in_enum` (400).
== Patch ==
The PHP change is a backport of the merged Gutenberg PR:
* Gutenberg PR: [https://github.com/WordPress/gutenberg/pull/77036
WordPress/gutenberg#77036, Deduplicate client-side image sizes with
matching dimensions]
* Core backport PR: [https://github.com/adamsilverstein/wordpress-
develop/pull/49 adamsilverstein/wordpress-develop#49]
The backport is stacked on the #65329 patch
([https://github.com/adamsilverstein/wordpress-develop/pull/48
adamsilverstein/wordpress-develop#48]); that should land first.
Files touched:
* `src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-
controller.php`
* `tests/phpunit/tests/rest-api/rest-attachments-controller.php`
The JavaScript counterpart (grouping client-side sizes with matching
dimensions before upload) ships through the normal Gutenberg to Core
package sync and is not part of this PHP patch.
== Tests ==
* `test_sideload_image_size_array`: sideload one file with `image_size`
set to `array( 'thumbnail', 'medium' )`, finalize, and assert both sizes
are registered in metadata and reference the same physical file.
* `test_sideload_image_size_invalid`: an array containing an unregistered
size name (`not-a-real-size`) is rejected with a 400.
---
**Note:** the tests in PR #49 currently use `@ticket 64737` (the sideload
endpoint ticket). Once this ticket is posted and Trac assigns a number,
add or swap the `@ticket` annotations to the new number.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/65330>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list