spatie / statamic-responsive-images

Responsive images for Statamic 3
MIT License
104 stars 29 forks source link

References not updated when renaming an asset folder #148

Closed stuartcusackie closed 2 years ago

stuartcusackie commented 2 years ago

When you rename an asset folder in Statamic it updates all asset fields that references files in that folder automatically. This package doesn't seem to do that and renaming an asset folder breaks all of my responsive image fields.

Multiple actions need to be handled:

These Statamic core files seem to be responsible for the above behaviour on the default asset fields:

So I guess all we would need are these new files:

stuartcusackie commented 2 years ago

I have run some experiments and it seems fairly simple. I think we just need a couple of modifications to the new files that I have listed above:

src/Listeners/UpdateResponsiveReferences.php A simple clone of src/Listeners/UpdateAssetReferences.php Container name needs to be prefixed to the originalPath / newPath:

public function handle(AssetSaved $event)
    {
        $asset = $event->asset;

        $container = $asset->container()->handle();
        $originalPath = $asset->getOriginal('path');
        $newPath = $asset->path();

        if (! $originalPath || $originalPath === $newPath) {
            return;
        }

        $this->getItemsContainingData()->each(function ($item) use ($container, $originalPath, $newPath) {
            AssetReferenceUpdater::item($item)
                ->filterByContainer($container)
                ->updateReferences($container . '::' . $originalPath, $container . '::' . $newPath);
        });
    }

src/ResponsiveReferenceUpdater.php A simple clone of AssetReferenceUpdater.php with the following modifications:

/**
     * Recursively update fields.
     *
     * @param  \Illuminate\Support\Collection  $fields
     * @param  null|string  $dottedPrefix
     */
    protected function recursivelyUpdateFields($fields, $dottedPrefix = null)
    {
        $this->updateResponsiveFieldValues($fields, $dottedPrefix);
    }

 /**
     * Update assets field values.
     *
     * @param  \Illuminate\Support\Collection  $fields
     * @param  null|string  $dottedPrefix
     * @return $this
     */
    protected function updateResponsiveFieldValues($fields, $dottedPrefix)
    {

        $fields
            ->filter(function ($field) {
                return $field->type() === 'responsive'
                    && $this->getConfiguredAssetsFieldContainer($field) === $this->container;
            })
            ->each(function ($field) use ($dottedPrefix) {
                $this->updateArrayValue($field, $dottedPrefix);
            });

        return $this;
    }
stuartcusackie commented 2 years ago

Might not get around to it for a while but let me know if this looks good and if you want me to put together a PR.

riasvdv commented 2 years ago

Feel free to send a PR! If you feel up to it a test would be great as well

stuartcusackie commented 2 years ago

I think I can manage the PR but I am a total noob when it comes to writing tests. Leave it with me.

ncla commented 2 years ago

Thanks for taking the initiative. This is now available in v2.14.0. :tada:

stuartcusackie commented 2 years ago

Thanks for fixing it all up!