diff --git a/src/Symfony/Component/Form/Extension/Core/Type/BaseType.php b/src/Symfony/Component/Form/Extension/Core/Type/BaseType.php index 4ac58bd2acd05..55efb652daec7 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/BaseType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/BaseType.php @@ -13,6 +13,7 @@ use Symfony\Component\Form\AbstractRendererEngine; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Exception\LogicException; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormView; @@ -70,8 +71,16 @@ public function buildView(FormView $view, FormInterface $form, array $options) if (!$labelFormat) { $labelFormat = $view->parent->vars['label_format']; } + + $rootFormAttrOption = $form->getRoot()->getConfig()->getOption('form_attr'); + if ($options['form_attr'] || $rootFormAttrOption) { + $options['attr']['form'] = \is_string($rootFormAttrOption) ? $rootFormAttrOption : $form->getRoot()->getName(); + if (empty($options['attr']['form'])) { + throw new LogicException('"form_attr" option must be a string identifier on root form when it has no id.'); + } + } } else { - $id = $name; + $id = \is_string($options['form_attr']) ? $options['form_attr'] : $name; $fullName = $name; $uniqueBlockPrefix = '_'.$blockName; @@ -137,6 +146,7 @@ public function configureOptions(OptionsResolver $resolver) 'translation_domain' => null, 'auto_initialize' => true, 'priority' => 0, + 'form_attr' => false, ]); $resolver->setAllowedTypes('block_prefix', ['null', 'string']); @@ -144,6 +154,7 @@ public function configureOptions(OptionsResolver $resolver) $resolver->setAllowedTypes('row_attr', 'array'); $resolver->setAllowedTypes('label_html', 'bool'); $resolver->setAllowedTypes('priority', 'int'); + $resolver->setAllowedTypes('form_attr', ['bool', 'string']); $resolver->setInfo('priority', 'The form rendering priority (higher priorities will be rendered first)'); } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FormType.php b/src/Symfony/Component/Form/Extension/Core/Type/FormType.php index f3bfd4d09519b..bd8ba13a3e7a5 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FormType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/FormType.php @@ -97,16 +97,6 @@ public function buildView(FormView $view, FormInterface $form, array $options) } $helpTranslationParameters = array_merge($view->parent->vars['help_translation_parameters'], $helpTranslationParameters); - - $rootFormAttrOption = $form->getRoot()->getConfig()->getOption('form_attr'); - if ($options['form_attr'] || $rootFormAttrOption) { - $view->vars['attr']['form'] = \is_string($rootFormAttrOption) ? $rootFormAttrOption : $form->getRoot()->getName(); - if (empty($view->vars['attr']['form'])) { - throw new LogicException('"form_attr" option must be a string identifier on root form when it has no id.'); - } - } - } elseif (\is_string($options['form_attr'])) { - $view->vars['id'] = $options['form_attr']; } $formConfig = $form->getConfig(); @@ -221,7 +211,6 @@ public function configureOptions(OptionsResolver $resolver) 'is_empty_callback' => null, 'getter' => null, 'setter' => null, - 'form_attr' => false, ]); $resolver->setAllowedTypes('label_attr', 'array'); @@ -233,7 +222,6 @@ public function configureOptions(OptionsResolver $resolver) $resolver->setAllowedTypes('is_empty_callback', ['null', 'callable']); $resolver->setAllowedTypes('getter', ['null', 'callable']); $resolver->setAllowedTypes('setter', ['null', 'callable']); - $resolver->setAllowedTypes('form_attr', ['bool', 'string']); $resolver->setInfo('getter', 'A callable that accepts two arguments (the view data and the current form field) and must return a value.'); $resolver->setInfo('setter', 'A callable that accepts three arguments (a reference to the view data, the submitted value and the current form field).'); diff --git a/src/Symfony/Component/Form/Tests/Command/DebugCommandTest.php b/src/Symfony/Component/Form/Tests/Command/DebugCommandTest.php index 798604649e012..73750380385f8 100644 --- a/src/Symfony/Component/Form/Tests/Command/DebugCommandTest.php +++ b/src/Symfony/Component/Form/Tests/Command/DebugCommandTest.php @@ -234,6 +234,7 @@ public function provideCompletionSuggestions(): iterable 'translation_domain', 'auto_initialize', 'priority', + 'form_attr', ], ]; @@ -253,6 +254,7 @@ public function provideCompletionSuggestions(): iterable 'translation_domain', 'auto_initialize', 'priority', + 'form_attr', ], ]; diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ButtonTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ButtonTypeTest.php index 654e04649e9f1..dcff028026482 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ButtonTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ButtonTypeTest.php @@ -13,6 +13,8 @@ use Symfony\Component\Form\Button; use Symfony\Component\Form\Exception\BadMethodCallException; +use Symfony\Component\Form\Exception\LogicException; +use Symfony\Component\Form\Extension\Core\Type\FormType; /** * @author Bernhard Schussek @@ -36,4 +38,65 @@ public function testSubmitNullUsesDefaultEmptyData($emptyData = 'empty', $expect $this->expectExceptionMessage('Buttons do not support empty data.'); parent::testSubmitNullUsesDefaultEmptyData($emptyData, $expectedData); } + + public function testFormAttrOnRoot() + { + $view = $this->factory + ->createNamedBuilder('parent', FormType::class, null, [ + 'form_attr' => true, + ]) + ->add('child1', $this->getTestedType()) + ->add('child2', $this->getTestedType()) + ->getForm() + ->createView(); + $this->assertArrayNotHasKey('form', $view->vars['attr']); + $this->assertSame($view->vars['id'], $view['child1']->vars['attr']['form']); + $this->assertSame($view->vars['id'], $view['child2']->vars['attr']['form']); + } + + public function testFormAttrOnChild() + { + $view = $this->factory + ->createNamedBuilder('parent') + ->add('child1', $this->getTestedType(), [ + 'form_attr' => true, + ]) + ->add('child2', $this->getTestedType()) + ->getForm() + ->createView(); + $this->assertArrayNotHasKey('form', $view->vars['attr']); + $this->assertSame($view->vars['id'], $view['child1']->vars['attr']['form']); + $this->assertArrayNotHasKey('form', $view['child2']->vars['attr']); + } + + public function testFormAttrAsBoolWithNoId() + { + $this->expectException(LogicException::class); + $this->expectErrorMessage('form_attr'); + $this->factory + ->createNamedBuilder('', FormType::class, null, [ + 'form_attr' => true, + ]) + ->add('child1', $this->getTestedType()) + ->add('child2', $this->getTestedType()) + ->getForm() + ->createView(); + } + + public function testFormAttrAsStringWithNoId() + { + $stringId = 'custom-identifier'; + $view = $this->factory + ->createNamedBuilder('', FormType::class, null, [ + 'form_attr' => $stringId, + ]) + ->add('child1', $this->getTestedType()) + ->add('child2', $this->getTestedType()) + ->getForm() + ->createView(); + $this->assertArrayNotHasKey('form', $view->vars['attr']); + $this->assertSame($stringId, $view->vars['id']); + $this->assertSame($view->vars['id'], $view['child1']->vars['attr']['form']); + $this->assertSame($view->vars['id'], $view['child2']->vars['attr']['form']); + } } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy