Multiple calls to \craft\services\Assets::moveAsset() in same request
@andris-sevcenko is already working on this.
Since Mar 26, 2020.
- Dominant language
- PHP
- Stars
- 3.6k
- Forks
- 705
- Avg merge
- 1d 5h
- Merged PRs (30d)
- 134
Description
Description
What I am trying to do is renumber all filenames of of a particular folder so they are in a sequential order (in this case, the order that they are set in when they appear in an asset field for a particular entry). This has to be a 2 step process. i.e. rename all files to a temporary name and then rename them back to the desired name. This is to avoid conflicting filenames.
The first time a call is made like: Craft::$app->getAssets()->moveAsset(...) it works. If you call the same function again on the same asset in the same request you get undefined (difficult to pin down) behaviour.
The effect depends on what the particular case is, but usually some files get renamed and others do not. Sometimes assets appear to swap the associated file on the filesystem.
I believe this happens because moveAsset() essentially, just calls Craft::$app->getElements()->saveElement(...) after setting some things up. When the asset is saved, the file operation of actually moving the file happens in an afterSave() event / hook / call on the Asset element, therefore something not sure what yet, changes during the file-op and is not updated (i.e. saved) in the AssetRecord which would already have been saved.
It can be worked around by explicitly reloading the asset before doing the second call of moveAsset() with something like: $asset = Asset::find()->id($asset->id)->one() but it's not very performant .
Steps to reproduce
- Have a folder in a volume with multiple files as assets
- Call
Craft::$app->getAssets()->moveAsset(...)on each of them with random filename - Call
Craft::$app->getAssets()->moveAsset(...)again on each going back to sequential filenames
Additional info
- Craft version: 3.4.10.1
- PHP version: 7.4.4
- Database driver & version: MySQL 5.7.29
- Plugins & versions: N/A
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.