Skip to content

Commit 6150f66

Browse files
committed
[Form] Make ButtonType handle form_attr option
1 parent 3b87465 commit 6150f66

File tree

4 files changed

+77
-13
lines changed

4 files changed

+77
-13
lines changed

Extension/Core/Type/BaseType.php

+12-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\Form\AbstractRendererEngine;
1515
use Symfony\Component\Form\AbstractType;
16+
use Symfony\Component\Form\Exception\LogicException;
1617
use Symfony\Component\Form\FormBuilderInterface;
1718
use Symfony\Component\Form\FormInterface;
1819
use Symfony\Component\Form\FormView;
@@ -70,8 +71,16 @@ public function buildView(FormView $view, FormInterface $form, array $options)
7071
if (!$labelFormat) {
7172
$labelFormat = $view->parent->vars['label_format'];
7273
}
74+
75+
$rootFormAttrOption = $form->getRoot()->getConfig()->getOption('form_attr');
76+
if ($options['form_attr'] || $rootFormAttrOption) {
77+
$options['attr']['form'] = \is_string($rootFormAttrOption) ? $rootFormAttrOption : $form->getRoot()->getName();
78+
if (empty($options['attr']['form'])) {
79+
throw new LogicException('"form_attr" option must be a string identifier on root form when it has no id.');
80+
}
81+
}
7382
} else {
74-
$id = $name;
83+
$id = \is_string($options['form_attr']) ? $options['form_attr'] : $name;
7584
$fullName = $name;
7685
$uniqueBlockPrefix = '_'.$blockName;
7786

@@ -137,13 +146,15 @@ public function configureOptions(OptionsResolver $resolver)
137146
'translation_domain' => null,
138147
'auto_initialize' => true,
139148
'priority' => 0,
149+
'form_attr' => false,
140150
]);
141151

142152
$resolver->setAllowedTypes('block_prefix', ['null', 'string']);
143153
$resolver->setAllowedTypes('attr', 'array');
144154
$resolver->setAllowedTypes('row_attr', 'array');
145155
$resolver->setAllowedTypes('label_html', 'bool');
146156
$resolver->setAllowedTypes('priority', 'int');
157+
$resolver->setAllowedTypes('form_attr', ['bool', 'string']);
147158

148159
$resolver->setInfo('priority', 'The form rendering priority (higher priorities will be rendered first)');
149160
}

Extension/Core/Type/FormType.php

-12
Original file line numberDiff line numberDiff line change
@@ -97,16 +97,6 @@ public function buildView(FormView $view, FormInterface $form, array $options)
9797
}
9898

9999
$helpTranslationParameters = array_merge($view->parent->vars['help_translation_parameters'], $helpTranslationParameters);
100-
101-
$rootFormAttrOption = $form->getRoot()->getConfig()->getOption('form_attr');
102-
if ($options['form_attr'] || $rootFormAttrOption) {
103-
$view->vars['attr']['form'] = \is_string($rootFormAttrOption) ? $rootFormAttrOption : $form->getRoot()->getName();
104-
if (empty($view->vars['attr']['form'])) {
105-
throw new LogicException('"form_attr" option must be a string identifier on root form when it has no id.');
106-
}
107-
}
108-
} elseif (\is_string($options['form_attr'])) {
109-
$view->vars['id'] = $options['form_attr'];
110100
}
111101

112102
$formConfig = $form->getConfig();
@@ -221,7 +211,6 @@ public function configureOptions(OptionsResolver $resolver)
221211
'is_empty_callback' => null,
222212
'getter' => null,
223213
'setter' => null,
224-
'form_attr' => false,
225214
]);
226215

227216
$resolver->setAllowedTypes('label_attr', 'array');
@@ -233,7 +222,6 @@ public function configureOptions(OptionsResolver $resolver)
233222
$resolver->setAllowedTypes('is_empty_callback', ['null', 'callable']);
234223
$resolver->setAllowedTypes('getter', ['null', 'callable']);
235224
$resolver->setAllowedTypes('setter', ['null', 'callable']);
236-
$resolver->setAllowedTypes('form_attr', ['bool', 'string']);
237225

238226
$resolver->setInfo('getter', 'A callable that accepts two arguments (the view data and the current form field) and must return a value.');
239227
$resolver->setInfo('setter', 'A callable that accepts three arguments (a reference to the view data, the submitted value and the current form field).');

Tests/Command/DebugCommandTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ public function provideCompletionSuggestions(): iterable
234234
'translation_domain',
235235
'auto_initialize',
236236
'priority',
237+
'form_attr',
237238
],
238239
];
239240

@@ -253,6 +254,7 @@ public function provideCompletionSuggestions(): iterable
253254
'translation_domain',
254255
'auto_initialize',
255256
'priority',
257+
'form_attr',
256258
],
257259
];
258260

Tests/Extension/Core/Type/ButtonTypeTest.php

+63
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
use Symfony\Component\Form\Button;
1515
use Symfony\Component\Form\Exception\BadMethodCallException;
16+
use Symfony\Component\Form\Exception\LogicException;
17+
use Symfony\Component\Form\Extension\Core\Type\FormType;
1618

1719
/**
1820
* @author Bernhard Schussek <[email protected]>
@@ -36,4 +38,65 @@ public function testSubmitNullUsesDefaultEmptyData($emptyData = 'empty', $expect
3638
$this->expectExceptionMessage('Buttons do not support empty data.');
3739
parent::testSubmitNullUsesDefaultEmptyData($emptyData, $expectedData);
3840
}
41+
42+
public function testFormAttrOnRoot()
43+
{
44+
$view = $this->factory
45+
->createNamedBuilder('parent', FormType::class, null, [
46+
'form_attr' => true,
47+
])
48+
->add('child1', $this->getTestedType())
49+
->add('child2', $this->getTestedType())
50+
->getForm()
51+
->createView();
52+
$this->assertArrayNotHasKey('form', $view->vars['attr']);
53+
$this->assertSame($view->vars['id'], $view['child1']->vars['attr']['form']);
54+
$this->assertSame($view->vars['id'], $view['child2']->vars['attr']['form']);
55+
}
56+
57+
public function testFormAttrOnChild()
58+
{
59+
$view = $this->factory
60+
->createNamedBuilder('parent')
61+
->add('child1', $this->getTestedType(), [
62+
'form_attr' => true,
63+
])
64+
->add('child2', $this->getTestedType())
65+
->getForm()
66+
->createView();
67+
$this->assertArrayNotHasKey('form', $view->vars['attr']);
68+
$this->assertSame($view->vars['id'], $view['child1']->vars['attr']['form']);
69+
$this->assertArrayNotHasKey('form', $view['child2']->vars['attr']);
70+
}
71+
72+
public function testFormAttrAsBoolWithNoId()
73+
{
74+
$this->expectException(LogicException::class);
75+
$this->expectErrorMessage('form_attr');
76+
$this->factory
77+
->createNamedBuilder('', FormType::class, null, [
78+
'form_attr' => true,
79+
])
80+
->add('child1', $this->getTestedType())
81+
->add('child2', $this->getTestedType())
82+
->getForm()
83+
->createView();
84+
}
85+
86+
public function testFormAttrAsStringWithNoId()
87+
{
88+
$stringId = 'custom-identifier';
89+
$view = $this->factory
90+
->createNamedBuilder('', FormType::class, null, [
91+
'form_attr' => $stringId,
92+
])
93+
->add('child1', $this->getTestedType())
94+
->add('child2', $this->getTestedType())
95+
->getForm()
96+
->createView();
97+
$this->assertArrayNotHasKey('form', $view->vars['attr']);
98+
$this->assertSame($stringId, $view->vars['id']);
99+
$this->assertSame($view->vars['id'], $view['child1']->vars['attr']['form']);
100+
$this->assertSame($view->vars['id'], $view['child2']->vars['attr']['form']);
101+
}
39102
}

0 commit comments

Comments
 (0)