Skip to content

Media: Track the original attachment for edited images. - #13303

Draft
ramonjd wants to merge 1 commit into
WordPress:trunkfrom
ramonjd:add/attachment-original-lineage
Draft

Media: Track the original attachment for edited images.#13303
ramonjd wants to merge 1 commit into
WordPress:trunkfrom
ramonjd:add/attachment-original-lineage

Conversation

@ramonjd

@ramonjd ramonjd commented Aug 28, 2026

Copy link
Copy Markdown
Member

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_image records 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_image exists.

This PR adds original_attachment metadata under media_details to 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

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 ramonjd self-assigned this Aug 28, 2026
'context' => array( 'edit' ),
'readonly' => true,
'properties' => array(
'attachment_id' => array(

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@github-actions

Copy link
Copy Markdown

Test using WordPress Playground

The 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

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant