Changing fields in beforeSave event does not work on first save
Nobody has claimed this yet.
- Dominant language
- PHP
- Stars
- 3.6k
- Forks
- 705
- Avg merge
- 1d 5h
- Merged PRs (30d)
- 134
Description
Description
When saving an entry it is possible to hook into the saving-process to change/add some values before actually saving. This used to work fine, but since upgrading to 3.7 it seems it does not work anymore, specifically when saving an entirely new entry. However, when opening and saving an existing entry or when a new entry first comes back with validation errors, it still works fine. It's only when a new entry is saved without getting validation errors that the changes made by the event aren't saved.
This code is what we use to fill a 'sortingDate' field with the current date when the entry is enabled but does not have a sortingDate-value yet:
// Fill sortingDate when article is about to be enabled
Event::on(Entry::class, Element::EVENT_BEFORE_SAVE, function (ModelEvent $e) {
$entry = $e->sender;
if ($entry->section->handle === 'article') {
if ($entry->enabled && !$entry->sortingDate) {
// Default the post date to the current date/time
$entry->sortingDate = new \DateTime();
// ...without the seconds
$entry->sortingDate->setTimestamp($entry->sortingDate->getTimestamp() - ($entry->sortingDate->getTimestamp() % 60));
}
}
});
Steps to reproduce
- Create a section with a sortingDate datetime-field with section-handle 'article'
- Add a module with the above code
- Create a new entry in the section with a title and enable it
- Save the entry, you'll see that the sortingDate field stays empty
- Re-open and save again, you'll see the field is now filled with the current date/time as intended
- Create a new entry, but this time omit the title, then enable & save it
- You'll get returned with a validation error, but the publication + sortingDate fields will now be filled with the current date, and are persisted when fixing the validation issue and saving again.
Additional info
- Craft version: 3.7.8
- PHP version: 7.4.16
- Database driver & version: MySQL 5.5.5 (MariaDB)
- Plugins & versions:
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.
Research direction
Start by tracing the Element::EVENT_BEFORE_SAVE handling for a new Entry and compare the initial valid save with the validation-error retry described in the reproduction steps. The Event::on callback and ModelEvent sender are the relevant entry points. Done means changes such as sortingDate persist on the first valid save, without breaking the retry case.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100