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 9bf6e8b

Browse filesBrowse files
committed
[Form] Compound forms now always need a data mapper. Otherwise an exception is thrown.
1 parent 5758119 commit 9bf6e8b
Copy full SHA for 9bf6e8b

File tree

12 files changed

+1578
-1399
lines changed
Filter options

12 files changed

+1578
-1399
lines changed

‎src/Symfony/Component/Form/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,4 @@ CHANGELOG
139139
* deprecated `getChildren` in Form and FormBuilder in favor of `all`
140140
* deprecated `hasChildren` in Form and FormBuilder in favor of `count`
141141
* FormBuilder now implements \IteratorAggregate
142+
* [BC BREAK] compound forms now always need a data mapper

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Extension/Core/Type/FormType.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public function buildForm(FormBuilderInterface $builder, array $options)
4444
->setVirtual($options['virtual'])
4545
->setCompound($options['compound'])
4646
->setData($options['data'])
47-
->setDataMapper(new PropertyPathMapper())
47+
->setDataMapper($options['compound'] ? new PropertyPathMapper() : null)
4848
;
4949

5050
if ($options['trim']) {

‎src/Symfony/Component/Form/Form.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Form.php
+16-13Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,13 @@ public function __construct(FormConfigInterface $config)
130130
$config = new UnmodifiableFormConfig($config);
131131
}
132132

133+
// Compound forms always need a data mapper, otherwise calls to
134+
// `setData` and `add` will not lead to the correct population of
135+
// the child forms.
136+
if ($config->getCompound() && !$config->getDataMapper()) {
137+
throw new FormException('Compound forms need a data mapper');
138+
}
139+
133140
$this->config = $config;
134141

135142
$this->setData($config->getData());
@@ -378,7 +385,7 @@ public function setData($modelData)
378385
$this->viewData = $viewData;
379386
$this->synchronized = true;
380387

381-
if ($this->config->getCompound() && $this->config->getDataMapper()) {
388+
if ($this->config->getCompound()) {
382389
// Update child forms from the data
383390
$this->config->getDataMapper()->mapDataToForms($viewData, $this->children);
384391
}
@@ -477,6 +484,9 @@ public function bind($submittedData)
477484
$this->config->getEventDispatcher()->dispatch(FormEvents::BIND_CLIENT_DATA, $event);
478485
$submittedData = $event->getData();
479486

487+
// By default, the submitted data is also the data in view format
488+
$viewData = $submittedData;
489+
480490
// Check whether the form is compound.
481491
// This check is preferrable over checking the number of children,
482492
// since forms without children may also be compound.
@@ -503,15 +513,10 @@ public function bind($submittedData)
503513
$extraData[$name] = $value;
504514
}
505515
}
506-
}
507516

508-
// By default, the submitted data is also the data in view format
509-
$viewData = $submittedData;
510-
511-
// If the form is compound, the default data in view format
512-
// is reused. The data of the children is merged into this
513-
// default data using the data mapper.
514-
if ($this->config->getCompound() && $this->config->getDataMapper()) {
517+
// If the form is compound, the default data in view format
518+
// is reused. The data of the children is merged into this
519+
// default data using the data mapper.
515520
$viewData = $this->getViewData();
516521
}
517522

@@ -527,7 +532,7 @@ public function bind($submittedData)
527532
}
528533

529534
// Merge form data from children into existing view data
530-
if ($this->config->getCompound() && $this->config->getDataMapper() && null !== $viewData) {
535+
if ($this->config->getCompound() && null !== $viewData) {
531536
$this->config->getDataMapper()->mapFormsToData($this->children, $viewData);
532537
}
533538

@@ -853,9 +858,7 @@ public function add(FormInterface $child)
853858

854859
$child->setParent($this);
855860

856-
if ($this->config->getDataMapper()) {
857-
$this->config->getDataMapper()->mapDataToForms($this->getViewData(), array($child));
858-
}
861+
$this->config->getDataMapper()->mapDataToForms($this->getViewData(), array($child));
859862

860863
return $this;
861864
}

‎src/Symfony/Component/Form/FormConfig.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/FormConfig.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class FormConfig implements FormConfigEditorInterface
5656
/**
5757
* @var Boolean
5858
*/
59-
private $compound = true;
59+
private $compound = false;
6060

6161
/**
6262
* @var array
+141Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Form\Tests;
13+
14+
use Symfony\Component\Form\FormError;
15+
use Symfony\Component\Form\FormBuilder;
16+
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
17+
18+
abstract class AbstractFormTest extends \PHPUnit_Framework_TestCase
19+
{
20+
/**
21+
* @var EventDispatcherInterface
22+
*/
23+
protected $dispatcher;
24+
25+
/**
26+
* @var \Symfony\Component\Form\FormFactoryInterface
27+
*/
28+
protected $factory;
29+
30+
/**
31+
* @var \Symfony\Component\Form\FormInterface
32+
*/
33+
protected $form;
34+
35+
protected function setUp()
36+
{
37+
if (!class_exists('Symfony\Component\EventDispatcher\EventDispatcher')) {
38+
$this->markTestSkipped('The "EventDispatcher" component is not available');
39+
}
40+
41+
$this->dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
42+
$this->factory = $this->getMock('Symfony\Component\Form\FormFactoryInterface');
43+
$this->form = $this->createForm();
44+
}
45+
46+
protected function tearDown()
47+
{
48+
$this->dispatcher = null;
49+
$this->factory = null;
50+
$this->form = null;
51+
}
52+
53+
/**
54+
* @return \Symfony\Component\Form\FormInterface
55+
*/
56+
abstract protected function createForm();
57+
58+
/**
59+
* @param string $name
60+
* @param EventDispatcherInterface $dispatcher
61+
* @param string $dataClass
62+
*
63+
* @return FormBuilder
64+
*/
65+
protected function getBuilder($name = 'name', EventDispatcherInterface $dispatcher = null, $dataClass = null)
66+
{
67+
return new FormBuilder($name, $dataClass, $dispatcher ?: $this->dispatcher, $this->factory);
68+
}
69+
70+
/**
71+
* @param string $name
72+
*
73+
* @return \PHPUnit_Framework_MockObject_MockObject
74+
*/
75+
protected function getMockForm($name = 'name')
76+
{
77+
$form = $this->getMock('Symfony\Component\Form\Tests\FormInterface');
78+
79+
$form->expects($this->any())
80+
->method('getName')
81+
->will($this->returnValue($name));
82+
83+
return $form;
84+
}
85+
86+
/**
87+
* @param string $name
88+
*
89+
* @return \PHPUnit_Framework_MockObject_MockObject
90+
*/
91+
protected function getValidForm($name)
92+
{
93+
$form = $this->getMockForm($name);
94+
95+
$form->expects($this->any())
96+
->method('isValid')
97+
->will($this->returnValue(true));
98+
99+
return $form;
100+
}
101+
102+
/**
103+
* @param string $name
104+
*
105+
* @return \PHPUnit_Framework_MockObject_MockObject
106+
*/
107+
protected function getInvalidForm($name)
108+
{
109+
$form = $this->getMockForm($name);
110+
111+
$form->expects($this->any())
112+
->method('isValid')
113+
->will($this->returnValue(false));
114+
115+
return $form;
116+
}
117+
118+
/**
119+
* @return \PHPUnit_Framework_MockObject_MockObject
120+
*/
121+
protected function getDataMapper()
122+
{
123+
return $this->getMock('Symfony\Component\Form\DataMapperInterface');
124+
}
125+
126+
/**
127+
* @return \PHPUnit_Framework_MockObject_MockObject
128+
*/
129+
protected function getDataTransformer()
130+
{
131+
return $this->getMock('Symfony\Component\Form\DataTransformerInterface');
132+
}
133+
134+
/**
135+
* @return \PHPUnit_Framework_MockObject_MockObject
136+
*/
137+
protected function getFormValidator()
138+
{
139+
return $this->getMock('Symfony\Component\Form\FormValidatorInterface');
140+
}
141+
}

0 commit comments

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