MoonShine Version
4.15
Laravel Version
Other framework
PHP Version
8.2
Database Driver & Version
No response
Description
Bug: FieldsNames settings are discarded by Settings
Select::fieldsNames() passes the FieldsNames values to settings():
public function fieldsNames(FieldsNames $names): static
{
return $this->settings(array_filter($names->toArray()));
}
When an array is passed to settings(), a new Settings instance is created:
public function settings(array|Settings $settings): static
{
if (is_array($settings)) {
$settings = Settings::make($settings);
}
$this->settings = array_merge(
$this->settings,
$settings->toArray()
);
return $this;
}
The problem is that Settings only accepts keys declared in its $values array:
protected array $values = [
'delimiter' => null,
'splitOn' => null,
'diacritics' => null,
// ...
];
However, FieldsNames provides fields such as:
[
'valueField' => 'id',
'labelField' => 'name',
]
Since valueField and labelField are not present in Settings::$values, Settings::fromArray() silently ignores them:
foreach ($values as $name => $value) {
if (array_key_exists($name, $this->values)) {
$this->set($name, $value);
}
}
As a result, Settings becomes empty and the valueField / labelField configuration is lost.
Expected behavior
FieldsNames::make()->value('id')->label('name') should produce:
[
'valueField' => 'id',
'labelField' => 'name',
]
and these values should be preserved when passed through settings().
Suggested fix
Add the corresponding keys to Settings::$values:
protected array $values = [
'valueField' => null,
'labelField' => null,
'delimiter' => null,
'splitOn' => null,
// ...
];
The important part is that the bug occurs because an array is converted into Settings, and Settings::fromArray() filters unknown keys against $values, thereby dropping all FieldsNames settings.
Workaround
Due to a bug in Settings::fromArray(), FieldsNames cannot currently be passed to settings() as an array.
Instead, I create an empty Settings instance and populate the required fields using set():
$settings = Settings::make([])
->set('valueField', 'id')
->set('labelField', 'name')
->set('searchField', 'name');
->settings($settings)
This works because set() adds the values directly to the internal $values array, bypassing the filtering performed by Settings::fromArray().
The issue can be fixed upstream by adding these fields to Settings::$values or by changing the filtering logic in fromArray().
Select::make('Select')
->settings($settings)
Steps To Reproduce
- Create search select
- Get list with other fields, exmaple:
id, name, not label, value
MoonShine Version
4.15
Laravel Version
Other framework
PHP Version
8.2
Database Driver & Version
No response
Description
Bug:
FieldsNamessettings are discarded bySettingsSelect::fieldsNames()passes theFieldsNamesvalues tosettings():When an array is passed to
settings(), a newSettingsinstance is created:The problem is that
Settingsonly accepts keys declared in its$valuesarray:However,
FieldsNamesprovides fields such as:[ 'valueField' => 'id', 'labelField' => 'name', ]Since
valueFieldandlabelFieldare not present inSettings::$values,Settings::fromArray()silently ignores them:As a result,
Settingsbecomes empty and thevalueField/labelFieldconfiguration is lost.Expected behavior
FieldsNames::make()->value('id')->label('name')should produce:[ 'valueField' => 'id', 'labelField' => 'name', ]and these values should be preserved when passed through
settings().Suggested fix
Add the corresponding keys to
Settings::$values:The important part is that the bug occurs because an array is converted into
Settings, andSettings::fromArray()filters unknown keys against$values, thereby dropping allFieldsNamessettings.Workaround
Due to a bug in
Settings::fromArray(),FieldsNamescannot currently be passed tosettings()as an array.Instead, I create an empty
Settingsinstance and populate the required fields usingset():This works because
set()adds the values directly to the internal$valuesarray, bypassing the filtering performed bySettings::fromArray().The issue can be fixed upstream by adding these fields to
Settings::$valuesor by changing the filtering logic infromArray().Steps To Reproduce
id, name, notlabel, value