diff --git a/UPGRADE-6.3.md b/UPGRADE-6.3.md index 1b6479a48a083..db216be23bea6 100644 --- a/UPGRADE-6.3.md +++ b/UPGRADE-6.3.md @@ -7,6 +7,11 @@ DependencyInjection * Deprecate `PhpDumper` options `inline_factories_parameter` and `inline_class_loader_parameter`, use `inline_factories` and `inline_class_loader` instead * Deprecate undefined and numeric keys with `service_locator` config, use string aliases instead +Form +---- + + * Remove argument `$legacyErrorMessages` from the constructor of `FormTypeValidatorExtension` and `ValidatorExtension` + FrameworkBundle --------------- diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.php index 3c936a284b325..2a6e1e7c3ef98 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.php @@ -132,7 +132,6 @@ ->set('form.type_extension.form.validator', FormTypeValidatorExtension::class) ->args([ service('validator'), - false, service('twig.form.renderer')->ignoreOnInvalid(), service('translator')->ignoreOnInvalid(), ]) diff --git a/src/Symfony/Component/Form/CHANGELOG.md b/src/Symfony/Component/Form/CHANGELOG.md index 68622612e30b3..cf187dddbdd84 100644 --- a/src/Symfony/Component/Form/CHANGELOG.md +++ b/src/Symfony/Component/Form/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +6.3 +--- + + * Remove argument `$legacyErrorMessages` from the constructor of `FormTypeValidatorExtension` and `ValidatorExtension` + 6.2 --- diff --git a/src/Symfony/Component/Form/Extension/Validator/Type/FormTypeValidatorExtension.php b/src/Symfony/Component/Form/Extension/Validator/Type/FormTypeValidatorExtension.php index 4602918c3a9b8..c4da3a8fb7e0b 100644 --- a/src/Symfony/Component/Form/Extension/Validator/Type/FormTypeValidatorExtension.php +++ b/src/Symfony/Component/Form/Extension/Validator/Type/FormTypeValidatorExtension.php @@ -29,10 +29,27 @@ class FormTypeValidatorExtension extends BaseValidatorExtension { private ValidatorInterface $validator; private ViolationMapper $violationMapper; - private bool $legacyErrorMessages; - public function __construct(ValidatorInterface $validator, bool $legacyErrorMessages = true, FormRendererInterface $formRenderer = null, TranslatorInterface $translator = null) + /** + * @param FormRendererInterface|null $formRenderer + * @param TranslatorInterface|null $translator + */ + public function __construct(ValidatorInterface $validator, /* FormRendererInterface */ $formRenderer = null, /* TranslatorInterface */ $translator = null) { + if (\is_bool($formRenderer)) { + trigger_deprecation('symfony/form', '6.3', 'The signature of "%s" constructor requires 3 arguments: "ValidatorInterface $validator, FormRendererInterface $formRenderer = null, TranslatorInterface $translator = null". Passing argument $legacyErrorMessages is deprecated.', __CLASS__); + $formRenderer = $translator; + $translator = 4 <= \func_num_args() ? func_get_arg(3) : null; + } + + if (null !== $formRenderer && !$formRenderer instanceof FormRendererInterface) { + throw new \TypeError(sprintf('Argument 2 passed to "%s()" must be an instance of "%s" or null, "%s" given.', __METHOD__, FormRendererInterface::class, get_debug_type($formRenderer))); + } + + if (null !== $translator && !$translator instanceof TranslatorInterface) { + throw new \TypeError(sprintf('Argument 3 passed to "%s()" must be an instance of "%s" or null, "%s" given.', __METHOD__, TranslatorInterface::class, get_debug_type($formRenderer))); + } + $this->validator = $validator; $this->violationMapper = new ViolationMapper($formRenderer, $translator); } diff --git a/src/Symfony/Component/Form/Extension/Validator/ValidatorExtension.php b/src/Symfony/Component/Form/Extension/Validator/ValidatorExtension.php index fe1bd33f5f8d5..b1f6478b56792 100644 --- a/src/Symfony/Component/Form/Extension/Validator/ValidatorExtension.php +++ b/src/Symfony/Component/Form/Extension/Validator/ValidatorExtension.php @@ -30,11 +30,26 @@ class ValidatorExtension extends AbstractExtension private ValidatorInterface $validator; private ?FormRendererInterface $formRenderer; private ?TranslatorInterface $translator; - private bool $legacyErrorMessages; - public function __construct(ValidatorInterface $validator, bool $legacyErrorMessages = true, FormRendererInterface $formRenderer = null, TranslatorInterface $translator = null) + /** + * @param FormRendererInterface|null $formRenderer + * @param TranslatorInterface|null $translator + */ + public function __construct(ValidatorInterface $validator, /* FormRendererInterface */ $formRenderer = null, /* TranslatorInterface */ $translator = null) { - $this->legacyErrorMessages = $legacyErrorMessages; + if (\is_bool($formRenderer)) { + trigger_deprecation('symfony/form', '6.3', 'The signature of "%s" constructor requires 3 arguments: "ValidatorInterface $validator, FormRendererInterface $formRenderer = null, TranslatorInterface $translator = null". Passing argument $legacyErrorMessages is deprecated.', __CLASS__); + $formRenderer = $translator; + $translator = 4 <= \func_num_args() ? func_get_arg(3) : null; + } + + if (null !== $formRenderer && !$formRenderer instanceof FormRendererInterface) { + throw new \TypeError(sprintf('Argument 2 passed to "%s()" must be an instance of "%s" or null, "%s" given.', __METHOD__, FormRendererInterface::class, get_debug_type($formRenderer))); + } + + if (null !== $translator && !$translator instanceof TranslatorInterface) { + throw new \TypeError(sprintf('Argument 3 passed to "%s()" must be an instance of "%s" or null, "%s" given.', __METHOD__, TranslatorInterface::class, get_debug_type($translator))); + } $metadata = $validator->getMetadataFor(\Symfony\Component\Form\Form::class); @@ -60,7 +75,7 @@ public function loadTypeGuesser(): ?FormTypeGuesserInterface protected function loadTypeExtensions(): array { return [ - new Type\FormTypeValidatorExtension($this->validator, $this->legacyErrorMessages, $this->formRenderer, $this->translator), + new Type\FormTypeValidatorExtension($this->validator, $this->formRenderer, $this->translator), new Type\RepeatedTypeValidatorExtension(), new Type\SubmitTypeValidatorExtension(), ]; diff --git a/src/Symfony/Component/Form/Test/Traits/ValidatorExtensionTrait.php b/src/Symfony/Component/Form/Test/Traits/ValidatorExtensionTrait.php index b4b35fadf9c40..80db4ae18e3db 100644 --- a/src/Symfony/Component/Form/Test/Traits/ValidatorExtensionTrait.php +++ b/src/Symfony/Component/Form/Test/Traits/ValidatorExtensionTrait.php @@ -39,6 +39,6 @@ protected function getValidatorExtension(): ValidatorExtension $this->validator->expects($this->any())->method('getMetadataFor')->will($this->returnValue($metadata)); $this->validator->expects($this->any())->method('validate')->will($this->returnValue(new ConstraintViolationList())); - return new ValidatorExtension($this->validator, false); + return new ValidatorExtension($this->validator); } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorPerformanceTest.php b/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorPerformanceTest.php index e8bfbc64ae5a5..64b49d7e9fb12 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorPerformanceTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorPerformanceTest.php @@ -23,7 +23,7 @@ class FormValidatorPerformanceTest extends FormPerformanceTestCase protected function getExtensions() { return [ - new ValidatorExtension(Validation::createValidator(), false), + new ValidatorExtension(Validation::createValidator()), ]; } diff --git a/src/Symfony/Component/Form/Tests/Extension/Validator/Type/FormTypeValidatorExtensionTest.php b/src/Symfony/Component/Form/Tests/Extension/Validator/Type/FormTypeValidatorExtensionTest.php index 3b4cd77396c60..3ccfc54626f0d 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Validator/Type/FormTypeValidatorExtensionTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Validator/Type/FormTypeValidatorExtensionTest.php @@ -76,7 +76,7 @@ public function testInvalidConstraint() public function testGroupSequenceWithConstraintsOption() { $form = Forms::createFormFactoryBuilder() - ->addExtension(new ValidatorExtension(Validation::createValidator(), false)) + ->addExtension(new ValidatorExtension(Validation::createValidator())) ->getFormFactory() ->create(FormTypeTest::TESTED_TYPE, null, ['validation_groups' => new GroupSequence(['First', 'Second'])]) ->add('field', TextTypeTest::TESTED_TYPE, [ diff --git a/src/Symfony/Component/Form/Tests/Extension/Validator/ValidatorExtensionTest.php b/src/Symfony/Component/Form/Tests/Extension/Validator/ValidatorExtensionTest.php index c92bbe6651904..64bd317fca591 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Validator/ValidatorExtensionTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Validator/ValidatorExtensionTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Form\Tests\Extension\Validator; use PHPUnit\Framework\TestCase; +use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Component\Form\Extension\Validator\Constraints\Form as FormConstraint; use Symfony\Component\Form\Extension\Validator\ValidatorExtension; use Symfony\Component\Form\Extension\Validator\ValidatorTypeGuesser; @@ -24,8 +25,15 @@ class ValidatorExtensionTest extends TestCase { - public function test2Dot5ValidationApi() + use ExpectDeprecationTrait; + + /** + * @group legacy + */ + public function testLegacy2Dot5ValidationApi() { + $this->expectDeprecation('Since symfony/form 6.3: The signature of "Symfony\Component\Form\Extension\Validator\ValidatorExtension" constructor requires 3 arguments: "ValidatorInterface $validator, FormRendererInterface $formRenderer = null, TranslatorInterface $translator = null". Passing argument $legacyErrorMessages is deprecated.'); + $metadata = new ClassMetadata(Form::class); $metadataFactory = new FakeMetadataFactory(); @@ -46,4 +54,67 @@ public function test2Dot5ValidationApi() $this->assertSame(TraversalStrategy::NONE, $metadata->traversalStrategy); $this->assertCount(0, $metadata->getPropertyMetadata('children')); } + + /** + * @group legacy + */ + public function testLegacyWithBadFormRendererType() + { + $metadata = new ClassMetadata(Form::class); + + $metadataFactory = new FakeMetadataFactory(); + $metadataFactory->addMetadata($metadata); + + $validator = Validation::createValidatorBuilder() + ->setMetadataFactory($metadataFactory) + ->getValidator(); + + $this->expectException(\TypeError::class); + $this->expectExceptionMessage('Argument 2 passed to "Symfony\Component\Form\Extension\Validator\ValidatorExtension::__construct()" must be an instance of "Symfony\Component\Form\FormRendererInterface" or null, "stdClass" given.'); + + new ValidatorExtension($validator, new \stdClass()); + } + + /** + * @group legacy + */ + public function testLegacyWithBadTranslatorType() + { + $metadata = new ClassMetadata(Form::class); + + $metadataFactory = new FakeMetadataFactory(); + $metadataFactory->addMetadata($metadata); + + $validator = Validation::createValidatorBuilder() + ->setMetadataFactory($metadataFactory) + ->getValidator(); + + $this->expectException(\TypeError::class); + $this->expectExceptionMessage('Argument 3 passed to "Symfony\Component\Form\Extension\Validator\ValidatorExtension::__construct()" must be an instance of "Symfony\Contracts\Translation\TranslatorInterface" or null, "stdClass" given.'); + + new ValidatorExtension($validator, null, new \stdClass()); + } + + public function test2Dot5ValidationApi() + { + $metadata = new ClassMetadata(Form::class); + + $metadataFactory = new FakeMetadataFactory(); + $metadataFactory->addMetadata($metadata); + + $validator = Validation::createValidatorBuilder() + ->setMetadataFactory($metadataFactory) + ->getValidator(); + + $extension = new ValidatorExtension($validator); + + $this->assertInstanceOf(ValidatorTypeGuesser::class, $extension->loadTypeGuesser()); + + $this->assertCount(1, $metadata->getConstraints()); + $this->assertInstanceOf(FormConstraint::class, $metadata->getConstraints()[0]); + + $this->assertSame(CascadingStrategy::NONE, $metadata->cascadingStrategy); + $this->assertSame(TraversalStrategy::NONE, $metadata->traversalStrategy); + $this->assertCount(0, $metadata->getPropertyMetadata('children')); + } }