8000 [Form] Allow pass filter callback to delete_empty option. · symfony/symfony@8630abe · GitHub
[go: up one dir, main page]

Skip to content

Commit 8630abe

Browse files
committed
[Form] Allow pass filter callback to delete_empty option.
1 parent 7695112 commit 8630abe

File tree

3 files changed

+50
-4
lines changed

3 files changed

+50
-4
lines changed

src/Symfony/Component/Form/Extension/Core/EventListener/ResizeFormListener.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class ResizeFormListener implements EventSubscriberInterface
4848
protected $allowDelete;
4949

5050
/**
51-
* @var bool
51+
* @var bool|callable
5252
*/
5353
private $deleteEmpty;
5454

@@ -148,14 +148,15 @@ public function onSubmit(FormEvent $event)
148148
throw new UnexpectedTypeException($data, 'array or (\Traversable and \ArrayAccess)');
149149
}
150150

151-
if ($this->deleteEmpty) {
152-
$previousData = $event->getForm()->getData();
151+
if ($entryFilter = $this->deleteEmpty) {
152+
$previousData = $form->getData();
153153
foreach ($form as $name => $child) {
154154
$isNew = !isset($previousData[$name]);
155+
$isEmpty = is_callable($entryFilter) ? $entryFilter($child->getData()) : $child->isEmpty();
155156

156157
// $isNew can only be true if allowAdd is true, so we don't
157158
// need to check allowAdd again
158-
if ($child->isEmpty() && ($isNew || $this->allowDelete)) {
159+
if ($isEmpty && ($isNew || $this->allowDelete)) {
159160
unset($data[$name]);
160161
$form->remove($name);
161162
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ public function configureOptions(OptionsResolver $resolver)
100100
));
101101

102102
$resolver->setNormalizer('entry_options', $entryOptionsNormalizer);
103+
$resolver->setAllowedTypes('delete_empty', array('bool', 'callable'));
103104
}
104105

105106
/**

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

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Form\Tests\Extension\Core\Type;
1313

1414
use Symfony\Component\Form\Tests\Fixtures\Author;
15+
use Symfony\Component\Form\Tests\Fixtures\AuthorType;
1516

1617
class CollectionTypeTest extends BaseTypeTest
1718
{
@@ -110,6 +111,49 @@ public function testResizedDownIfSubmittedWithEmptyDataAndDeleteEmpty()
110111
$this->assertEquals(array('foo@foo.com'), $form->getData());
111112
}
112113

114+
public function testResizedDownWithDeleteEmptyCallable()
115+
{
116+
$form = $this->factory->create(static::TESTED_TYPE, null, array(
117+
'entry_type' => AuthorType::class,
118+
'allow_delete' => true,
119+
'delete_empty' => function (Author $obj = null) {
120+
return null === $obj || empty($obj->firstName);
121+
},
122+
));
123+
124+
$form->setData(array(new Author('Bob'), new Author('Alice')));
125+
$form->submit(array(array('firstName' => 'Bob'), array('firstName' => '')));
126+
127+
$this->assertTrue($form->has('0'));
128+
$this->assertFalse($form->has('1'));
129+
$this->assertEquals(new Author('Bob'), $form[0]->getData());
130+
$this->assertEquals(array(new Author('Bob')), $form->getData());
131+
}
132+
133+
public function testResizedDownIfSubmittedWithCompoundEmptyDataDeleteEmptyAndNoDataClass()
134+
{
135+
$form = $this->factory->create(static::TESTED_TYPE, null, array(
136+
'entry_type' => AuthorType::class,
137+
// If the field is not required, no new Author will be created if the
138+
// form is completely empty
139+
'entry_options' => array('data_class' => null),
140+
'allow_add' => true,
141+
'allow_delete' => true,
142+
'delete_empty' => function ($author) {
143+
return empty($author['firstName']);
144+
},
145+
));
146+
$form->setData(array(array('firstName' => 'first', 'lastName' => 'last')));
147+
$form->submit(array(
148+
array('firstName' => 's_first', 'lastName' => 's_last'),
149+
array('firstName' => '', 'lastName' => ''),
150+
));
151+
$this->assertTrue($form->has('0'));
152+
$this->assertFalse($form->has('1'));
153+
$this->assertEquals(array('firstName' => 's_first', 'lastName' => 's_last'), $form[0]->getData());
154+
$this->assertEquals(array(array('firstName' => 's_first', 'lastName' => 's_last')), $form->getData());
155+
}
156+
113157
public function testDontAddEmptyDataIfDeleteEmpty()
114158
{
115159
$form = $this->factory->create(static::TESTED_TYPE, null, array(

0 commit comments

Comments
 (0)
0