[Form] Ignoring invalid forms from delete_empty behavior in CollectionType

This commit is contained in:
Yonel Ceruto 2021-02-19 17:17:21 -05:00 committed by Fabien Potencier
parent 1329689ace
commit e4911554e3
3 changed files with 30 additions and 3 deletions

View File

@ -132,6 +132,10 @@ class ResizeFormListener implements EventSubscriberInterface
$previousData = $form->getData(); $previousData = $form->getData();
/** @var FormInterface $child */ /** @var FormInterface $child */
foreach ($form as $name => $child) { foreach ($form as $name => $child) {
if (!$child->isValid() || !$child->isSynchronized()) {
continue;
}
$isNew = !isset($previousData[$name]); $isNew = !isset($previousData[$name]);
$isEmpty = \is_callable($this->deleteEmpty) ? ($this->deleteEmpty)($child->getData()) : $child->isEmpty(); $isEmpty = \is_callable($this->deleteEmpty) ? ($this->deleteEmpty)($child->getData()) : $child->isEmpty();

View File

@ -255,7 +255,7 @@ class ResizeFormListenerTest extends TestCase
$data = [0 => 'first', 1 => '']; $data = [0 => 'first', 1 => ''];
foreach ($data as $child => $dat) { foreach ($data as $child => $dat) {
$this->form->get($child)->setData($dat); $this->form->get($child)->submit($dat);
} }
$event = new FormEvent($this->form, $data); $event = new FormEvent($this->form, $data);
$listener = new ResizeFormListener('text', [], false, true, true); $listener = new ResizeFormListener('text', [], false, true, true);
@ -282,11 +282,11 @@ class ResizeFormListenerTest extends TestCase
$data = ['0' => ['name' => 'John'], '1' => ['name' => '']]; $data = ['0' => ['name' => 'John'], '1' => ['name' => '']];
foreach ($data as $child => $dat) { foreach ($data as $child => $dat) {
$this->form->get($child)->setData($dat); $this->form->get($child)->submit($dat);
} }
$event = new FormEvent($this->form, $data); $event = new FormEvent($this->form, $data);
$callback = function ($data) { $callback = function ($data) {
return '' === $data['name']; return null === $data['name'];
}; };
$listener = new ResizeFormListener('text', [], false, true, $callback); $listener = new ResizeFormListener('text', [], false, true, $callback);
$listener->onSubmit($event); $listener->onSubmit($event);

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\Form\Tests\Extension\Core\Type; namespace Symfony\Component\Form\Tests\Extension\Core\Type;
use Symfony\Component\Form\Exception\UnexpectedTypeException; use Symfony\Component\Form\Exception\UnexpectedTypeException;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Form; use Symfony\Component\Form\Form;
use Symfony\Component\Form\Tests\Fixtures\Author; use Symfony\Component\Form\Tests\Fixtures\Author;
use Symfony\Component\Form\Tests\Fixtures\AuthorType; use Symfony\Component\Form\Tests\Fixtures\AuthorType;
@ -211,6 +212,28 @@ class CollectionTypeTest extends BaseTypeTest
$this->assertEquals([new Author('s_first', 's_last')], $form->getData()); $this->assertEquals([new Author('s_first', 's_last')], $form->getData());
} }
public function testNotDeleteEmptyIfInvalid()
{
$form = $this->factory->create(static::TESTED_TYPE, null, [
'entry_type' => ChoiceType::class,
'entry_options' => [
'choices' => ['a', 'b'],
],
'allow_add' => true,
'allow_delete' => true,
'delete_empty' => true,
]);
$form->submit(['a', 'x', '']);
$this->assertSame(['a'], $form->getData());
$this->assertCount(2, $form);
$this->assertTrue($form->has('1'));
$this->assertFalse($form[1]->isValid());
$this->assertNull($form[1]->getData());
$this->assertSame('x', $form[1]->getViewData());
}
public function testNotResizedIfSubmittedWithExtraData() public function testNotResizedIfSubmittedWithExtraData()
{ {
$form = $this->factory->create(static::TESTED_TYPE, null, [ $form = $this->factory->create(static::TESTED_TYPE, null, [