Skip to content

Commit 524c6ab

Browse files
Merge branch '6.1' into 6.2
2 parents 6c63a89 + 5fc3f2d commit 524c6ab

File tree

2 files changed

+74
-19
lines changed

2 files changed

+74
-19
lines changed

src/Forms/ListboxField.php

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -256,28 +256,31 @@ public function getValueArray()
256256
if (empty($validValues)) {
257257
return [];
258258
}
259-
260-
$canary = reset($validValues);
261-
$targetType = gettype($canary);
259+
if (!is_array($value) && ($value === 0 || $value === '0')) {
260+
$value = [$value];
261+
}
262262
if (is_array($value) && count($value) > 0) {
263-
$first = reset($value);
264-
// sanity check the values - make sure strings get strings, ints get ints etc
265-
if ($targetType !== gettype($first)) {
266-
$replaced = [];
267-
foreach ($value as $item) {
268-
if (!is_array($item)) {
269-
$item = json_decode($item ?? '', true);
270-
}
271-
272-
if ($targetType === gettype($item)) {
273-
$replaced[] = $item;
274-
} elseif (isset($item['Value'])) {
275-
$replaced[] = $item['Value'];
263+
$replaced = [];
264+
foreach ($value as $item) {
265+
if (!is_array($item) && is_string($item)) {
266+
$trimmed = trim($item);
267+
if ($trimmed !== '') {
268+
$firstChar = substr($trimmed, 0, 1);
269+
if ($firstChar === '{' || $firstChar === '[') {
270+
$decoded = json_decode($item, true);
271+
if (is_array($decoded)) {
272+
$item = $decoded;
273+
}
274+
}
276275
}
277276
}
278-
279-
$value = $replaced;
277+
if (is_array($item) && array_key_exists('Value', $item)) {
278+
$replaced[] = $item['Value'];
279+
} else {
280+
$replaced[] = $item;
281+
}
280282
}
283+
$value = $replaced;
281284
}
282285

283286
return $this->getListValues($value);

tests/php/Forms/ListboxFieldTest.php

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace SilverStripe\Forms\Tests;
44

5+
use PHPUnit\Framework\Attributes\DataProvider;
56
use SilverStripe\Forms\Tests\ListboxFieldTest\Article;
67
use SilverStripe\Forms\Tests\ListboxFieldTest\Tag;
78
use SilverStripe\Forms\Tests\ListboxFieldTest\TestObject;
@@ -11,7 +12,6 @@
1112
use SilverStripe\Forms\ListboxField;
1213
use SilverStripe\Forms\Validation\RequiredFieldsValidator;
1314
use SilverStripe\Model\ArrayData;
14-
use PHPUnit\Framework\Attributes\DataProvider;
1515

1616
class ListboxFieldTest extends SapphireTest
1717
{
@@ -119,6 +119,58 @@ public function testSaveIntoMultiple()
119119
$this->assertEquals('["a","c"]', $obj2->Choices);
120120
}
121121

122+
public static function provideSaveIntoValueScenarios(): array
123+
{
124+
return [
125+
'mixed-values' => [
126+
'input' => [null, 0, false, '123', -123, '', '0', 'ABC123'],
127+
'expected' => [null, 0, false, '123', -123, '', '0', 'ABC123'],
128+
],
129+
'string-values' => [
130+
'input' => ['123', '0', '-123', '', 'ABC123'],
131+
'expected' => ['123', '0', '-123', '', 'ABC123'],
132+
],
133+
'integer-values' => [
134+
'input' => [0, 123, -123],
135+
'expected' => [0, 123, -123],
136+
],
137+
'boolean-values' => [
138+
'input' => [false, true],
139+
'expected' => [false, true],
140+
],
141+
'null-only' => [
142+
'input' => [null],
143+
'expected' => [null],
144+
],
145+
'scalar-zero' => [
146+
'input' => 0,
147+
'expected' => [0],
148+
],
149+
'scalar-string-zero' => [
150+
'input' => '0',
151+
'expected' => ['0'],
152+
],
153+
];
154+
}
155+
156+
#[DataProvider('provideSaveIntoValueScenarios')]
157+
public function testSaveIntoPreservesValueTypes(mixed $input, array $expected): void
158+
{
159+
$choices = [
160+
'' => 'Empty string',
161+
0 => 'Zero',
162+
'123' => 'String integer',
163+
-123 => 'Negative integer',
164+
'ABC123' => 'Alpha-numeric string',
165+
'false' => 'False string',
166+
];
167+
$field = new ListboxField('Choices', 'Choices', $choices);
168+
$obj = new TestObject();
169+
$field->setValue($input);
170+
$field->saveInto($obj);
171+
$this->assertSame($expected, json_decode($obj->Choices, true));
172+
}
173+
122174
public function testSaveIntoManyManyRelation()
123175
{
124176
$article = $this->objFromFixture(Article::class, 'articlewithouttags');

0 commit comments

Comments
 (0)