Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 63087e5

Browse filesBrowse files
committed
bug symfony#20762 [Form] Fix FormDataCollector (nicolas-grekas, Padam87)
This PR was merged into the 3.2 branch. Discussion ---------- [Form] Fix FormDataCollector | Q | A | ------------- | --- | Branch? | 3.2 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | symfony#20698 | License | MIT | Doc PR | - Alternative to symfony#20707 Commits ------- 50400c4 [Form] Add failing test for data collector bug 164a20c [Form] Fix FormDataCollector
2 parents 456e68b + 50400c4 commit 63087e5
Copy full SHA for 63087e5

File tree

2 files changed

+123
-19
lines changed
Filter options

2 files changed

+123
-19
lines changed

‎src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php
+15-19Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -209,19 +209,15 @@ public function collectViewVariables(FormView $view)
209209
*/
210210
public function buildPreliminaryFormTree(FormInterface $form)
211211
{
212-
$this->data['forms'][$form->getName()] = array();
213-
214-
$this->recursiveBuildPreliminaryFormTree($form, $this->data['forms'][$form->getName()], $this->data['forms_by_hash']);
212+
$this->data['forms'][$form->getName()] = &$this->recursiveBuildPreliminaryFormTree($form, $this->data['forms_by_hash']);
215213
}
216214

217215
/**
218216
* {@inheritdoc}
219217
*/
220218
public function buildFinalFormTree(FormInterface $form, FormView $view)
221219
{
222-
$this->data['forms'][$form->getName()] = array();
223-
224-
$this->recursiveBuildFinalFormTree($form, $view, $this->data['forms'][$form->getName()], $this->data['forms_by_hash']);
220+
$this->data['forms'][$form->getName()] = &$this->recursiveBuildFinalFormTree($form, $view, $this->data['forms_by_hash']);
225221
}
226222

227223
/**
@@ -258,7 +254,7 @@ public function serialize()
258254
case 'resolved_options':
259255
case 'default_data':
260256
case 'submitted_data':
261-
if ($v) {
257+
if ($v && is_array($v)) {
262258
$form[$k] = array_map($cloneVar, $v);
263259
}
264260
break;
@@ -354,26 +350,25 @@ protected function cloneVar($var, $isClass = false)
354350
return $cache = $this->cloner->cloneVar($var);
355351
}
356352

357-
private function recursiveBuildPreliminaryFormTree(FormInterface $form, &$output, array &$outputByHash)
353+
private function &recursiveBuildPreliminaryFormTree(FormInterface $form, array &$outputByHash)
358354
{
359355
$hash = spl_object_hash($form);
360356

357+
$output = &$outputByHash[$hash];
361358
$output = isset($this->dataByForm[$hash])
362359
? $this->dataByForm[$hash]
363360
: array();
364361

365-
$outputByHash[$hash] = &$output;
366-
367362
$output['children'] = array();
368363

369364
foreach ($form as $name => $child) {
370-
$output['children'][$name] = array();
371-
372-
$this->recursiveBuildPreliminaryFormTree($child, $output['children'][$name], $outputByHash);
365+
$output['children'][$name] = &$this->recursiveBuildPreliminaryFormTree($child, $outputByHash);
373366
}
367+
368+
return $output;
374369
}
375370

376-
private function recursiveBuildFinalFormTree(FormInterface $form = null, FormView $view, &$output, array &$outputByHash)
371+
private function &recursiveBuildFinalFormTree(FormInterface $form = null, FormView $view, array &$outputByHash)
377372
{
378373
$viewHash = spl_object_hash($view);
379374
$formHash = null;
@@ -386,6 +381,9 @@ private function recursiveBuildFinalFormTree(FormInterface $form = null, FormVie
386381
// corresponding FormInterface instance for its view in a different way
387382
$formHash = $this->formsByView[$viewHash];
388383
}
384+
if (null !== $formHash) {
385+
$output = &$outputByHash[$formHash];
386+
}
389387

390388
$output = isset($this->dataByView[$viewHash])
391389
? $this->dataByView[$viewHash]
@@ -398,8 +396,6 @@ private function recursiveBuildFinalFormTree(FormInterface $form = null, FormVie
398396
? $this->dataByForm[$formHash]
399397
: array()
400398
);
401-
402-
$outputByHash[$formHash] = &$output;
403399
}
404400

405401
$output['children'] = array();
@@ -411,9 +407,9 @@ private function recursiveBuildFinalFormTree(FormInterface $form = null, FormVie
411407
? $form->get($name)
412408
: null;
413409

414-
$output['children'][$name] = array();
415-
416-
$this->recursiveBuildFinalFormTree($childForm, $childView, $output['children'][$name], $outputByHash);
410+
$output['children'][$name] = &$this->recursiveBuildFinalFormTree($childForm, $childView, $outputByHash);
417411
}
412+
413+
return $output;
418414
}
419415
}

‎src/Symfony/Component/Form/Tests/Extension/DataCollector/FormDataCollectorTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Tests/Extension/DataCollector/FormDataCollectorTest.php
+108Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,114 @@ public function testBuildFinalFormTree()
342342
), $this->dataCollector->getData());
343343
}
344344

345+
public function testSerializeWithFormAddedMultipleTimes()
346+
{
347+
$form1 = $this->createForm('form1');
348+
$form2 = $this->createForm('form2');
349+
$child1 = $this->createForm('child1');
350+
351+
$form1View = new FormView();
352+
$form2View = new FormView();
353+
$child1View = new FormView();
354+
$child1View->vars['is_selected'] = function ($choice, array $values) {
355+
return in_array($choice, $values, true);
356+
};
357+
358+
$form1->add($child1);
359+
$form2->add($child1);
360+
361+
$form1View->children['child1'] = $child1View;
362+
$form2View->children['child1'] = $child1View;
363+
364+
$this->dataExtractor->expects($this->at(0))
365+
->method('extractConfiguration')
366+
->with($form1)
367+
->will($this->returnValue(array('config' => 'foo')));
368+
$this->dataExtractor->expects($this->at(1))
369+
->method('extractConfiguration')
370+
->with($child1)
371+
->will($this->returnValue(array('config' => 'bar')));
372+
373+
$this->dataExtractor->expects($this->at(2))
374+
->method('extractDefaultData')
375+
->with($form1)
376+
->will($this->returnValue(array('default_data' => 'foo')));
377+
$this->dataExtractor->expects($this->at(3))
378+
->method('extractDefaultData')
379+
->with($child1)
380+
->will($this->returnValue(array('default_data' => 'bar')));
381+
382+
$this->dataExtractor->expects($this->at(4))
383+
->method('extractSubmittedData')
384+
->with($form1)
385+
->will($this->returnValue(array('submitted_data' => 'foo')));
386+
$this->dataExtractor->expects($this->at(5))
387+
->method('extractSubmittedData')
388+
->with($child1)
389+
->will($this->returnValue(array('submitted_data' => 'bar')));
390+
391+
$this->dataExtractor->expects($this->at(6))
392+
->method('extractViewVariables')
393+
->with($form1View)
394+
->will($this->returnValue(array('view_vars' => 'foo')));
395+
396+
$this->dataExtractor->expects($this->at(7))
397+
->method('extractViewVariables')
398+
->with($child1View)
399+
->will($this->returnValue(array('view_vars' => $child1View->vars)));
400+
401+
$this->dataExtractor->expects($this->at(8))
402+
->method('extractConfiguration')
403+
->with($form2)
404+
->will($this->returnValue(array('config' => 'foo')));
405+
$this->dataExtractor->expects($this->at(9))
406+
->method('extractConfiguration')
407+
->with($child1)
408+
->will($this->returnValue(array('config' => 'bar')));
409+
410+
$this->dataExtractor->expects($this->at(10))
411+
->method('extractDefaultData')
412+
->with($form2)
413+
->will($this->returnValue(array('default_data' => 'foo')));
414+
$this->dataExtractor->expects($this->at(11))
415+
->method('extractDefaultData')
416+
->with($child1)
417+
->will($this->returnValue(array('default_data' => 'bar')));
418+
419+
$this->dataExtractor->expects($this->at(12))
420+
->method('extractSubmittedData')
421+
->with($form2)
422+
->will($this->returnValue(array('submitted_data' => 'foo')));
423+
$this->dataExtractor->expects($this->at(13))
424+
->method('extractSubmittedData')
425+
->with($child1)
426+
->will($this->returnValue(array('submitted_data' => 'bar')));
427+
428+
$this->dataExtractor->expects($this->at(14))
429+
->method('extractViewVariables')
430+
->with($form2View)
431+
->will($this->returnValue(array('view_vars' => 'foo')));
432+
433+
$this->dataExtractor->expects($this->at(15))
434+
->method('extractViewVariables')
435+
->with($child1View)
436+
->will($this->returnValue(array('view_vars' => $child1View->vars)));
437+
438+
$this->dataCollector->collectConfiguration($form1);
439+
$this->dataCollector->collectDefaultData($form1);
440+
$this->dataCollector->collectSubmittedData($form1);
441+
$this->dataCollector->collectViewVariables($form1View);
442+
$this->dataCollector->buildFinalFormTree($form1, $form1View);
443+
444+
$this->dataCollector->collectConfiguration($form2);
445+
$this->dataCollector->collectDefaultData($form2);
446+
$this->dataCollector->collectSubmittedData($form2);
447+
$this->dataCollector->collectViewVariables($form2View);
448+
$this->dataCollector->buildFinalFormTree($form2, $form2View);
449+
450+
$this->dataCollector->serialize();
451+
}
452+
345453
public function testFinalFormReliesOnFormViewStructure()
346454
{
347455
$this->form->add($child1 = $this->createForm('first'));

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.