Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7c430bd

Browse files
committed
[Form] Add "is empty callback" to form config
1 parent dab6732 commit 7c430bd

16 files changed

+153
-0
lines changed

UPGRADE-5.1.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
UPGRADE FROM 5.0 to 5.1
2+
=======================
3+
4+
Form
5+
----
6+
7+
* Implementing the `FormConfigInterface` without implementing the `getIsEmptyCallback()` method
8+
is deprecated. The method will be added to the interface in 6.0.
9+
* Implementing the `FormConfigBuilderInterface` without implementing the `setIsEmptyCallback()` method
10+
is deprecated. The method will be added to the interface in 6.0.

UPGRADE-6.0.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
UPGRADE FROM 5.x to 6.0
2+
=======================
3+
4+
Form
5+
----
6+
7+
* Added the `getIsEmptyCallback()` method to the `FormConfigInterface`.
8+
* Added the `setIsEmptyCallback()` method to the `FormConfigBuilderInterface`.

src/Symfony/Component/Form/ButtonBuilder.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,16 @@ public function getFormConfig()
466466
return $config;
467467
}
468468

469+
/**
470+
* Unsupported method.
471+
*
472+
* @throws BadMethodCallException
473+
*/
474+
public function setIsEmptyCallback(?callable $isEmptyCallback)
475+
{
476+
throw new BadMethodCallException('Buttons do not support "is empty" callback.');
477+
}
478+
469479
/**
470480
* Unsupported method.
471481
*/
@@ -738,6 +748,16 @@ public function getOption(string $name, $default = null)
738748
return \array_key_exists($name, $this->options) ? $this->options[$name] : $default;
739749
}
740750

751+
/**
752+
* Unsupported method.
753+
*
754+
* @throws BadMethodCallException
755+
*/
756+
public function getIsEmptyCallback(): ?callable
757+
{
758+
throw new BadMethodCallException('Buttons do not support "is empty" callback.');
759+
}
760+
741761
/**
742762
* Unsupported method.
743763
*

src/Symfony/Component/Form/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
CHANGELOG
22
=========
33

4+
5.1.0
5+
-----
6+
7+
* Implementing the `FormConfigInterface` without implementing the `getIsEmptyCallback()` method
8+
is deprecated. The method will be added to the interface in 6.0.
9+
* Implementing the `FormConfigBuilderInterface` without implementing the `setIsEmptyCallback()` method
10+
is deprecated. The method will be added to the interface in 6.0.
11+
412
5.0.0
513
-----
614

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ public function configureOptions(OptionsResolver $resolver)
6060
'empty_data' => $emptyData,
6161
'compound' => false,
6262
'false_values' => [null],
63+
'is_empty_callback' => static function ($modelData): bool {
64+
return false === $modelData;
65+
},
6366
]);
6467

6568
$resolver->setAllowedTypes('false_values', 'array');

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper;
1616
use Symfony\Component\Form\Extension\Core\EventListener\TrimListener;
1717
use Symfony\Component\Form\FormBuilderInterface;
18+
use Symfony\Component\Form\FormConfigBuilderInterface;
1819
use Symfony\Component\Form\FormInterface;
1920
use Symfony\Component\Form\FormView;
2021
use Symfony\Component\OptionsResolver\Options;
@@ -58,6 +59,14 @@ public function buildForm(FormBuilderInterface $builder, array $options)
5859
if ($options['trim']) {
5960
$builder->addEventSubscriber(new TrimListener());
6061
}
62+
63+
if (!method_exists($builder, 'setIsEmptyCallback')) {
64+
@trigger_error(sprintf('Not implementing the "%s::setIsEmptyCallback()" method in "%s" is deprecated since Symfony 5.1.', FormConfigBuilderInterface::class, \get_class($builder)), E_USER_DEPRECATED);
65+
66+
return;
67+
}
68+
69+
$builder->setIsEmptyCallback($options['is_empty_callback']);
6170
}
6271

6372
/**
@@ -190,13 +199,15 @@ public function configureOptions(OptionsResolver $resolver)
190199
'help_attr' => [],
191200
'help_html' => false,
192201
'help_translation_parameters' => [],
202+
'is_empty_callback' => null,
193203
]);
194204

195205
$resolver->setAllowedTypes('label_attr', 'array');
196206
$resolver->setAllowedTypes('upload_max_size_message', ['callable']);
197207
$resolver->setAllowedTypes('help', ['string', 'null']);
198208
$resolver->setAllowedTypes('help_attr', 'array');
199209
$resolver->setAllowedTypes('help_html', 'bool');
210+
$resolver->setAllowedTypes('is_empty_callback', ['null', 'callable']);
200211
}
201212

202213
/**

src/Symfony/Component/Form/Form.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,18 @@ public function isEmpty()
726726
}
727727
}
728728

729+
if (!method_exists($this->config, 'getIsEmptyCallback')) {
730+
@trigger_error(sprintf('Not implementing the "%s::getIsEmptyCallback()" method in "%s" is deprecated since Symfony 5.1.', FormConfigInterface::class, \get_class($this->config)), E_USER_DEPRECATED);
731+
732+
$isEmptyCallback = null;
733+
} else {
734+
$isEmptyCallback = $this->config->getIsEmptyCallback();
735+
}
736+
737+
if (null !== $isEmptyCallback) {
738+
return $isEmptyCallback($this->modelData);
739+
}
740+
729741
return FormUtil::isEmpty($this->modelData) ||
730742
// arrays, countables
731743
((\is_array($this->modelData) || $this->modelData instanceof \Countable) && 0 === \count($this->modelData)) ||

src/Symfony/Component/Form/FormConfigBuilder.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Symfony\Component\EventDispatcher\ImmutableEventDispatcher;
1717
use Symfony\Component\Form\Exception\BadMethodCallException;
1818
use Symfony\Component\Form\Exception\InvalidArgumentException;
19+
use Symfony\Component\Form\Util\FormUtil;
1920
use Symfony\Component\PropertyAccess\PropertyPath;
2021
use Symfony\Component\PropertyAccess\PropertyPathInterface;
2122

@@ -102,6 +103,7 @@ class FormConfigBuilder implements FormConfigBuilderInterface
102103

103104
private $autoInitialize = false;
104105
private $options;
106+
private $isEmptyCallback;
105107

106108
/**
107109
* Creates an empty form configuration.
@@ -461,6 +463,11 @@ public function getOption(string $name, $default = null)
461463
return \array_key_exists($name, $this->options) ? $this->options[$name] : $default;
462464
}
463465

466+
public function getIsEmptyCallback(): ?callable
467+
{
468+
return $this->isEmptyCallback;
469+
}
470+
464471
/**
465472
* {@inheritdoc}
466473
*/
@@ -761,6 +768,16 @@ public function getFormConfig()
761768
return $config;
762769
}
763770

771+
/**
772+
* {@inheritdoc}
773+
*/
774+
public function setIsEmptyCallback(?callable $isEmptyCallback)
775+
{
776+
$this->isEmptyCallback = $isEmptyCallback;
777+
778+
return $this;
779+
}
780+
764781
/**
765782
* Validates whether the given variable is a valid form name.
766783
*

src/Symfony/Component/Form/FormConfigBuilderInterface.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
/**
1818
* @author Bernhard Schussek <[email protected]>
19+
*
20+
* @method $this setIsEmptyCallback(callable|null $isEmptyCallback) Sets the callback that will be called to determine if the model data of the form is empty or not - not implementing it is deprecated since Symfony 5.1
1921
*/
2022
interface FormConfigBuilderInterface extends FormConfigInterface
2123
{

src/Symfony/Component/Form/FormConfigInterface.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
* The configuration of a {@link Form} object.
1919
*
2020
* @author Bernhard Schussek <[email protected]>
21+
*
22+
* @method callable|null getIsEmptyCallback() Returns a callable that takes the model data as argument and that returns if it is empty or not - not implementing it is deprecated since Symfony 5.1
2123
*/
2224
interface FormConfigInterface
2325
{

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

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

src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
"help_html",
4343
"help_translation_parameters",
4444
"inherit_data",
45+
"is_empty_callback",
4546
"label",
4647
"label_attr",
4748
"label_format",

src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Symfony\Component\Form\Extension\Core\Type\ChoiceType (Block prefix: "choice")
2222
help_html
2323
help_translation_parameters
2424
inherit_data
25+
is_empty_callback
2526
label
2627
label_attr
2728
label_format

src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_2.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"help_html",
2323
"help_translation_parameters",
2424
"inherit_data",
25+
"is_empty_callback",
2526
"label",
2627
"label_attr",
2728
"label_format",

src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_2.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Symfony\Component\Form\Extension\Core\Type\FormType (Block prefix: "form")
2424
help_html
2525
help_translation_parameters
2626
inherit_data
27+
is_empty_callback
2728
label
2829
label_attr
2930
label_format

src/Symfony/Component/Form/Tests/SimpleFormTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,6 +1097,21 @@ public function testCannotCallGetViewDataInPreSetDataListener()
10971097
$form->setData('foo');
10981098
}
10991099

1100+
public function testIsEmptyCallback()
1101+
{
1102+
$config = new FormConfigBuilder('foo', null, $this->dispatcher);
1103+
1104+
$config->setIsEmptyCallback(function ($modelData): bool { return 'ccc' === $modelData; });
1105+
$form = new Form($config);
1106+
$form->setData('ccc');
1107+
$this->assertTrue($form->isEmpty());
1108+
1109+
$config->setIsEmptyCallback(function (): bool { return false; });
1110+
$form = new Form($config);
1111+
$form->setData(null);
1112+
$this->assertFalse($form->isEmpty());
1113+
}
1114+
11001115
protected function createForm(): FormInterface
11011116
{
11021117
return $this->getBuilder()->getForm();

0 commit comments

Comments
 (0)