2

I'm trying to set the value of a custom field for an asset while uploading the asset. But somehow the value is not being saved. I can see the data in the EVENT_BEFORE_SAVE and EVENT_AFTER_SAVE hook, it is also in the dirty fields array, but it's just not saved in the database. What am I doing wrong?

Event::on(
    Asset::class,
    Asset::EVENT_BEFORE_HANDLE_FILE,
    function (AssetEvent $event) {
        if (Craft::$app->getRequest()->getIsCpRequest()) {
            $asset = $event->asset;
            if ($asset->extension === 'mp3' && $asset->tempFilePath) {
                $mp3 = new Mp3($asset->tempFilePath);
                $duration = $mp3->getDuration();
                $asset->setFieldValue('duration', $duration);
            }
        }
    }
);

1 Answer 1

1

I think you need to resave the element after using setFieldValue. Maybe try hooking into EVENT_AFTER_SAVE instead?

Event::on(
    Asset::class,
    Asset::EVENT_AFTER_SAVE,
    function (AssetEvent $event) {
        $asset = $event->asset;
        //Avoid endless loop if the asset already has duration set
        if ($asset->extension == 'mp3' && !$asset->duration) {
            $mp3 = new Mp3($asset->path);
            $duration = $mp3->getDuration();
            $asset->setFieldValue('duration', $duration);
            Craft::$app->getElements()->saveElement($asset);
        }
        
    }
);
2
  • Unfortunately that doesn't work. The asset is in S3, so I don't want to download it again. It has to happen before uploading it to S3. I am also getting the following errors: Argument #1 ($event) must be of type craft\events\AssetEvent, craft\events\ModelEvent given and Invalid field handle: duration (the duration field does exist though!) I did workaround those errors, and can see the duration is in the dirty fields array and the saveElement function is being called, but it's just not being saved! Jan 25 at 20:52
  • @thomasjonas - Looking at the EVENT_AFTER_SAVE docs, it's returning a ModelEvent instead of an AssetEvent. So changing... function (AssetEvent $event) { ...to ... function (ModelEvent $event) { ... should fix this error. Mar 27 at 20:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.