Media uploading - declare convert_format as boolean arg on sideload route#77565
Conversation
…route The sideload handler reads $request['convert_format'] but the route did not declare it. Multipart/form-data requests delivered the client's "false" as a PHP string which evaluates truthy, so the filter that suppresses server-side format conversion was never added. This caused HEIC companion originals to get a numeric suffix while the JPEG derivative had none, and the drift widened on every subsequent upload of the same HEIC. Declaring convert_format with type=boolean (default true) lets the REST layer coerce the string to a PHP bool, matching what is already done for the create_item path, and incidentally fixes the HEIC/JPEG filename drift reported against #77506. Fixes #77564.
|
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 If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
|
I will plan to backport this to WordPress core once client side media is restored to core in WordPress/wordpress-develop#11324 |
|
Flaky tests detected in f0b7ac5. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/24790568579
|
The feature shipping target moved from 7.0 to 7.1 (per #76756). Bring the architecture explanation and how-to guide up to date with the post-7.0-cycle state of the code: - Reposition introductions around 7.1 with 7.0 as the groundwork cycle. - HEIC/HEIF: document the canvas-based fallback path (createImageBitmap, HTMLImageElement+OffscreenCanvas, HEIC container parsing + WebCodecs VideoDecoder), JPEG companion file, and isHeicCanvasSupported() gate. - AVIF: note the wp_prevent_unsupported_mime_type_uploads bypass when generate_sub_sizes=false (#76371). - Batch thumbnail generation via image.copyMemory() / thumbnailImage() (#76979). - Sub-size deduplication via image_size: string|string[] on the sideload route (#77036). - Single VIPS instance via promise caching (#76780). - Build-output trimming: remove vips-jxl.wasm (#76639), skip non-min worker (#76615), skip WASM-inlined sourcemaps (#75993). - COI: <img> excluded from cross-origin attribute injection (#76618). - Loosened feature-detection thresholds: 2 cores, 3g (#76616). - Post-saving lock fix: Save Draft now respects the lock (#76973). - convert_format declared as boolean on sideload route (#77565). - Fix incorrect REST index settings list (only image_sizes and image_size_threshold are exposed). - Remove references to client_side_supported_mime_types filter (PR #76549 was closed unmerged); state the supported MIME set is fixed at CLIENT_SIDE_SUPPORTED_MIME_TYPES. Refs #75111.


What
Declares
convert_formatas a boolean arg on the/wp/v2/media/<id>/sideloadroute so REST coerces the incoming value before it reaches the handler.Why
The sideload handler reads
$request['convert_format']atclass-gutenberg-rest-attachments-controller.php:548and the client sendsconvert_format: falseinadditionalDatawhen uploading a HEIC companion. Because the arg was not declared,multipart/form-datadelivered the value as the string"false", which evaluates truthy, soif ( ! $request['convert_format'] )never fired andadd_filter( 'image_editor_output_format', '__return_empty_array', 100 )was skipped.With the filter skipped,
wp_unique_filename()retained the default HEIC→JPEG output-format mapping and ran its alt-extension collision check — which bumped the.heicoriginal to-1even though the JPEG derivative stayed at no suffix. On subsequent uploads of the same HEIC, the two filenames drifted further apart (HEIC-3, JPEG-2).Declaring the arg mirrors what is already done for
create_item's endpoint args and lets REST coerce"false"→ PHPfalse. The filter fires, alt-ext is skipped during the sideload, and the HEIC and JPEG end up sharing the same numeric suffix on every upload.How
lib/media/class-gutenberg-rest-attachments-controller.php— add theconvert_formatboolean arg (defaulttrue) to the sideload route'sargsarray, alongsidegenerate_sub_sizes.phpunit/media/class-gutenberg-rest-attachments-controller-test.php— two new tests:test_sideload_route_declares_convert_format_booleanasserts the route schema.test_sideload_convert_format_false_suppresses_alt_ext_suffixsimulates the HEIC-companion flow (PNG stand-in + PNG→JPEG mapping) and verifies the companion keeps the shared basename with no numeric suffix.Both tests fail on
trunkand pass with this change.Testing instructions
npx wp-env run --env-cwd='wp-content/plugins/gutenberg' wordpress vendor/bin/phpunit -c phpunit.xml.dist --filter 'Gutenberg_REST_Attachments_Controller_Test'.heicoriginal and.jpgderivative share the same numeric suffix (no suffix the first time,-1the second, etc.) on the filesystem.Closes #77564
cc @andrewserong
AI use
I prompted Claude Code to write this PR and reviewed and tested it manually.