8000 [Form] Adapted Form to create a deterministic property path by default · symfony/symfony@860dd1f · GitHub
[go: up one dir, main page]

Skip to content

Commit 860dd1f

Browse files
committed
[Form] Adapted Form to create a deterministic property path by default
1 parent 03f5058 commit 860dd1f

23 files changed

+354
-155
lines changed

src/Symfony/Component/Form/Extension/Core/DataMapper/PropertyPathMapper.php

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,6 @@
1818

1919
class PropertyPathMapper implements DataMapperInterface
2020
{
21-
/**
22-
* Stores the class that the data of this form must be instances of.
23-
*
24-
* @var string
25-
*/
26-
private $dataClass;
27-
28-
public function __construct($dataClass = null)
29-
{
30-
$this->dataClass = $dataClass;
31-
}
32-
3321
/**
3422
* {@inheritdoc}
3523
*/
@@ -40,10 +28,6 @@ public function mapDataToForms($data, array $forms)
4028
}
4129

4230
if (!empty($data)) {
43-
if (null !== $this->dataClass && !$data instanceof $this->dataClass) {
44-
throw new UnexpectedTypeException($data, $this->dataClass);
45-
}
46-
4731
$iterator = new VirtualFormAwareIterator($forms);
4832
$iterator = new \RecursiveIteratorIterator($iterator);
4933

@@ -59,7 +43,7 @@ public function mapDataToForms($data, array $forms)
5943
public function mapDataToForm($data, FormInterface $form)
6044
{
6145
if (!empty($data)) {
62-
$propertyPath = $form->getAttribute('property_path');
46+
$propertyPath = $form->getPropertyPath();
6347

6448
if (null !== $propertyPath) {
6549
$propertyData = $propertyPath->getValue($data);
@@ -91,7 +75,7 @@ public function mapFormsToData(array $forms, &$data)
9175
*/
9276
public function mapFormToData(FormInterface $form, &$data)
9377
{
94-
$propertyPath = $form->getAttribute('property_path');
78+
$propertyPath = $form->getPropertyPath();
9579

9680
if (null !== $propertyPath && $form->isSynchronized() && !$form->isDisabled()) {
9781
// If the data is identical to the value in $data, we are

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

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,6 @@ class FormType extends AbstractType
3131
*/
3232
public function buildForm(FormBuilder $builder, array $options)
3333
{
34-
if (null === $options['property_path']) {
35-
$options['property_path'] = $builder->getName();
36-
}
37-
38-
if (false === $options['property_path'] || '' === $options['property_path']) {
39-
$options['property_path'] = null;
40-
} else {
41-
$options['property_path'] = new PropertyPath($options['property_path']);
42-
}
43-
4434
if (!is_array($options['attr'])) {
4535
throw new FormException('The "attr" option must be an "array".');
4636
}
@@ -54,9 +44,9 @@ public function buildForm(FormBuilder $builder, array $options)
5444
->setDisabled($options['disabled'])
5545
->setErrorBubbling($options['error_bubbling'])
5646
->setEmptyData($options['empty_data'])
47+
->setPropertyPath($options['property_path'])
5748
->setAttribute('read_only', $options['read_only'])
5849
->setAttribute('by_reference', $options['by_reference'])
59-
->setAttribute('property_path', $options['property_path'])
6050
->setAttribute('error_mapping', $options['error_mapping'])
6151
->setAttribute('max_length', $options['max_length'])
6252
->setAttribute('pattern', $options['pattern'])
@@ -69,7 +59,7 @@ public function buildForm(FormBuilder $builder, array $options)
6959
->setAttribute('virtual', $options['virtual'])
7060
->setAttribute('single_control', $options['single_control'])
7161
->setData($options['data'])
72-
->setDataMapper(new PropertyPathMapper($options['data_class']))
62+
->setDataMapper(new PropertyPathMapper())
7363
->addEventSubscriber(new ValidationListener())
7464
;
7565

@@ -112,7 +102,7 @@ public function buildView(FormView $view, FormInterface $form)
112102
}
113103

114104
$types = array();
115-
foreach ($form->getTypes() as $type) {
105+
foreach ($form->getConfig()->getTypes() as $type) {
116106
$types[] = $type->getName();
117107
}
118108

@@ -229,7 +219,7 @@ public function getDefaultOptions()
229219
*/
230220
public function createBuilder($name, FormFactoryInterface $factory, array $options)
231221
{
232-
return new FormBuilder($name, $factory, new EventDispatcher(), $options['data_class']);
222+
return new FormBuilder($name, $options['data_class'], new EventDispatcher(), $factory);
233223
}
234224

235225
/**

src/Symfony/Component/Form/Form.php

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Symfony\Component\Form\Exception\AlreadyBoundException;
1818
use Symfony\Component\Form\Exception\UnexpectedTypeException;
1919
use Symfony\Component\Form\Exception\TransformationFailedException;
20+
use Symfony\Component\Form\Util\PropertyPath;
2021
use Symfony\Component\HttpFoundation\Request;
2122
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
2223

@@ -162,10 +163,33 @@ public function getName()
162163
return $this->config->getName();
163164
}
164165

166+
/**
167+
* {@inheritdoc}
168+
*/
169+
public function getPropertyPath()
170+
{
171+
if (!$this->hasParent() || null !== $this->config->getPropertyPath()) {
172+
return $this->config->getPropertyPath();
173+
}
174+
175+
if (null === $this->getName() || '' === $this->getName()) {
176+
return null;
177+
}
178+
179+
if (null === $this->getParent()->getConfig()->getDataClass()) {
180+
return new PropertyPath('[' . $this->getName() . ']');
181+
}
182+
183+
return new PropertyPath($this->getName());
184+
}
185+
165186
/**
166187
* Returns the types used by this form.
167188
*
168189
* @return array An array of FormTypeInterface
190+
*
191+
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
192+
* {@link getConfig()} and {@link FormConfigInterface::getTypes()} instead.
169193
*/
170194
public function getTypes()
171195
{
@@ -261,9 +285,9 @@ public function isRoot()
261285
/**
262286
* Returns whether the form has an attribute with the given name.
263287
*
264-
* @param string $name The name of the attribute
288+
* @param string $name The name of the attribute.
265289
*
266-
* @return Boolean
290+
* @return Boolean Whether the attribute exists.
267291
*/
268292
public function hasAttribute($name)
269293
{
@@ -273,7 +297,9 @@ public function hasAttribute($name)
273297
/**
274298
* Returns the value of the attributes with the given name.
275299
*
276-
* @param string $name The name of the attribute
300+
* @param string $name The name of the attribute
301+
*
302+
* @return mixed The attribute value.
277303
*/
278304
public function getAttribute($name)
279305
{
@@ -310,6 +336,25 @@ public function setData($appData)
310336
$normData = $this->appToNorm($appData);
311337
$clientData = $this->normToClient($normData);
312338

339+
// Validate if client data matches data class (unless empty)
340+
if (!empty($clientData)) {
341+
// TESTME
342+
$dataClass = $this->config->getDataClass();
343+
344+
if (null === $dataClass && is_object($clientData)) {
345+
// TODO clarify error message: should not be transformed to object if data class is null
346+
// possible solutions: set data class or change client transformers
347+
throw new UnexpectedTypeException($clientData, 'scalar or array');
348+
}
349+
350+
// TESTME
351+
if (null !== $dataClass && !$clientData instanceof $dataClass) {
352+
// TODO clarify error message: should be transformed to object if data class is set
353+
// possible solutions: change data class or client transformers
354+
throw new UnexpectedTypeException($clientData, $dataClass);
355+
}
356+
}
357+
313358
$this->appData = $appData;
314359
$this->normData = $normData;
315360
$this->clientData = $clientData;
@@ -568,6 +613,9 @@ public function addError(FormError $error)
568613
* Returns whether errors bubble up to the parent.
569614
*
570615
* @return Boolean
616+
*
617+
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
618+
* {@link getConfig()} and {@link FormConfigInterface::getErrorBubbling()} instead.
571619
*/
572620
public function getErrorBubbling()
573621
{
@@ -693,6 +741,9 @@ public function getErrorsAsString($level = 0)
693741
* Returns the DataTransformers.
694742
*
695743
* @return array An array of DataTransformerInterface
744+
*
745+
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
746+
* {@link getConfig()} and {@link FormConfigInterface::getNormTransformers()} instead.
696747
*/
697748
public function getNormTransformers()
698749
{
@@ -703,6 +754,9 @@ public function getNormTransformers()
703754
* Returns the DataTransformers.
704755
*
705756
* @return array An array of DataTransformerInterface
757+
*
758+
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
759+
* {@link getConfig()} and {@link FormConfigInterface::getClientTransformers()} instead.
706760
*/
707761
public function getClientTransformers()
708762
{

src/Symfony/Component/Form/FormBuilder.php

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,6 @@ class FormBuilder extends FormConfig
3131
*/
3232
private $factory;
3333

34-
/**
35-
* @var string
36-
*/
37-
private $dataClass;
38-
3934
/**
4035
* The children of the form builder.
4136
*
@@ -59,19 +54,18 @@ class FormBuilder extends FormConfig
5954
private $parent;
6055

6156
/**
62-
* Constructor.
57+
* Creates a new form builder.
6358
*
6459
* @param string $name
65-
* @param FormFactoryInterface $factory
66-
* @param EventDispatcherInterface $dispatcher
6760
* @param string $dataClass
61+
* @param EventDispatcherInterface $dispatcher
62+
* @param FormFactoryInterface $factory
6863
*/
69-
public function __construct($name, FormFactoryInterface $factory, EventDispatcherInterface $dispatcher, $dataClass = null)
64+
public function __construct($name, $dataClass, EventDispatcherInterface $dispatcher, FormFactoryInterface $factory)
7065
{
71-
parent::__construct($name, $dispatcher);
66+
parent::__construct($name, $dataClass, $dispatcher);
7267

7368
$this->factory = $factory;
74-
$this->dataClass = $dataClass;
7569
}
7670

7771
/**
@@ -140,15 +134,15 @@ public function add($child, $type = null, array $options = array())
140134
*/
141135
public function create($name, $type = null, array $options = array())
142136
{
143-
if (null === $type && !$this->dataClass) {
137+
if (null === $type && null === $this->getDataClass()) {
144138
$type = 'text';
145139
}
146140

147141
if (null !== $type) {
148142
return $this->getFormFactory()->createNamedBuilder($type, $name, null, $options, $this);
149143
}
150144

151-
return $this->getFormFactory()->createBuilderForProperty($this->dataClass, $name, null, $options, $this);
145+
return $this->getFormFactory()->createBuilderForProperty($this->getDataClass(), $name, null, $options, $this);
152146
}
153147

154148
/**

0 commit comments

Comments
 (0)
0