Skip to content

Commit

Permalink
[Form] Handle false as empty value on expanded choices
Browse files Browse the repository at this point in the history
  • Loading branch information
fancyweb committed Mar 3, 2020
1 parent dcf3da8 commit 1919349
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 1 deletion.
Expand Up @@ -33,6 +33,7 @@ public function buildForm(FormBuilderInterface $builder, array $options)
// doing so also calls setDataLocked(true).
$builder->setData(isset($options['data']) ? $options['data'] : false);
$builder->addViewTransformer(new BooleanToStringTransformer($options['value']));
$builder->setAttribute('false_is_empty', true);
}

/**
Expand Down
4 changes: 3 additions & 1 deletion src/Symfony/Component/Form/Form.php
Expand Up @@ -725,7 +725,9 @@ public function isEmpty()
// arrays, countables
((\is_array($this->modelData) || $this->modelData instanceof \Countable) && 0 === \count($this->modelData)) ||
// traversables that are not countable
($this->modelData instanceof \Traversable && 0 === iterator_count($this->modelData));
($this->modelData instanceof \Traversable && 0 === iterator_count($this->modelData)) ||
// @internal - Do not rely on it, it will be removed in Symfony 5.1.
(false === $this->modelData && $this->config->getAttribute('false_is_empty'));
}

/**
Expand Down
Expand Up @@ -2046,4 +2046,45 @@ public function provideTrimCases()
'Multiple expanded' => [true, true],
];
}

/**
* @dataProvider expandedIsEmptyWhenNoRealChoiceIsSelectedProvider
*/
public function testExpandedIsEmptyWhenNoRealChoiceIsSelected(bool $expected, $submittedData, bool $multiple, bool $required, $placeholder)
{
$options = [
'expanded' => true,
'choices' => [
'foo' => 'bar',
],
'multiple' => $multiple,
'required' => $required,
];

if (!$multiple) {
$options['placeholder'] = $placeholder;
}

$form = $this->factory->create(static::TESTED_TYPE, null, $options);

$form->submit($submittedData);

$this->assertSame($expected, $form->isEmpty());
}

public function expandedIsEmptyWhenNoRealChoiceIsSelectedProvider()
{
// Some invalid cases are voluntarily not tested:
// - multiple with placeholder
// - required with placeholder
return [
'Nothing submitted / single / not required / without a placeholder -> should be empty' => [true, null, false, false, null],
'Nothing submitted / single / not required / with a placeholder -> should not be empty' => [false, null, false, false, 'ccc'], // It falls back on the placeholder
'Nothing submitted / single / required / without a placeholder -> should be empty' => [true, null, false, true, null],
'Nothing submitted / single / required / with a placeholder -> should be empty' => [true, null, false, true, 'ccc'],
'Nothing submitted / multiple / not required / without a placeholder -> should be empty' => [true, null, true, false, null],
'Nothing submitted / multiple / required / without a placeholder -> should be empty' => [true, null, true, true, null],
'Placeholder submitted / single / not required / with a placeholder -> should not be empty' => [false, '', false, false, 'ccc'], // The placeholder is a selected value
];
}
}

0 comments on commit 1919349

Please sign in to comment.