Skip to content

Conversation

@morhi
Copy link
Contributor

@morhi morhi commented Jan 27, 2026

Problem

Statamic's DataReferenceUpdater delegates asset reference updates to AssetReferenceUpdater, 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.

Solution

This PR introduces a new approach: fieldtypes handle their own reference updates via the UpdatesReferences trait. Since only the fieldtype knows its internal data structure, I think it's best positioned to locate and replace references.

Custom fieldtypes containing asset/term fields or nested structures (flat or array based) can implement this trait to opt into reference updating.

Example

A fieldtype containing asset references

class FieldtypeWithAssets extends Fieldtype
{
    use UpdatesReferences;
 
    /**
     * Replace asset references in the stored data.
     * This fieldtype stores asset references in the format: asset::{container}::{path}
     *
     * @param  mixed  $data
     * @param  string|null  $newValue
     * @param  string  $oldValue
     * @return mixed
     */
    public function replaceAssetReferences($data, $newValue, $oldValue)
    {
        $container = $this->config('container');

        // Skip if asset option is not enabled or no container configured
        if (!$this->showAssetOption() || !$container) {
            return $data;
        }

        $expectedValue = "asset::{$container}::{$oldValue}";

        // Check if this field contains the asset we're looking for
        if (($data['href'] ?? null) !== $expectedValue) {
            return $data;
        }

        // Handle removal case
        if ($newValue === null) {
            return null;
        }

        // Update the reference
        $data['href'] = "asset::{$container}::{$newValue}";

        return $data;
    }

A fieldtype with nested fields

    use UpdatesReferences;


    protected function configFieldItems(): array
    {
        return [
            'fields' => [
                'display' => __('Fields'),
                'type' => 'fields',
            ],
        ];
    }

    /**
     * Process nested fields for reference updates (assets, terms, etc.).
     * Columns stores data as an array of rows (grid-like structure).
     *
     * @param  mixed  $data
     * @param  callable  $processFields
     */
    public function processNestedFieldsForReferences($data, callable $processFields)
    {
        $this->processArrayNestedFields($data, $processFields, 'fields');
    }

Status

This is still a work in progress. I'd appreciate early feedback on whether this approach makes sense before I complete the implementation.

Closes statamic/ideas#698

@duncanmcclean duncanmcclean changed the title [5.x] Support reference updates for custom fieldtypes [6.x] Support reference updates for custom fieldtypes Jan 28, 2026
@duncanmcclean duncanmcclean changed the base branch from 5.x to 6.x January 28, 2026 17:25
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.

Support custom callbacks in AssetReferenceUpdater for handling custom fieldtypes

1 participant