Media: Track the original attachment for edited images. - #13303
Draft
ramonjd wants to merge 1 commit into
Draft
Conversation
Editing an image via the `wp/v2/media/<id>/edit` REST endpoint saves the result as a new attachment and leaves the edited image untouched, so a site can build up a chain: an upload, a crop of it, a crop of that crop. `parent_image` records only the immediately preceding image, so finding the image a chain started from meant walking it one attachment at a time. Each attachment created by an edit now records the ID at the top of its chain in `_wp_attachment_original_id` postmeta, inheriting it from the image being edited. `wp_get_original_attachment_id()` reads it back in a single lookup, and returns the ID it was given for attachments that were uploaded rather than edited. The attachments REST controller exposes the result as `media_details.original_attachment` in the `edit` context only, giving editors what they need to offer a way back to the original without telling visitors which images were made from which. Deleting an attachment clears the record from any image edited from it, so nothing is left pointing at an ID that could later be reused. Records are written going forward only; images edited before this lands are not backfilled. Props ramonjd. Fixes #65987.
ramonjd
commented
Aug 28, 2026
| 'context' => array( 'edit' ), | ||
| 'readonly' => true, | ||
| 'properties' => array( | ||
| 'attachment_id' => array( |
Member
Author
There was a problem hiding this comment.
I don't believe there's a precedent for media_details with registered context.
The original_attachment sub-property has context: edit.
media_details is usually treated as a bare, typeless object with no properties at all.
The alternative is a top-level property.
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. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What? Why?
When Gutenberg crops an image, Core's /edit creates an entirely new attachment with no stable pointer back to the image the lineage started from.
parent_imagerecords only the immediate source; there is no root/original reference across crop-of-crop chains.That means we can't navigate a crop back to its original in a performant way, that is, without getting each post up the change where
parent_imageexists.This PR adds
original_attachmentmetadata undermedia_detailsto track the lineage.Trac ticket: https://core.trac.wordpress.org/ticket/65987
Use of AI Tools
To create the backport of WordPress/gutenberg#81803 and its tests