diff --git a/src/Generator.php b/src/Generator.php index 315b33427..5f744594c 100644 --- a/src/Generator.php +++ b/src/Generator.php @@ -76,6 +76,36 @@ public function generateClass(string $className, string $templateName, array $va return $targetPath; } + /** + * Future replacement for generateClass(). + * + * @internal + * + * @param string $templateName Template name in Resources/skeleton to use + * @param array $variables Array of variables to pass to the template + * + * @return string The path where the file will be created + * + * @throws \Exception + */ + final public function generateClassFromClassData(ClassData $classData, string $templateName, array $variables = []): string + { + $classData = $this->templateComponentGenerator->configureClass($classData); + $targetPath = $this->fileManager->getRelativePathForFutureClass($classData->getFullClassName()); + + if (null === $targetPath) { + throw new \LogicException(\sprintf('Could not determine where to locate the new class "%s", maybe try with a full namespace like "\\My\\Full\\Namespace\\%s"', $classData->getFullClassName(), $classData->getClassName())); + } + + $variables = array_merge($variables, [ + 'class_data' => $classData, + ]); + + $this->addOperation($targetPath, $templateName, $variables); + + return $targetPath; + } + /** * Generate a normal file from a template. * diff --git a/src/Maker/MakeValidator.php b/src/Maker/MakeValidator.php index 7fb12c299..51c40ed69 100644 --- a/src/Maker/MakeValidator.php +++ b/src/Maker/MakeValidator.php @@ -16,9 +16,12 @@ use Symfony\Bundle\MakerBundle\Generator; use Symfony\Bundle\MakerBundle\InputConfiguration; use Symfony\Bundle\MakerBundle\Str; +use Symfony\Bundle\MakerBundle\Util\ClassSource\Model\ClassData; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Validation; /** @@ -49,26 +52,31 @@ public function configureCommand(Command $command, InputConfiguration $inputConf /** @return void */ public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator) { - $validatorClassNameDetails = $generator->createClassNameDetails( - $input->getArgument('name'), - 'Validator\\', - 'Validator' + $validatorClassData = ClassData::create( + class: \sprintf('Validator\\%s', $input->getArgument('name')), + suffix: 'Validator', + extendsClass: ConstraintValidator::class, + useStatements: [ + Constraint::class, + ], ); - $constraintFullClassName = Str::removeSuffix($validatorClassNameDetails->getFullName(), 'Validator'); + $constraintDataClass = ClassData::create( + class: \sprintf('Validator\\%s', Str::removeSuffix($validatorClassData->getClassName(), 'Validator')), + extendsClass: Constraint::class, + ); - $generator->generateClass( - $validatorClassNameDetails->getFullName(), + $generator->generateClassFromClassData( + $validatorClassData, 'validator/Validator.tpl.php', [ - 'constraint_class_name' => Str::getShortClassName($constraintFullClassName), + 'constraint_class_name' => $constraintDataClass->getClassName(), ] ); - $generator->generateClass( - $constraintFullClassName, + $generator->generateClassFromClassData( + $constraintDataClass, 'validator/Constraint.tpl.php', - [] ); $generator->writeChanges(); diff --git a/src/Maker/MakeVoter.php b/src/Maker/MakeVoter.php index faabc993e..aa118afa7 100644 --- a/src/Maker/MakeVoter.php +++ b/src/Maker/MakeVoter.php @@ -60,10 +60,9 @@ class: \sprintf('Security\Voter\%s', $input->getArgument('name')), ] ); - $generator->generateClass( - $voterClassData->getFullClassName(), + $generator->generateClassFromClassData( + $voterClassData, 'security/Voter.tpl.php', - ['class_data' => $voterClassData] ); $generator->writeChanges(); diff --git a/src/Resources/skeleton/validator/Constraint.tpl.php b/src/Resources/skeleton/validator/Constraint.tpl.php index 009c13a05..414c19eeb 100644 --- a/src/Resources/skeleton/validator/Constraint.tpl.php +++ b/src/Resources/skeleton/validator/Constraint.tpl.php @@ -1,11 +1,11 @@ -namespace ; +namespace getNamespace(); ?>; -use Symfony\Component\Validator\Constraint; +getUseStatements(); ?> #[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] -class extends Constraint +getClassDeclaration(); ?> { public string $message = 'The string "{{ string }}" contains an illegal character: it can only contain letters or numbers.'; diff --git a/src/Resources/skeleton/validator/Validator.tpl.php b/src/Resources/skeleton/validator/Validator.tpl.php index ccc1a00f9..ef711e888 100644 --- a/src/Resources/skeleton/validator/Validator.tpl.php +++ b/src/Resources/skeleton/validator/Validator.tpl.php @@ -1,11 +1,10 @@ -namespace ; +namespace getNamespace(); ?>; -use Symfony\Component\Validator\Constraint; -use Symfony\Component\Validator\ConstraintValidator; +getUseStatements(); ?> -class extends ConstraintValidator +getClassDeclaration(); ?> { public function validate(mixed $value, Constraint $constraint): void { @@ -18,6 +17,7 @@ public function validate(mixed $value, Constraint $constraint): void // TODO: implement the validation here $this->context->buildViolation($constraint->message) ->setParameter('{{ value }}', $value) - ->addViolation(); + ->addViolation() + ; } } diff --git a/tests/Maker/MakeValidatorTest.php b/tests/Maker/MakeValidatorTest.php index 0ca11939c..acc551b0c 100644 --- a/tests/Maker/MakeValidatorTest.php +++ b/tests/Maker/MakeValidatorTest.php @@ -32,6 +32,18 @@ public function getTestDetails(): \Generator 'FooBar', ] ); + + // Validator + $expectedVoterPath = \dirname(__DIR__).'/fixtures/make-validator/expected/FooBarValidator.php'; + $generatedVoter = $runner->getPath('src/Validator/FooBarValidator.php'); + + self::assertSame(file_get_contents($expectedVoterPath), file_get_contents($generatedVoter)); + + // Constraint + $expectedVoterPath = \dirname(__DIR__).'/fixtures/make-validator/expected/FooBar.php'; + $generatedVoter = $runner->getPath('src/Validator/FooBar.php'); + + self::assertSame(file_get_contents($expectedVoterPath), file_get_contents($generatedVoter)); }), ]; } diff --git a/tests/fixtures/make-validator/expected/FooBar.php b/tests/fixtures/make-validator/expected/FooBar.php new file mode 100644 index 000000000..40bbd5087 --- /dev/null +++ b/tests/fixtures/make-validator/expected/FooBar.php @@ -0,0 +1,21 @@ +context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $value) + ->addViolation() + ; + } +}