diff --git a/config/sets/symfony/symfony7/symfony73.php b/config/sets/symfony/symfony7/symfony73.php index 267b9b60..b003d2ca 100644 --- a/config/sets/symfony/symfony7/symfony73.php +++ b/config/sets/symfony/symfony7/symfony73.php @@ -10,4 +10,5 @@ $rectorConfig->import(__DIR__ . '/symfony73/symfony73-console.php'); $rectorConfig->import(__DIR__ . '/symfony73/symfony73-security-core.php'); $rectorConfig->import(__DIR__ . '/symfony73/symfony73-twig-bundle.php'); + $rectorConfig->import(__DIR__ . '/symfony73/symfony73-validator.php'); }; diff --git a/config/sets/symfony/symfony7/symfony73/symfony73-validator.php b/config/sets/symfony/symfony7/symfony73/symfony73-validator.php new file mode 100644 index 00000000..061fa642 --- /dev/null +++ b/config/sets/symfony/symfony7/symfony73/symfony73-validator.php @@ -0,0 +1,10 @@ +rules([ConstraintOptionsToNamedArgumentsRector::class]); +}; diff --git a/rules-tests/Symfony73/Rector/Class_/ConstraintOptionsToNamedArgumentsRector/ConstraintOptionsToNamedArgumentsRectorTest.php b/rules-tests/Symfony73/Rector/Class_/ConstraintOptionsToNamedArgumentsRector/ConstraintOptionsToNamedArgumentsRectorTest.php new file mode 100644 index 00000000..c1f80614 --- /dev/null +++ b/rules-tests/Symfony73/Rector/Class_/ConstraintOptionsToNamedArgumentsRector/ConstraintOptionsToNamedArgumentsRectorTest.php @@ -0,0 +1,28 @@ +doTestFile($filePath); + } + + public static function provideData(): Iterator + { + return self::yieldFilesFromDirectory(__DIR__ . '/Fixture'); + } + + public function provideConfigFilePath(): string + { + return __DIR__ . '/config/configured_rule.php'; + } +} diff --git a/rules-tests/Symfony73/Rector/Class_/ConstraintOptionsToNamedArgumentsRector/Fixture/some_form.php.inc b/rules-tests/Symfony73/Rector/Class_/ConstraintOptionsToNamedArgumentsRector/Fixture/some_form.php.inc new file mode 100644 index 00000000..afe9af5b --- /dev/null +++ b/rules-tests/Symfony73/Rector/Class_/ConstraintOptionsToNamedArgumentsRector/Fixture/some_form.php.inc @@ -0,0 +1,45 @@ +add('name', TextType::class, [ + 'constraints' => [ + new NotBlank(['message' => 'Name is required.']), + ], + ]); + } +} +?> +----- +add('name', TextType::class, [ + 'constraints' => [ + new NotBlank(message: 'Name is required.'), + ], + ]); + } +} +?> diff --git a/rules-tests/Symfony73/Rector/Class_/ConstraintOptionsToNamedArgumentsRector/config/configured_rule.php b/rules-tests/Symfony73/Rector/Class_/ConstraintOptionsToNamedArgumentsRector/config/configured_rule.php new file mode 100644 index 00000000..67a80ade --- /dev/null +++ b/rules-tests/Symfony73/Rector/Class_/ConstraintOptionsToNamedArgumentsRector/config/configured_rule.php @@ -0,0 +1,10 @@ +rule(ConstraintOptionsToNamedArgumentsRector::class); +}; diff --git a/rules/Symfony73/Rector/Class_/ConstraintOptionsToNamedArgumentsRector.php b/rules/Symfony73/Rector/Class_/ConstraintOptionsToNamedArgumentsRector.php new file mode 100644 index 00000000..b13d58fb --- /dev/null +++ b/rules/Symfony73/Rector/Class_/ConstraintOptionsToNamedArgumentsRector.php @@ -0,0 +1,103 @@ + 'This field should not be blank.']); +CODE_SAMPLE + , + <<<'CODE_SAMPLE' +use Symfony\Component\Validator\Constraints\NotBlank; + +$constraint = new NotBlank(message: 'This field should not be blank.'); +CODE_SAMPLE + )] + ); + } + + public function getNodeTypes(): array + { + return [New_::class]; + } + + public function refactor(Node $node): ?Node + { + if (!$node instanceof New_) { + return null; + } + + // Match classes starting with Symfony\Component\Validator\Constraints\ + if (!$node->class instanceof FullyQualified && !$node->class instanceof Name) { + return null; + } + + $className = $this->getName($node->class); + if (!is_string($className)) { + return null; + } + + if (!str_starts_with($className, 'Symfony\Component\Validator\Constraints\\')) { + return null; + } + + if ( + 0 === count($node->args) || + !$node->args[0] instanceof Arg || + !$node->args[0]->value instanceof Array_ + ) { + return null; + } + + $array = $node->args[0]->value; + $namedArgs = []; + + foreach ($array->items as $item) { + if (!$item instanceof ArrayItem || null === $item->key) { + continue; + } + + $keyValue = $this->valueResolver->getValue($item->key); + if (!is_string($keyValue)) { + continue; + } + + $arg = new Node\Arg($item->value); + $arg->name = new Node\Identifier($keyValue); + + $namedArgs[] = $arg; + } + + $node->args = $namedArgs; + + return $node; + } +} diff --git a/src/Set/SetProvider/Symfony7SetProvider.php b/src/Set/SetProvider/Symfony7SetProvider.php index e6e6c397..68e42b12 100644 --- a/src/Set/SetProvider/Symfony7SetProvider.php +++ b/src/Set/SetProvider/Symfony7SetProvider.php @@ -104,6 +104,12 @@ public function provide(): array '7.3', __DIR__ . '/../../../config/sets/symfony/symfony7/symfony73/symfony73-twig-bundle.php' ), + new ComposerTriggeredSet( + SetGroup::SYMFONY, + 'symfony/validator', + '7.3', + __DIR__ . '/../../../config/sets/symfony/symfony7/symfony73/symfony73-validator.php' + ), ]; } }