1

We need to send a notification email when an entry's asset field, Custom Image, has been updated on entry save. We're able to do this consistently for text fields but I'm having trouble doing the same for an asset field.

// Use statements etc

...

// Register the event handler
Event::on(Entry::class, Entry::EVENT_AFTER_SAVE, [$this, 'handleAfterSave']);

...

public function handleAfterSave(ModelEvent $event): void
{
    $entry = $event->sender;
    $revisions = Entry::find()->revisionOf($entry)->status(null)->orderBy('revisionId DESC')->all();
    $lastRevision = Craft::$app->getElements()->getElementById($revisions[1]->id);

    $fields = Craft::$app->getFields();
    
    // text fields
    $notificationHandles = [
        'textField1',
        'textField2',
    ];
    $updatedFields = array_map(
        fn ($h) => [
            'fieldName' => $fields->getFieldByHandle($h)->name,
            'oldValue' => $lastRevision[$h],
            'newValue' => $entry[$h],
        ],
        // Only need to show field if different from last revision
        array_filter($notificationHandles, fn ($h) => $lastRevision[$h] !== $entry[$h])
    );
    
    if (count($updatedFields) > 0) {
        self::$notifications->notifyUpdated($entry, $updatedFields);
    }
}

The above works for text fields. However, when adapting for an asset field, it appears that $lastRevision[$h] is not immediately updated.

If we have an entry with an empty Custom Image asset field:

  1. Assign an image to Custom Image
  2. Save
  3. Email is sent
  4. Return to the entry
  5. Remove the asset from Custom Image
  6. Save
  7. No email is sent

To put it another way, if I have an entry with an empty Custom Image field:

  1. Assign an image to Custom Image
  2. Save
  3. Email is sent
  4. Return to the entry
  5. Remove the asset from Custom Image
  6. Save, but dump $lastRevision using EVENT_AFTER_SAVE
  7. We can see that customImage is still null, where I would expect it to show the previously attached image (an AssetQuery etc)
  8. No email is sent because both $lastRevision['customImage'] and $entry['customImage'] are null.

Thanks!

1

Have you tried the $element->isFieldDirty() method, or checking through the $element->dirtyFields array for your asset field, rather than checking revision dates?

There may be a good reason why you're not using those, but I thought I'd suggest it in case you hadn't considered it.

2
  • I appreciate the suggestion, and this does seem to consistently tell me that the asset field has changed. But we need details about the asset itself which I don't think we can get via dirtyFields. – plaintxt May 5 at 19:06
  • I decided to flag this as the correct answer because $element-dirtyFields does reliably tell me whether the Custom Image has been updated during the save cycle. I can then use $entry->customImage->one(), which will either return null (image removed) or an AssetQuery that I can use to get the detailed info we need. Thanks! – plaintxt May 5 at 20:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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