Repository navigation
Some server-side image-processing hooks never fire on the client upload path #80216
Description
What problem does this address?
The hooks audit in #80210 found that five server-side image-processing hooks never fire when an image is uploaded through the client-side media path, for any supported image type:
| Hook | Core purpose |
|---|---|
wp_image_editors |
Choose/extend the server-side WP_Image_Editor implementations |
image_make_intermediate_size |
Filter each generated sub-size file |
image_strip_meta |
Control whether metadata is stripped from resized images |
image_max_bit_depth |
Cap the bit depth of generated images |
image_memory_limit |
Raise the PHP memory limit during image processing |
The cause is structural: on the client path, decoding, scaling, and encoding happen in the browser (wasm-vips), so no WP_Image_Editor is ever instantiated on the server. Plugins relying on these hooks for watermarking gates, metadata policies, or bit-depth control silently lose that behavior when client-side processing is active.
(Related but distinct: wp_image_maybe_exif_rotate does fire on the client path for EXIF-oriented images, but create_item forces it to false so the client owns rotation - where rotation should live is tracked in #77582.)
What is your proposed solution?
Explore, per hook, whether to reconcile or document:
image_strip_meta- export the filtered value in the client settings payload (alongside output format, quality, progressive, and threshold, which are already exported) and honor it in the client encoder. vips supports stripping/keeping metadata, so site-level customizations could keep working.image_max_bit_depth- export to the client settings payload as well. Particularly relevant for HDR/AVIF sub-size bit depth (see the high-bit-depth work in Vips: preserve bit depth of high-bit-depth AVIF in sub-sizes #79556 and follow-up Vips: Add positional-crop test for high-bit-depth AVIF #79880).image_make_intermediate_size- two options:- Document that the per-sideload
wp_handle_uploadfiring is the equivalent signal (the audit confirmed each sideloaded sub-size fires it once with the final file path). - Or fire the filter manually in the
/sideloadcontroller with the sub-size metadata array, matching core's timing (file exists, metadata not yet saved). Return-value mutations would need to flow into the stored metadata.
- Document that the per-sideload
wp_image_editors- cannot meaningfully fire (there is no server-side editor involved). Document that sites depending on custom image editors can disable the feature via thewp_client_side_media_processing_enabledfilter.image_memory_limit- not applicable client-side; document only.
Whatever ends up documented rather than reconciled should land in the client-side media documentation being added in #75895.
Prior art
- Audit hooks fired during media upload - server vs client path, per image type #80210 - the hooks audit that produced these findings (full comparison table there).
- Ensure that existing media hooks continue to run (when possible) #74358 - the original "Ensure that existing media hooks continue to run (when possible)" task.
- Docs: Add client-side media processing documentation #75895 - client-side media documentation.
- Media: Where should EXIF rotation belong — server, client, or hybrid? #77582 - EXIF rotation ownership discussion.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fields✅ Done
Activity
adamsilverstein commentedon Jul 13, 2026
PR up for the two reconcilable hooks: #80218 exports the filtered
image_strip_metaandimage_max_bit_depthvalues on the REST index (same pattern asimage_size_threshold) and honors them in the client encoder.Disposition of the remaining three, to be covered in the docs work in #75895:
image_make_intermediate_size- going with option A (document): the audit in Audit hooks fired during media upload - server vs client path, per image type #80210 confirmed each sideloaded sub-size fireswp_handle_uploadonce with the final file path, which is the equivalent per-file signal. Firing the filter manually in the/sideloadcontroller could be revisited if a concrete plugin use case needs return-value mutations to flow into metadata.wp_image_editors- document only; sites depending on custom server-side editors can disable the feature viawp_client_side_media_processing_enabled.image_memory_limit- not applicable client-side; document only.Docs: Document hook firing on the client-side media path
[-]Client Side Media: five server-side image-processing hooks never fire on the client upload path[/-][+]Some server-side image-processing hooks never fire on the client upload path[/+]