-
-
Notifications
You must be signed in to change notification settings - Fork 227
Description
Winter CMS Build
1.2
PHP Version
8.3
Database engine
MySQL/MariaDB
Plugins installed
No response
Issue description
While testing the upgrade from Winter CMS 1.2.3 to 1.2.7, an automated test began failing because changes to a settings model in its beforeSave function are lost immediately after the beforeSave function returns. I have traced it down to the Winter\Storm\Database\Model::bootNicerEvents function where it fires $model->fireEvent('model.beforeSave').
I added a dump at the end of the beforeSave and the attributes are what I expect. I added a dump just after this event is fired and the attributes are reverted.
After Luke's hint to look at this commit, I changed bindEventOnce to bindEvent in the bootNicerEvents function and it started working as expected, so this commit is the likely cause of the issue. However, the root cause may be something deeper inside of the bindEventOnce function specifically for settings models.
Steps to replicate
- Create a settings model with some simple text fields.
- Run something like
php artisan create:settings Company.Plugin TestSettings - Add the following to the fields.yaml file:
- Run something like
fields:
foo:
label: Foo
type: text
bar:
label: Bar
type: text
- Register the backend settings page as needed to point to this new settings model.
'test' => [
'label' => 'Test Settings',
'description' => 'Test settings.',
'icon' => 'icon-lock',
'category' => 'Testing',
'class' => 'Company\Plugin\Models\TestSettings',
'order' => 30,
'keywords' => 'testing',
'permissions' => ['company.plugin.*'],
],
- Add a beforeSave function to the settings model and override the value attribute with something noticeable.
public function beforeSave()
{
$value = json_decode($this->attributes['value'] ?? '[]', true);
$value['foo'] = 'nonsense';
$value['baz'] = 'more nonsense';
$this->attributes['value'] = json_encode($value);
}
- Open the backend settings page, change the values in the text fields, and click the save button.
- Check the
system_settingstable to verify that it accepted the values on the form and whether it accepted the changes from the beforeSave function. - Modify
Winter\Storm\Database\Model::bootNicerEventsto usebindEventinstead ofbindEventOnceand repeat steps 4-5 again.
Workaround
It appears that beforeValidate does not exhibit this same behavior, so it can be used instead if needed/possible.