Cms: Assets.php getAssetUrl() doesn't account for the focalPoint

Created on 11 Dec 2017  路  5Comments  路  Source: craftcms/cms

Craft CMS 3 RC1; calling Assets.php's getAssetUrl() doesn't account for the focalPoint

Expected result:

getAssetUrl() would account for the focalPoint set on the Asset

Actual result:

getAssetUrl() doesn't appear to take the Asset's focalPoint into consideration when generating the image; instead it relies on the position setting in the AssetTranform.

I'm not sure if this is expected behavior?

Most helpful comment

Thank you @andris-sevcenko !

All 5 comments

So I've been doing some further testing, and it _does_ work... the first time.

But if you then change the focalPoint and Save it... it doesn't regenerate the image with the new focalPoint.

If you delete the image transforms from the folder, and clear the Asset Indexes, then it does work.

Steps to reproduce:

1) Create an Image Transform in the AdminCP called test; set it to crop 200x200, or whatever you like
2) Open up an Asset, and Set a Focal Point on the image
3) Display the image on the frontend with <img src="{{ entry.someAsset.one().getUrl('test') }}">
4) Click on the Asset, then choose "Edit Image" from the gear menu, and change the Focal Point
5) Reload the frontend image

Expected result:

The image is displayed centered around the new Focal Point

Actual result:

The image doesn't change until you delete the transformed images from the transform directories, and clear the asset caches via Utilities -> Clear Caches

Thank you @andris-sevcenko !

So this is _almost_ perfect @andris-sevcenko -- please don't hurt me, but can you nuke the transforms _before_ you save the asset?

I think it probably makes sense to clear out any transformed images before saving the asset, in case someone like me saves image variants afterElementSave()

Just by moving it up like this, it works perfectly:

``` if ($replace) {
$nukeTransforms = $asset->focalPoint !== $focal;
$asset->focalPoint = $focal;

            if ($nukeTransforms) {
                $transforms = Craft::$app->getAssetTransforms();
                $transforms->deleteCreatedTransformsForAsset($asset);
                $transforms->deleteTransformIndexDataByAssetId($assetId);
            }

            // Only replace file if it changed, otherwise just save changed focal points
            if ($imageChanged) {
                $assets->replaceAssetFile($asset, $imageCopy, $asset->filename);
            } else if ($focal) {
                Craft::$app->getElements()->saveElement($asset);
            }

        } else {
            $newAsset = new Asset();
            $newAsset->avoidFilenameConflicts = true;
            $newAsset->setScenario(Asset::SCENARIO_CREATE);

            $newAsset->tempFilePath = $imageCopy;
            $newAsset->filename = $asset->filename;
            $newAsset->newFolderId = $folder->id;
            $newAsset->volumeId = $folder->volumeId;
            $newAsset->focalPoint = $focal;

            // Don't validate required custom fields
            Craft::$app->getElements()->saveElement($newAsset);
        }

```

Otherwise, what I have to do is listen for Elements::EVENT_AFTER_SAVE_ELEMENT and then kick off a second re-save of the element after it's actually been saved due to the Focal Point changing.

I'll buy the next burger...

There's just no pleasing some people... :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

timkelty picture timkelty  路  3Comments

leigeber picture leigeber  路  3Comments

mattstein picture mattstein  路  3Comments

RitterKnightCreative picture RitterKnightCreative  路  3Comments

angrybrad picture angrybrad  路  3Comments