diff --git a/src/Fieldtypes/HasSelectOptions.php b/src/Fieldtypes/HasSelectOptions.php index 219a664e0c8..0f04e6a38d7 100644 --- a/src/Fieldtypes/HasSelectOptions.php +++ b/src/Fieldtypes/HasSelectOptions.php @@ -66,9 +66,18 @@ public function preProcess($value) return []; } + $keys = collect($this->getOptions())->pluck('value'); + // NOTE: Null-coalescing into `[null]` as that matches old behaviour. - $values = collect($value ?? [null])->map(function ($value) { - return $this->config('cast_booleans') ? $this->castFromBoolean($value) : $value; + $values = collect($value ?? [null])->map(function ($value) use ($keys) { + $value = $this->config('cast_booleans') ? $this->castFromBoolean($value) : $value; + + // Front-end form submissions store numeric keys as strings, e.g. '1' for an option key of 1. + if (is_string($value) && ! $keys->containsStrict($value)) { + $value = $keys->first(fn ($key) => is_int($key) && (string) $key === $value) ?? $value; + } + + return $value; }); return $multiple ? $values->all() : $values->first(); diff --git a/tests/Fieldtypes/HasSelectOptionsTests.php b/tests/Fieldtypes/HasSelectOptionsTests.php index fa655bf5482..efe3f899dd4 100644 --- a/tests/Fieldtypes/HasSelectOptionsTests.php +++ b/tests/Fieldtypes/HasSelectOptionsTests.php @@ -104,6 +104,29 @@ public static function preProcessIndexProvider() 'two', ['two'], ], + 'numeric keys with string value' => [ + [ + ['key' => 926450000, 'value' => 'One'], + ['key' => 926450001, 'value' => 'Two'], + ], + '926450001', + ['Two'], + ], + 'numeric keys with differently formatted string value' => [ + [ + ['key' => 1, 'value' => 'One'], + ], + '01', + ['01'], + ], + 'numeric and string keys with string value' => [ + [ + ['key' => 1, 'value' => 'One'], + ['key' => '1', 'value' => 'String One'], + ], + '1', + ['String One'], + ], ]; } }