8000 add reindexOnSubmit option to ResizeFormListener · symfony/symfony@a4462c8 · GitHub
[go: up one dir, main page]

Skip to content

Commit a4462c8

Browse files
add reindexOnSubmit option to ResizeFormListener
1 parent dc5e0b2 commit a4462c8

File tree

3 files changed

+86
-22
lines changed

3 files changed

+86
-22
lines changed

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

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,22 @@ class ResizeFormListener implements EventSubscriberInterface
3030
protected $allowDelete;
3131

3232
private $deleteEmpty;
33+
private $reindexOnSubmit;
3334

3435
/**
35-
* @param bool $allowAdd Whether children could be added to the group
36-
* @param bool $allowDelete Whether children could be removed from the group
36+
* @param bool $allowAdd Whether children could be added to the group
37+
* @param bool $allowDelete Whether children could be removed from the group
3738
* @param bool|callable $deleteEmpty
39+
* @param bool $reindexOnSubmit Whether children should be renamed with sequential keys after submit
3840
*/
39-
public function __construct(string $type, array $options = [], bool $allowAdd = false, bool $allowDelete = false, $deleteEmpty = false)
41+
public function __construct(string $type, array $options = [], bool $allowAdd = false, bool $allowDelete = false, $deleteEmpty = false, $reindexOnSubmit = false)
4042
{
4143
$this->type = $type;
4244
$this->allowAdd = $allowAdd;
4345
$this->allowDelete = $allowDelete;
4446
$this->options = $options;
4547
$this->deleteEmpty = $deleteEmpty;
48+
$this->reindexOnSubmit = $reindexOnSubmit;
4649
}
4750

4851
public static function getSubscribedEvents()
@@ -160,6 +163,20 @@ public function onSubmit(FormEvent $event)
160163
}
161164
}
162165

166+
if ($this->reindexOnSubmit) {
167+
$formReindex = [];
168+
foreach ($form as $name => $child) {
169+
$formReindex[] = $child;
170+
$form->remove($name);
171+
}
172+
foreach ($formReindex as $index => $child) {
173+
$form->add($index, $this->type, array_replace([
174+
'property_path' => '['.$index.']',
175+
], $this->options));
176+
}
177+
$data = array_values($data);
178+
}
179+
163180
$event->setData($data);
164181
}
165182
}

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ public function buildForm(FormBuilderInterface $builder, array $options)
4545
$options['entry_options'],
4646
$options['allow_add'],
4747
$options['allow_delete'],
48-
$options['delete_empty']
48+
$options['delete_empty'],
49+
$options['reindex_on_submit']
4950
);
5051

5152
$builder->addEventSubscriber($resizeListener);
@@ -97,10 +98,12 @@ public function configureOptions(OptionsResolver $resolver)
9798
'entry_type' => TextType::class,
9899
'entry_options' => [],
99100
'delete_empty' => false,
101+
'reindex_on_submit' => false,
100102
]);
101103

102104
$resolver->setNormalizer('entry_options', $entryOptionsNormalizer);
103105
$resolver->setAllowedTypes('delete_empty', ['bool', 'callable']);
106+
$resolver->setAllowedTypes('reindex_on_submit', ['bool']);
104107
}
105108

106109
/**

src/Symfony/Component/Form/Tests/Extension/Validator/Type/FormTypeValidatorExtensionTest.php

Lines changed: 62 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -175,21 +175,7 @@ public function testErrorPathOnCollections()
175175
->setMetadataFactory($metadataFactory)
176176
->getValidator();
177177

178-
$form = Forms::createFormFactoryBuilder()
179-
->addExtension(new ValidatorExtension($validator))
180-
->getFormFactory()
181-
->create(FormTypeTest::TESTED_TYPE, new Organization([]), [
182-
'data_class' => Organization::class,
183-
'by_reference' => false,
184-
])
185-
->add('authors', CollectionTypeTest::TESTED_TYPE, [
186-
'entry_type' => AuthorType::class,
187-
'allow_add' => true,
188-
'allow_delete' => true,
189-
])
190-
;
191-
192-
$form->submit([
178+
$submitData = [
193179
'authors' => [
194180
0 => [
195181
'firstName' => '', // Fires a Not Blank Error
@@ -205,7 +191,23 @@ public function testErrorPathOnCollections()
205191
'lastName' => 'lastName3',
206192
],
207193
],
208-
]);
194+
];
195+
196+
$form = Forms::createFormFactoryBuilder()
197+
->addExtension(new ValidatorExtension($validator))
198+
->getFormFactory()
199+
->create(FormTypeTest::TESTED_TYPE, new Organization([]), [
200+
'data_class' => Organization::class,
201+
'by_reference' => false,
202+
])
203+
->add('authors', CollectionTypeTest::TESTED_TYPE, [
204+
'entry_type' => AuthorType::class,
205+
'allow_add' => true,
206+
'allow_delete' => true,
207+
])
208+
;
209+
210+
$form->submit($submitData);
209211

210212
//Form behaves right (...?). It has index 0, 2 and 3 (1 has been removed)
211213
$this->assertTrue($form->get('authors')->has('0'));
@@ -225,11 +227,53 @@ public function testErrorPathOnCollections()
225227
];
226228

227229
$this->assertContains('data.authors[0].firstName', $errorPaths);
228-
$this->assertNotContains('data.authors[1].firstName', $errorPaths);
230+
$this->assertContains('data.authors[1].firstName', $errorPaths);
229231
$this->assertContains('data.authors[2].firstName', $errorPaths);
230-
$this->assertContains('data.authors[3].firstName', $errorPaths);
232+
$this->assertNotContains('data.authors[3].firstName', $errorPaths);
231233

232234
//In fact, root form should NOT contain errors but it does
235+
$this->assertCount(1, $form->getErrors(false));
236+
237+
//Let's to this again, but with new "reindex_on_submit" option set to true
238+
$form = Forms::createFormFactoryBuilder()
239+
->addExtension(new ValidatorExtension($validator))
240+
->getFormFactory()
241+
->create(FormTypeTest::TESTED_TYPE, new Organization([]), [
242+
'data_class' => Organization::class,
243+
'by_reference' => false,
244+
])
245+
->add('authors', CollectionTypeTest::TESTED_TYPE, [
246+
'entry_type' => AuthorType::class,
247+
'allow_add' => true,
248+
'allow_delete' => true,
249+
'reindex_on_submit' => true,
250+
])
251+
;
252+
253+
$form->submit($submitData);
254+
255+
//Errors paths are not messing up now, because we reindexed the form on submit
256+
$this->assertTrue($form->get('authors')->has('0'));
257+
$this->assertTrue($form->get('authors')->has('1'));
258+
$this->assertTrue($form->get('authors')->has('2'));
259+
$this->assertNotTrue($form->get('authors')->has('3'));
260+
261+
//Form does have 3 not blank errors
262+
$errors = $form->getErrors(true);
263+
$this->assertCount(3, $errors);
264+
265+
$errorPaths = [
266+
$errors[0]->getCause()->getPropertyPath(),
267+
$errors[1]->getCause()->getPropertyPath(),
268+
$errors[2]->getCause()->getPropertyPath(),
269+
];
270+
271+
$this->assertContains('data.authors[0].firstName', $errorPaths);
272+
$this->assertContains('data.authors[1].firstName', $errorPaths);
273+
$this->assertContains('data.authors[2].firstName', $errorPaths);
274+
$this->assertNotContains('data.authors[3].firstName', $errorPaths);
275+
276+
//Root form does NOT contain errors
233277
$this->assertCount(0, $form->getErrors(false));
234278
}
235279
}

0 commit comments

Comments
 (0)
0