fix: duplicate action crashes on option settings cast#96
Conversation
getRawOriginal('settings') returns a raw JSON string, but
DataEloquentCast expects a Data object or array. Pass the hydrated
settings property instead.
There was a problem hiding this comment.
Pull request overview
Fixes a crash when duplicating custom fields that have option settings stored via a Spatie Laravel Data Eloquent cast, ensuring option settings are correctly preserved during duplication.
Changes:
- Update the field duplication action to pass the hydrated option
settingsvalue instead of the raw JSON string. - Add a regression test covering duplication of select fields while preserving per-option settings (e.g., color).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/Livewire/ManageCustomField.php |
Adjusts option cloning during duplication to use the cast/hydrated settings value. |
tests/Feature/Admin/Pages/CustomFieldsFieldManagementTest.php |
Adds a regression test asserting option settings are preserved when duplicating a select field. |
| $clone->options()->create([ | ||
| 'name' => $option->getRawOriginal('name'), | ||
| 'sort_order' => $option->sort_order, | ||
| 'settings' => $option->getRawOriginal('settings'), | ||
| 'settings' => $option->settings, | ||
| ]); |
There was a problem hiding this comment.
In the duplication loop, using $option->getRawOriginal('name') can break encrypted fields: CustomFieldOption::saving() will encrypt the provided name when the parent field is encrypted, so passing an already-encrypted raw DB value will result in double encryption and unreadable option labels. Prefer duplicating with the decrypted accessor value (e.g., $option->name) and, if concerned about N+1 queries, eager-load the relation needed by the accessor before the loop or handle decryption based on $this->field->settings->encrypted.
| $field->options->first()->update(['settings' => new \Relaticle\CustomFields\Data\CustomFieldOptionSettingsData(color: '#ff0000')]); | ||
| $field->options->last()->update(['settings' => new \Relaticle\CustomFields\Data\CustomFieldOptionSettingsData(color: '#0000ff')]); |
There was a problem hiding this comment.
This test uses fully-qualified \Relaticle\CustomFields\Data\CustomFieldOptionSettingsData inline. For consistency with the rest of the file (which imports its dependencies at the top) and to keep the test more readable, consider adding a use import and referencing CustomFieldOptionSettingsData directly.
Summary
getRawOriginal('settings')returns a raw JSON string, butDataEloquentCast::set()expects aDataobject or array — causing aCannotCastDataexception when duplicating a field with options$option->settingswhich passes the hydratedCustomFieldOptionSettingsDataobjectTest plan
can duplicate a select field and preserve option settings