REST API: Expose per-attachment output format and progressive flags on attachment responses#12007
Conversation
…n attachment responses. Add two readonly fields to `WP_REST_Attachments_Controller`, in the `edit` context, alongside the existing `exif_orientation` field: * `image_output_format` returns the resolved output MIME type when `image_editor_output_format` maps the source MIME to a different one (e.g. JPEG -> WebP), or `null` when no conversion is needed. The filter is invoked with the real attached filename and MIME type so plugins can make per-file decisions, mirroring the way `WP_Image_Editor::set_quality()` resolves the output format. * `image_save_progressive` returns the boolean result of the `image_save_progressive` filter for the attachment's MIME type. Both fields are evaluated only for image attachments. Client-side media processing now has the per-file context it needs to encode sub-sizes consistently with server-side behavior, instead of relying on the file-less generic values previously surfaced on the REST API root index. Adds focused PHPUnit coverage for the schema, the default response, custom filter behavior, and that the fields are skipped for non-image attachments. See #65367. Backport of Gutenberg PR #75793 (WordPress/gutenberg#75793).
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
…rom the index. The image_output_formats, jpeg_interlaced, png_interlaced, and gif_interlaced settings were exposed on the REST API root index without any per-file context, so the image_editor_output_format filter ran with an empty filename and could not make per-file decisions. These values are now provided per attachment via the image_output_format and image_save_progressive response fields added in the attachments controller, making the file-less index values redundant. Keep image_sizes and image_size_threshold on the index, which remain useful without file context. Update the generated REST API qunit fixture to match.
Core's re-introduced client-side media processing (changeset 62428) restored a pre-#75793 REST API root index that still exposes the file-less `image_output_formats`, `jpeg_interlaced`, `png_interlaced`, and `gif_interlaced` settings. When the plugin runs against Core trunk, these keys are present, so the `assertArrayNotHasKey` assertions in the media processing test fail. The proper fix lives in Core, where wordpress-develop#12007 removes these redundant index keys in favor of the per-attachment `image_output_format` and `image_save_progressive` response fields. Until that PR merges, disable the affected assertions and link to it so they can be reactivated. See WordPress/wordpress-develop#12007
|
Added a follow-up commit that completes the #75793 migration in Core: it removes the now-redundant, file-less Those values were exposed on the REST root index without per-file context, so This also resolves the failing Gutenberg media processing test (the plugin asserts those keys are absent from the index). A temporary stopgap that disables those assertions until this merges is in WordPress/gutenberg#78788. |
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
Core's re-introduced client-side media processing (changeset 62428) restored a pre-#75793 REST API root index that still exposes the file-less `image_output_formats`, `jpeg_interlaced`, `png_interlaced`, and `gif_interlaced` settings. When the plugin runs against Core trunk, these keys are present, so the `assertArrayNotHasKey` assertions in the media processing test fail. The proper fix lives in Core, where wordpress-develop#12007 removes these redundant index keys in favor of the per-attachment `image_output_format` and `image_save_progressive` response fields. Until that PR merges, disable the affected assertions and link to it so they can be reactivated. See WordPress/wordpress-develop#12007
Core's re-introduced client-side media processing (changeset 62428) restored a pre-#75793 REST API root index that still exposes the file-less `image_output_formats`, `jpeg_interlaced`, `png_interlaced`, and `gif_interlaced` settings. When the plugin runs against Core trunk, these keys are present, so the `assertArrayNotHasKey` assertions in the media processing test fail. The proper fix lives in Core, where wordpress-develop#12007 removes these redundant index keys in favor of the per-attachment `image_output_format` and `image_save_progressive` response fields. Until that PR merges, disable the affected assertions and link to it so they can be reactivated. See WordPress/wordpress-develop#12007 Source: WordPress/gutenberg@db0cf2f
Summary
Adds two readonly fields to
WP_REST_Attachments_Controller, in theeditcontext, alongside the existingexif_orientationfield:image_output_format— returns the resolved output MIME type whenimage_editor_output_formatmaps the source MIME to a different one (e.g. JPEG → WebP), ornullwhen no conversion is needed. The filter is invoked with the real attached filename and MIME type so plugins can make per-file decisions, mirroring the wayWP_Image_Editor::set_quality()resolves the output format.image_save_progressive— returns the boolean result of theimage_save_progressivefilter for the attachment's MIME type.Both fields are evaluated only for image attachments (
wp_attachment_is_image()).Why
Client-side media processing encodes sub-sizes (and the threshold-scaled "scaled" copy) in the browser. To match server-side output, the browser needs to know the output MIME type and whether to use progressive encoding for the specific file being saved. Those decisions are filename- and MIME-aware (
image_editor_output_formatsignature is( array $formats, string $filename, string $mime_type )), so values computed at the REST API root index — without a real filename — are incorrect for any non-trivial site.Putting the resolved values on the per-attachment response gives the client real context to act on, mirroring the existing
exif_orientationpattern.Trac ticket
https://core.trac.wordpress.org/ticket/65367
Backport from Gutenberg
No Core Sync Requiredlabel; the Core sync is now required since client-side media processing has been re-introduced in Core).Tests
New coverage in
tests/phpunit/tests/rest-api/rest-attachments-controller.php:test_image_output_format_and_progressive_schema— both fields are present, typed correctly,readonly,edit-context only.test_image_output_format_and_progressive_defaults_in_create_response— JPEG default response hasimage_output_format = nullandimage_save_progressive = false.test_image_output_format_with_custom_filter— a JPEG→WebPimage_editor_output_formatfilter is reflected in the response, and the filter sees the real attached filename and MIME type.test_image_save_progressive_with_custom_filter— a MIME-awareimage_save_progressivefilter is honored.test_image_output_format_skipped_for_non_image— non-image attachments do not surface the fields.Local results:
WP_Test_REST_Attachments_Controllerruns green (134 tests, 809 assertions, 2 skipped). PHPCS clean.Follow-up
A follow-up could remove the now-redundant index-level
image_output_formats,jpeg_interlaced,png_interlaced,gif_interlacedfields fromWP_REST_Server::get_index(), but that needs coordinated updates to JS preloads insite-editor.phpandedit-form-blocks.phpand is left for a separate change.