Skip to content

Commit fac98f6

Browse files
Merge branch '6.1' into 6.2
* 6.1: [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 6efa6f8 + 96b9b6f commit fac98f6

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;
@@ -62,8 +63,16 @@ public function buildView(FormView $view, FormInterface $form, array $options)
6263
if (!$labelFormat) {
6364
$labelFormat = $view->parent->vars['label_format'];
6465
}
66+
67+
$rootFormAttrOption = $form->getRoot()->getConfig()->getOption('form_attr');
68+
if ($options['form_attr'] || $rootFormAttrOption) {
69+
$options['attr']['form'] = \is_string($rootFormAttrOption) ? $rootFormAttrOption : $form->getRoot()->getName();
70+
if (empty($options['attr']['form'])) {
71+
throw new LogicException('"form_attr" option must be a string identifier on root form when it has no id.');
72+
}
73+
}
6574
} else {
66-
$id = $name;
75+
$id = \is_string($options['form_attr']) ? $options['form_attr'] : $name;
6776
$fullName = $name;
6877
$uniqueBlockPrefix = '_'.$blockName;
6978

@@ -126,13 +135,15 @@ public function configureOptions(OptionsResolver $resolver)
126135
'translation_domain' => null,
127136
'auto_initialize' => true,
128137
'priority' => 0,
138+
'form_attr' => false,
129139
]);
130140

131141
$resolver->setAllowedTypes('block_prefix', ['null', 'string']);
132142
$resolver->setAllowedTypes('attr', 'array');
133143
$resolver->setAllowedTypes('row_attr', 'array');
134144
$resolver->setAllowedTypes('label_html', 'bool');
135145
$resolver->setAllowedTypes('priority', 'int');
146+
$resolver->setAllowedTypes('form_attr', ['bool', 'string']);
136147

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

Extension/Core/Type/FormType.php

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

8686
$helpTranslationParameters = array_merge($view->parent->vars['help_translation_parameters'], $helpTranslationParameters);
87-
88-
$rootFormAttrOption = $form->getRoot()->getConfig()->getOption('form_attr');
89-
if ($options['form_attr'] || $rootFormAttrOption) {
90-
$view->vars['attr']['form'] = \is_string($rootFormAttrOption) ? $rootFormAttrOption : $form->getRoot()->getName();
91-
if (empty($view->vars['attr']['form'])) {
92-
throw new LogicException('"form_attr" option must be a string identifier on root form when it has no id.');
93-
}
94-
}
95-
} elseif (\is_string($options['form_attr'])) {
96-
$view->vars['id'] = $options['form_attr'];
9787
}
9888

9989
$formConfig = $form->getConfig();
@@ -201,7 +191,6 @@ public function configureOptions(OptionsResolver $resolver)
201191
'is_empty_callback' => null,
202192
'getter' => null,
203193
'setter' => null,
204-
'form_attr' => false,
205194
]);
206195

207196
$resolver->setAllowedTypes('label_attr', 'array');
@@ -213,7 +202,6 @@ public function configureOptions(OptionsResolver $resolver)
213202
$resolver->setAllowedTypes('is_empty_callback', ['null', 'callable']);
214203
$resolver->setAllowedTypes('getter', ['null', 'callable']);
215204
$resolver->setAllowedTypes('setter', ['null', 'callable']);
216-
$resolver->setAllowedTypes('form_attr', ['bool', 'string']);
217205

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