8000 [Form] Handle false as empty value on expanded choices · symfony/symfony@1919349 · GitHub
[go: up one dir, main page]

Skip to content

Commit 1919349

Browse files
committed
[Form] Handle false as empty value on expanded choices
1 parent dcf3da8 commit 1919349

File tree

3 files changed

+45
-1
lines changed

3 files changed

+45
-1
lines changed

src/Symfony/Component/Form/Extension/Core/Type/CheckboxType.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public function buildForm(FormBuilderInterface $builder, array $options)
3333
// doing so also calls setDataLocked(true).
3434
$builder->setData(isset($options['data']) ? $options['data'] : false);
3535
$builder->addViewTransformer(new BooleanToStringTransformer($options['value']));
36+
$builder->setAttribute('false_is_empty', true);
3637
}
3738

3839
/**

src/Symfony/Component/Form/Form.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -725,7 +725,9 @@ public function isEmpty()
725725
// arrays, countables
726726
((\is_array($this->modelData) || $this->modelData instanceof \Countable) && 0 === \count($this->modelData)) ||
727727
// traversables that are not countable
728-
($this->modelData instanceof \Traversable && 0 === iterator_count($this->modelData));
728+
($this->modelData instanceof \Traversable && 0 === iterator_count($this->modelData)) ||
729+
// @internal - Do not rely on it, it will be removed in Symfony 5.1.
730+
(false === $this->modelData && $this->config->getAttribute('false_is_empty'));
729731
}
730732

731733
/**

src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2046,4 +2046,45 @@ public function provideTrimCases()
20462046
'Multiple expanded' => [true, true],
20472047
];
20482048
}
2049+
2050+
/**
2051+
* @dataProvider expandedIsEmptyWhenNoRealChoiceIsSelectedProvider
2052+
*/
2053+
public function testExpandedIsEmptyWhenNoRealChoiceIsSelected(bool $expected, $submittedData, bool $multiple, bool $required, $placeholder)
2054+
{
2055+
$options = [
2056+
'expanded' => true,
2057+
'choices' => [
2058+
'foo' => 'bar',
2059+
],
2060+
'multiple' => $multiple,
2061+
'required' => $required,
2062+
];
2063+
2064+
if (!$multiple) {
2065+
$options['placeholder'] = $placeholder;
2066+
}
2067+
2068+
$form = $this->factory->create(static::TESTED_TYPE, null, $options);
2069+
2070+
$form->submit($submittedData);
2071+
2072+
$this->assertSame($expected, $form->isEmpty());
2073+
}
2074+
2075+
public function expandedIsEmptyWhenNoRealChoiceIsSelectedProvider()
2076+
{
2077+
// Some invalid cases are voluntarily not tested:
2078+
// - multiple with placeholder
2079+
// - required with placeholder
2080+
return [
2081+
'Nothing submitted / single / not required / without a placeholder -> should be empty' => [true, null, false, false, null],
2082+
'Nothing submitted / single / not required / with a placeholder -> should not be empty' => [false, null, false, false, 'ccc'], // It falls back on the placeholder
2083+
'Nothing submitted / single / required / without a placeholder -> should be empty' => [true, null, false, true, null],
2084+
'Nothing submitted / single / required / with a placeholder -> should be empty' => [true, null, false, true, 'ccc'],
2085+
'Nothing submitted / multiple / not required / without a placeholder -> should be empty' => [true, null, true, false, null],
2086+
'Nothing submitted / multiple / required / without a placeholder -> should be empty' => [true, null, true, true, null],
2087+
'Placeholder submitted / single / not required / with a placeholder -> should not be empty' => [false, '', false, false, 'ccc'], // The placeholder is a selected value
2088+
];
2089+
}
20492090
}

0 commit comments

Comments
 (0)
0