Skip to content

Commit 96b9b6f

Browse files
Merge branch '6.0' into 6.1
* 6.0: [Console] Correctly overwrite progressbars with different line count per step [DependencyInjection] Fix deduplicating service instances in circular graphs [Form] Make `ButtonType` handle `form_attr` option [PhpUnitBridge] Use verbose deprecation output for quiet types only when it reaches the threshold [CssSelector] Fix escape patterns
2 parents 9b81fcb + 8e16d40 commit 96b9b6f

File tree

4 files changed

+77
-13
lines changed

4 files changed

+77
-13
lines changed

Extension/Core/Type/BaseType.php

Lines changed: 12 additions & 1 deletion
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

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -90,16 +90,6 @@ public function buildView(FormView $view, FormInterface $form, array $options)
9090
}
9191

9292
$helpTranslationParameters = array_merge($view->parent->vars['help_translation_parameters'], $helpTranslationParameters);
93-
94-
$rootFormAttrOption = $form->getRoot()->getConfig()->getOption('form_attr');
95-
if ($options['form_attr'] || $rootFormAttrOption) {
96-
$view->vars['attr']['form'] = \is_string($rootFormAttrOption) ? $rootFormAttrOption : $form->getRoot()->getName();
97-
if (empty($view->vars['attr']['form'])) {
98-
throw new LogicException('"form_attr" option must be a string identifier on root form when it has no id.');
99-
}
100-
}
101-
} elseif (\is_string($options['form_attr'])) {
102-
$view->vars['id'] = $options['form_attr'];
10393
}
10494

10595
$formConfig = $form->getConfig();
@@ -214,7 +204,6 @@ public function configureOptions(OptionsResolver $resolver)
214204
'is_empty_callback' => null,
215205
'getter' => null,
216206
'setter' => null,
217-
'form_attr' => false,
218207
]);
219208

220209
$resolver->setAllowedTypes('label_attr', 'array');
@@ -226,7 +215,6 @@ public function configureOptions(OptionsResolver $resolver)
226215
$resolver->setAllowedTypes('is_empty_callback', ['null', 'callable']);
227216
$resolver->setAllowedTypes('getter', ['null', 'callable']);
228217
$resolver->setAllowedTypes('setter', ['null', 'callable']);
229-
$resolver->setAllowedTypes('form_attr', ['bool', 'string']);
230218

231219
$resolver->setInfo('getter', 'A callable that accepts two arguments (the view data and the current form field) and must return a value.');
232220
$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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ public function provideCompletionSuggestions(): iterable
225225
'translation_domain',
226226
'auto_initialize',
227227
'priority',
228+
'form_attr',
228229
],
229230
];
230231

@@ -244,6 +245,7 @@ public function provideCompletionSuggestions(): iterable
244245
'translation_domain',
245246
'auto_initialize',
246247
'priority',
248+
'form_attr',
247249
],
248250
];
249251

Tests/Extension/Core/Type/ButtonTypeTest.php

Lines changed: 63 additions & 0 deletions
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)