Skip to content

Commit 2bf4d6c

Browse files
committed
[Form] Fixed FormFactory not to set "data" option if not explicitely given
1 parent 7149d26 commit 2bf4d6c

File tree

4 files changed

+31
-12
lines changed

4 files changed

+31
-12
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ public function setDefaultOptions(OptionsResolverInterface $resolver)
149149
{
150150
// Derive "data_class" option from passed "data" object
151151
$dataClass = function (Options $options) {
152-
return is_object($options['data']) ? get_class($options['data']) : null;
152+
return isset($options['data']) && is_object($options['data']) ? get_class($options['data']) : null;
153153
};
154154

155155
// Derive "empty_data" closure from "data_class" option

src/Symfony/Component/Form/FormFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ public function createBuilder($type, $data = null, array $options = array(), For
145145
*/
146146
public function createNamedBuilder($name, $type, $data = null, array $options = array(), FormBuilderInterface $parent = null)
147147
{
148-
if (!array_key_exists('data', $options)) {
148+
if (null !== $data && !array_key_exists('data', $options)) {
149149
$options['data'] = $data;
150150
}
151151

src/Symfony/Component/Form/Tests/Fixtures/FooType.php

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,19 @@
1616
use Symfony\Component\Form\FormBuilderInterface;
1717
use Symfony\Component\Form\FormFactoryInterface;
1818
use Symfony\Component\EventDispatcher\EventDispatcher;
19+
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
1920

2021
class FooType extends AbstractType
2122
{
2223
public function buildForm(FormBuilderInterface $builder, array $options)
2324
{
2425
$builder->setAttribute('foo', 'x');
25-
$builder->setAttribute('data_option', $options['data']);
26+
$builder->setAttribute('data_option', isset($options['data']) ? $options['data'] : null);
27+
// Important: array_key_exists(), not isset()
28+
// -> The "data" option is optional in FormType
29+
// If it is given, the form's data will be locked to the value of the option
30+
// Thus "data" must not be set in the array unless explicitely specified
31+
$builder->setAttribute('data_option_set', array_key_exists('data', $options));
2632
}
2733

2834
public function getName()
@@ -35,21 +41,21 @@ public function createBuilder($name, FormFactoryInterface $factory, array $optio
3541
return new FormBuilder($name, null, new EventDispatcher(), $factory);
3642
}
3743

38-
public function getDefaultOptions()
44+
public function setDefaultOptions(OptionsResolverInterface $resolver)
3945
{
40-
return array(
41-
'data' => null,
46+
$resolver->setDefaults(array(
4247
'required' => false,
4348
'max_length' => null,
4449
'a_or_b' => 'a',
45-
);
46-
}
50+
));
4751

48-
public function getAllowedOptionValues()
49-
{
50-
return array(
52+
$resolver->setOptional(array(
53+
'data',
54+
));
55+
56+
$resolver->setAllowedValues(array(
5157
'a_or_b' => array('a', 'b'),
52-
);
58+
));
5359
}
5460

5561
public function getParent()

src/Symfony/Component/Form/Tests/FormFactoryTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,21 @@ public function testCreateNamedBuilderFillsDataOption()
150150
$builder = $this->factory->createNamedBuilder('bar', 'foo', 'xyz');
151151

152152
// see FooType::buildForm()
153+
$this->assertTrue($builder->getAttribute('data_option_set'));
153154
$this->assertEquals('xyz', $builder->getAttribute('data_option'));
154155
}
155156

157+
public function testCreateNamedBuilderDoesNotSetDataOptionIfNull()
158+
{
159+
$type = new FooType();
160+
$this->extension1->addType($type);
161+
162+
$builder = $this->factory->createNamedBuilder('bar', 'foo', null);
163+
164+
// see FooType::buildForm()
165+
$this->assertFalse($builder->getAttribute('data_option_set'));
166+
}
167+
156168
public function testCreateNamedBuilderDoesNotOverrideExistingDataOption()
157169
{
158170
$type = new FooType();
@@ -163,6 +175,7 @@ public function testCreateNamedBuilderDoesNotOverrideExistingDataOption()
163175
));
164176

165177
// see FooType::buildForm()
178+
$this->assertTrue($builder->getAttribute('data_option_set'));
166179
$this->assertEquals('abc', $builder->getAttribute('data_option'));
167180
}
168181

0 commit comments

Comments
 (0)