[6.x] Support reference updates for custom fieldtypes and working copies#13693
[6.x] Support reference updates for custom fieldtypes and working copies#13693morhi wants to merge 9 commits intostatamic:6.xfrom
Conversation
|
This would be amazing to have! We developed a custom asset fieldtype to better manage contextual metadata. While great for using custom fieldtype components, it also disables automatic reference updates for those fields. This PR would really help make this possible without re-implementing the logic of the reference updater classes in our addon. |
|
Thanks @daun Do you have any thoughts or concerns about the implementation I suggested? |
- Use strict null checks instead of falsy checks to avoid skipping valid data like empty arrays or 0 - Replace json_encode comparison with native PHP strict equality for change detection - Add non-array guards in helper methods to prevent TypeError on unexpected data - Standardize helper parameter ordering: callable always last
|
@morhi No concerns here, looks logical to me :) An approach we explored previously was to create a new |
Yea, I developed something similar too. It works, but it requires going through all fields twice. I was just thinking if there is a solution that would be easier to integrate in custom fieldtypes. Currently, you have to use the trait and implement the given methods. |
Instead of hardcoding type checks in the updater classes, each fieldtype now owns its reference update logic. Built-in fieldtypes use the same trait as addon developers, serving as examples. Updater classes are simplified to generic loops with cached fieldtype detection via Blink.
…elds Improves IDE discoverability for addon developers by replacing the opaque callable parameter with a typed NestedFieldUpdater class.
The current data reference update system only replaced data in the published entry. This commits also replaces the data of a working copy, if it exists.
|
Hey @ryanmitchell @jasonvarga @jacksleight @marcorieser ! Would love to hear your opinion on this PR. I am quite sure that all of us came across this issue at some point and it would be super cool to have this fixed :) |
Problem
Statamic's
DataReferenceUpdaterdelegates asset reference updates toAssetReferenceUpdater, which only supports Statamic's built-in fieldtypes. Custom fieldtypes referencing assets or containing nested fields (including nested Statamic Asset fields) don't receive reference updates when assets are renamed, moved, or deleted. This causes broken references.Because of this, I had to disable renaming and moving files entirely in all of my projects.
Also, while working on this PR I noticed, that working copies don't receive any data updates, which makes assets and terms disappear if the entry has a working copy that you are working on. The PR also fixes that issue.
Solution
This PR moves reference update logic into the fieldtypes themselves via the
UpdatesReferencestrait. Since only the fieldtype knows its internal data structure, it's best positioned to locate and replace references.All built-in fieldtypes (Assets, Link, Bard, Markdown, Grid, Group, Replicator, Terms) now use this trait, serving as reference implementations for addon developers. The updater classes (
AssetReferenceUpdater,TermReferenceUpdater,DataReferenceUpdater) are simplified to generic loops that delegate to fieldtype methods, with a one-time cached Blink lookup to detect which fieldtypes participate.The trait provides three no-op methods to override:
replaceAssetReferences($data, $newValue, $oldValue, $container)replaceTermReferences($data, $newValue, $oldValue, $taxonomy)iterateReferenceFields($data, NestedFieldUpdater $updater)Plus three helpers:
replaceValue(),replaceValuesInArray(),replaceStatamicUrls().Examples
Custom fieldtype with asset references
Custom fieldtype with term references
Custom fieldtype with nested sub-fields
Closes statamic/ideas#698