I'm trying to automatically fill out an asset field on an asset when it is being saved. (I'm generating an image, uploading it and want to put it in this field)
Everything is working, but It doesn't save the asset field.
I tested and it works fine with a text field 鈥撀燾ategory fields don't work either.
This is part of my code in the plugin I'm writing to achieve this:
Event::on(
Asset::class,
Asset::EVENT_AFTER_SAVE,
function(ModelEvent $e) {
$entry = $e->sender;
if($entry->volumeId == 2 && $entry->extension == 'mp3' && $e->isNew) {
$filepath = CRAFT_BASE_PATH . "/web/audio/" . $entry->path;
shell_exec(dirname(__FILE__) . "/spectrogram.sh '" . $filepath . "'");
$sonapath = substr($filepath, 0, -3) . "png";
$sonafilename = substr($entry->filename, 0, -3) . "png";
$asset = new Asset();
$asset->tempFilePath = $sonapath;
$asset->filename = $sonafilename;
$asset->newFolderId = 16;
$asset->volumeId = 1;
$asset->avoidFilenameConflicts = true;
$asset->setScenario(Asset::SCENARIO_CREATE);
$result = Craft::$app->elements->saveElement($asset);
$entry->setFieldValue('sonogramAsset', [$asset->id]); // This line is not doing anything
Craft::$app->elements->saveElement($entry);
}
}
);
EVENT_AFTER_SAVE is called _after_ the asset has been saved. Try doing this from EVENT_BEFORE_SAVE instead.
Thanks for your reply!
I'm saving it again (see the last line of code) - shouldn't that work?
Unfortunately I can't do this in EVENT_BEFORE_SAVE, because the script can't find the file at that stage.
Ah sorry I missed that. Try going with EVENT_AFTER_PROPAGATE instead. It鈥檚 a little further along in the element save lifecycle, and more reliable for this sort of thing.
Unfortunately that doesn't work either! I just can't save to category or asset fields here. Any other ideas?
Thanks so much for your help.
I managed to circumvent the issue by searching for the element again (which I already should have access to). Does that make sense?
$foundEntry = Asset::find()->id($entry->id)->one();
It works now, but seems like a weird solution.
I think this might be your issue:
$asset->setScenario(Asset::SCENARIO_CREATE);
That limits which validators will run, and opts out of some save functionality. Try changing to SCENARIO_DEFAULT.
Oh, it seems to work when i call setScenario(Asset::SCENARIO_DEFAULT) on the entry that called the event.
Thanks again!!
Sweet!