diff --git a/UPGRADE-6.4.md b/UPGRADE-6.4.md index f7ed4c4a7a524..8213301f0e3b5 100644 --- a/UPGRADE-6.4.md +++ b/UPGRADE-6.4.md @@ -62,6 +62,8 @@ Routing ------- * Add native return type to `AnnotationClassLoader::setResolver()` + * Deprecate Doctrine annotations support in favor of native attributes + * Change the constructor signature of `AnnotationClassLoader` to `__construct(?string $env = null)`, passing an annotation reader as first argument is deprecated Security -------- @@ -69,3 +71,17 @@ Security * `UserValueResolver` no longer implements `ArgumentValueResolverInterface` * Make `PersistentToken` immutable * Deprecate accepting only `DateTime` for `TokenProviderInterface::updateToken()`, use `DateTimeInterface` instead + +Serializer +---------- + + * Deprecate Doctrine annotations support in favor of native attributes + * Deprecate passing an annotation reader to the constructor of `AnnotationLoader` + +Validator +--------- + + * Deprecate Doctrine annotations support in favor of native attributes + * Deprecate passing an annotation reader to the constructor signature of `AnnotationLoader` + * Deprecate `ValidatorBuilder::setDoctrineAnnotationReader()` + * Deprecate `ValidatorBuilder::addDefaultDoctrineAnnotationReader()` diff --git a/src/Symfony/Bridge/Doctrine/Tests/Validator/DoctrineLoaderTest.php b/src/Symfony/Bridge/Doctrine/Tests/Validator/DoctrineLoaderTest.php index 94f4b0527f0dc..70a30f3173920 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Validator/DoctrineLoaderTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Validator/DoctrineLoaderTest.php @@ -28,7 +28,7 @@ use Symfony\Component\Validator\Mapping\ClassMetadata; use Symfony\Component\Validator\Mapping\PropertyMetadata; use Symfony\Component\Validator\Mapping\TraversalStrategy; -use Symfony\Component\Validator\Tests\Fixtures\Entity; +use Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity; use Symfony\Component\Validator\Validation; /** @@ -40,7 +40,6 @@ public function testLoadClassMetadata() { $validator = Validation::createValidatorBuilder() ->enableAnnotationMapping(true) - ->addDefaultDoctrineAnnotationReader() ->addLoader(new DoctrineLoader(DoctrineTestHelper::createTestEntityManager(), '{^Symfony\\\\Bridge\\\\Doctrine\\\\Tests\\\\Fixtures\\\\DoctrineLoader}')) ->getValidator() ; @@ -144,7 +143,6 @@ public function testExtractEnum() $validator = Validation::createValidatorBuilder() ->addMethodMapping('loadValidatorMetadata') ->enableAnnotationMapping(true) - ->addDefaultDoctrineAnnotationReader() ->addLoader(new DoctrineLoader(DoctrineTestHelper::createTestEntityManager(), '{^Symfony\\\\Bridge\\\\Doctrine\\\\Tests\\\\Fixtures\\\\DoctrineLoader}')) ->getValidator() ; @@ -162,7 +160,6 @@ public function testFieldMappingsConfiguration() { $validator = Validation::createValidatorBuilder() ->enableAnnotationMapping(true) - ->addDefaultDoctrineAnnotationReader() ->addXmlMappings([__DIR__.'/../Resources/validator/BaseUser.xml']) ->addLoader( new DoctrineLoader( @@ -204,7 +201,6 @@ public function testClassNoAutoMapping() { $validator = Validation::createValidatorBuilder() ->enableAnnotationMapping(true) - ->addDefaultDoctrineAnnotationReader() ->addLoader(new DoctrineLoader(DoctrineTestHelper::createTestEntityManager(), '{.*}')) ->getValidator(); diff --git a/src/Symfony/Bridge/Doctrine/composer.json b/src/Symfony/Bridge/Doctrine/composer.json index 062528317223a..e12b86af4a75d 100644 --- a/src/Symfony/Bridge/Doctrine/composer.json +++ b/src/Symfony/Bridge/Doctrine/composer.json @@ -43,7 +43,6 @@ "symfony/uid": "^5.4|^6.0|^7.0", "symfony/validator": "^5.4.25|~6.2.12|^6.3.1|^7.0", "symfony/var-dumper": "^5.4|^6.0|^7.0", - "doctrine/annotations": "^1.13.1|^2", "doctrine/collections": "^1.0|^2.0", "doctrine/data-fixtures": "^1.1", "doctrine/dbal": "^2.13.1|^3.0", @@ -51,7 +50,6 @@ "psr/log": "^1|^2|^3" }, "conflict": { - "doctrine/annotations": "<1.13.1", "doctrine/dbal": "<2.13.1", "doctrine/lexer": "<1.1", "doctrine/orm": "<2.15", diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/Fixtures/SerializerModelFixture.php b/src/Symfony/Bridge/Twig/Tests/Extension/Fixtures/SerializerModelFixture.php index 07493ea9d8db7..6c0cc210eac95 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/Fixtures/SerializerModelFixture.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/Fixtures/SerializerModelFixture.php @@ -9,9 +9,7 @@ */ class SerializerModelFixture { - /** - * @Groups({"read"}) - */ + #[Groups(['read'])] public $name = 'howdy'; public $title = 'fixture'; diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/SerializerExtensionTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/SerializerExtensionTest.php index 0c36c8c6b4b93..0115f867d8a80 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/SerializerExtensionTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/SerializerExtensionTest.php @@ -11,7 +11,6 @@ namespace Symfony\Bridge\Twig\Tests\Extension; -use Doctrine\Common\Annotations\AnnotationReader; use PHPUnit\Framework\TestCase; use Symfony\Bridge\Twig\Extension\SerializerExtension; use Symfony\Bridge\Twig\Extension\SerializerRuntime; @@ -50,7 +49,7 @@ public static function serializerDataProvider(): \Generator private function getTwig(string $template): Environment { - $meta = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $meta = new ClassMetadataFactory(new AnnotationLoader()); $runtime = new SerializerRuntime(new Serializer([new ObjectNormalizer($meta)], [new JsonEncoder(), new YamlEncoder()])); $mockRuntimeLoader = $this->createMock(RuntimeLoaderInterface::class); diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json index abe6f4d75f66f..36014a590b41f 100644 --- a/src/Symfony/Bridge/Twig/composer.json +++ b/src/Symfony/Bridge/Twig/composer.json @@ -21,7 +21,6 @@ "twig/twig": "^2.13|^3.0.4" }, "require-dev": { - "doctrine/annotations": "^1.12|^2", "egulias/email-validator": "^2.1.10|^3|^4", "league/html-to-markdown": "^5.0", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", @@ -62,6 +61,7 @@ "symfony/http-foundation": "<5.4", "symfony/http-kernel": "<6.2", "symfony/mime": "<6.2", + "symfony/serializer": "<6.2", "symfony/translation": "<5.4", "symfony/workflow": "<5.4" }, diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 846639ebda2ac..c5785beb2e8d9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -144,6 +144,7 @@ use Symfony\Component\RateLimiter\Storage\CacheStorage; use Symfony\Component\RemoteEvent\Attribute\AsRemoteEventConsumer; use Symfony\Component\RemoteEvent\RemoteEvent; +use Symfony\Component\Routing\Loader\AnnotationClassLoader; use Symfony\Component\Routing\Loader\Psr4DirectoryLoader; use Symfony\Component\Scheduler\Attribute\AsSchedule; use Symfony\Component\Scheduler\Messenger\SchedulerTransportFactory; @@ -181,6 +182,7 @@ use Symfony\Component\Validator\Mapping\Loader\PropertyInfoLoader; use Symfony\Component\Validator\ObjectInitializerInterface; use Symfony\Component\Validator\Validation; +use Symfony\Component\Validator\ValidatorBuilder; use Symfony\Component\Webhook\Controller\WebhookController; use Symfony\Component\WebLink\HttpHeaderSerializer; use Symfony\Component\Workflow; @@ -1179,6 +1181,13 @@ private function registerRouterConfiguration(array $config, ContainerBuilder $co if (!class_exists(Psr4DirectoryLoader::class)) { $container->removeDefinition('routing.loader.psr4'); } + + if ($this->isInitializedConfigEnabled('annotations') && (new \ReflectionClass(AnnotationClassLoader::class))->hasProperty('reader')) { + $container->getDefinition('routing.loader.annotation')->setArguments([ + new Reference('annotation_reader'), + '%kernel.environment%', + ]); + } } private function registerSessionConfiguration(array $config, ContainerBuilder $container, PhpFileLoader $loader): void @@ -1609,7 +1618,7 @@ private function registerValidationConfiguration(array $config, ContainerBuilder if (\array_key_exists('enable_annotations', $config) && $config['enable_annotations']) { $validatorBuilder->addMethodCall('enableAnnotationMapping', [true]); - if ($this->isInitializedConfigEnabled('annotations')) { + if ($this->isInitializedConfigEnabled('annotations') && \method_exists(ValidatorBuilder::class, 'setDoctrineAnnotationReader')) { $validatorBuilder->addMethodCall('setDoctrineAnnotationReader', [new Reference('annotation_reader')]); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.php index 86a7cf874629c..10745b225e684 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.php @@ -94,7 +94,6 @@ ->set('routing.loader.annotation', AnnotatedRouteControllerLoader::class) ->args([ - service('annotation_reader')->nullOnInvalid(), '%kernel.environment%', ]) ->tag('routing.loader', ['priority' => -10]) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/ValidatorCacheWarmerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/ValidatorCacheWarmerTest.php index 8a54680c0f557..92ef379b1b819 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/ValidatorCacheWarmerTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/ValidatorCacheWarmerTest.php @@ -26,7 +26,7 @@ public function testWarmUp() $validatorBuilder->addXmlMapping(__DIR__.'/../Fixtures/Validation/Resources/person.xml'); $validatorBuilder->addYamlMapping(__DIR__.'/../Fixtures/Validation/Resources/author.yml'); $validatorBuilder->addMethodMapping('loadValidatorMetadata'); - $validatorBuilder->enableAnnotationMapping(true)->addDefaultDoctrineAnnotationReader(); + $validatorBuilder->enableAnnotationMapping(); $file = sys_get_temp_dir().'/cache-validator.php'; @unlink($file); @@ -46,7 +46,7 @@ public function testWarmUpWithAnnotations() { $validatorBuilder = new ValidatorBuilder(); $validatorBuilder->addYamlMapping(__DIR__.'/../Fixtures/Validation/Resources/categories.yml'); - $validatorBuilder->enableAnnotationMapping(true)->addDefaultDoctrineAnnotationReader(); + $validatorBuilder->enableAnnotationMapping(); $file = sys_get_temp_dir().'/cache-validator-with-annotations.php'; @unlink($file); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php index 877d502cdb5ec..b6324b96fd844 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php @@ -81,6 +81,7 @@ use Symfony\Component\Validator\DependencyInjection\AddConstraintValidatorsPass; use Symfony\Component\Validator\Validation; use Symfony\Component\Validator\Validator\ValidatorInterface; +use Symfony\Component\Validator\ValidatorBuilder; use Symfony\Component\Webhook\Client\RequestParser; use Symfony\Component\Webhook\Controller\WebhookController; use Symfony\Component\Workflow; @@ -1308,12 +1309,17 @@ public function testValidationLegacyAnnotations() $this->assertCount(8, $calls); $this->assertSame('enableAnnotationMapping', $calls[4][0]); - $this->assertSame('setDoctrineAnnotationReader', $calls[5][0]); - $this->assertEquals([new Reference('annotation_reader')], $calls[5][1]); - $this->assertSame('addMethodMapping', $calls[6][0]); - $this->assertSame(['loadValidatorMetadata'], $calls[6][1]); - $this->assertSame('setMappingCache', $calls[7][0]); - $this->assertEquals([new Reference('validator.mapping.cache.adapter')], $calls[7][1]); + if (\method_exists(ValidatorBuilder::class, 'setDoctrineAnnotationReader')) { + $this->assertSame('setDoctrineAnnotationReader', $calls[5][0]); + $this->assertEquals([new Reference('annotation_reader')], $calls[5][1]); + $i = 6; + } else { + $i = 5; + } + $this->assertSame('addMethodMapping', $calls[$i][0]); + $this->assertSame(['loadValidatorMetadata'], $calls[$i][1]); + $this->assertSame('setMappingCache', $calls[++$i][0]); + $this->assertEquals([new Reference('validator.mapping.cache.adapter')], $calls[$i][1]); // no cache this time } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Validation/Category.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Validation/Category.php index 6d9539cc58c48..ce1aa8018f3ea 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Validation/Category.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Validation/Category.php @@ -10,8 +10,6 @@ class Category public $id; - /** - * @Assert\Type("string") - */ + #[Assert\Type('string')] public $name; } diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index b0fac1a188e58..ba0096cfc52a8 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -30,7 +30,7 @@ "symfony/polyfill-mbstring": "~1.0", "symfony/filesystem": "^5.4|^6.0|^7.0", "symfony/finder": "^5.4|^6.0|^7.0", - "symfony/routing": "^6.1|^7.0" + "symfony/routing": "^6.4|^7.0" }, "require-dev": { "doctrine/annotations": "^1.13.1|^2", diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/SerializerExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/SerializerExtractorTest.php index 66d8c06b3e6ff..1aa57864d0927 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/SerializerExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/SerializerExtractorTest.php @@ -11,10 +11,10 @@ namespace Symfony\Component\PropertyInfo\Tests\Extractor; -use Doctrine\Common\Annotations\AnnotationReader; use PHPUnit\Framework\TestCase; use Symfony\Component\PropertyInfo\Extractor\SerializerExtractor; use Symfony\Component\PropertyInfo\Tests\Fixtures\AdderRemoverDummy; +use Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy; use Symfony\Component\PropertyInfo\Tests\Fixtures\IgnorePropertyDummy; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory; use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; @@ -24,14 +24,11 @@ */ class SerializerExtractorTest extends TestCase { - /** - * @var SerializerExtractor - */ - private $extractor; + private SerializerExtractor $extractor; protected function setUp(): void { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $this->extractor = new SerializerExtractor($classMetadataFactory); } @@ -39,7 +36,7 @@ public function testGetProperties() { $this->assertEquals( ['collection'], - $this->extractor->getProperties('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', ['serializer_groups' => ['a']]) + $this->extractor->getProperties(Dummy::class, ['serializer_groups' => ['a']]) ); } diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php index 5b38fc1bcc722..fabf1a0f767ea 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php @@ -42,8 +42,8 @@ class Dummy extends ParentDummy /** * @var \DateTimeImmutable[] - * @Groups({"a", "b"}) */ + #[Groups(['a', 'b'])] public $collection; /** diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/IgnorePropertyDummy.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/IgnorePropertyDummy.php index f2891b8d1bd35..39d29638a35af 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/IgnorePropertyDummy.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/IgnorePropertyDummy.php @@ -19,14 +19,9 @@ */ class IgnorePropertyDummy { - /** - * @Groups({"a"}) - */ + #[Groups(['a'])] public $visibleProperty; - /** - * @Groups({"a"}) - * @Ignore - */ + #[Groups(['a']), Ignore] private $ignoredProperty; } diff --git a/src/Symfony/Component/PropertyInfo/composer.json b/src/Symfony/Component/PropertyInfo/composer.json index 163ab8a0113ee..0828727944070 100644 --- a/src/Symfony/Component/PropertyInfo/composer.json +++ b/src/Symfony/Component/PropertyInfo/composer.json @@ -31,13 +31,13 @@ "symfony/cache": "^5.4|^6.0|^7.0", "symfony/dependency-injection": "^5.4|^6.0|^7.0", "phpdocumentor/reflection-docblock": "^5.2", - "phpstan/phpdoc-parser": "^1.0", - "doctrine/annotations": "^1.10.4|^2" + "phpstan/phpdoc-parser": "^1.0" }, "conflict": { "phpdocumentor/reflection-docblock": "<5.2", "phpdocumentor/type-resolver": "<1.5.1", - "symfony/dependency-injection": "<5.4" + "symfony/dependency-injection": "<5.4", + "symfony/serializer": "<5.4" }, "autoload": { "psr-4": { "Symfony\\Component\\PropertyInfo\\": "" }, diff --git a/src/Symfony/Component/Routing/CHANGELOG.md b/src/Symfony/Component/Routing/CHANGELOG.md index 570e09421ab60..c0685780955a3 100644 --- a/src/Symfony/Component/Routing/CHANGELOG.md +++ b/src/Symfony/Component/Routing/CHANGELOG.md @@ -6,6 +6,8 @@ CHANGELOG * Add FQCN and FQCN::method aliases for routes loaded from attributes/annotations when applicable * Add native return type to `AnnotationClassLoader::setResolver()` + * Deprecate Doctrine annotations support in favor of native attributes + * Change the constructor signature of `AnnotationClassLoader` to `__construct(?string $env = null)`, passing an annotation reader as first argument is deprecated 6.2 --- diff --git a/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php b/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php index ca12eb8399c82..9b64614ed1d01 100644 --- a/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php +++ b/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php @@ -26,33 +26,14 @@ * time, this method should define some PHP callable to be called for the route * (a controller in MVC speak). * - * The @Route annotation can be set on the class (for global parameters), + * The #[Route] attribute can be set on the class (for global parameters), * and on each method. * - * The @Route annotation main value is the route path. The annotation also + * The #[Route] attribute main value is the route path. The attribute also * recognizes several parameters: requirements, options, defaults, schemes, * methods, host, and name. The name parameter is mandatory. * Here is an example of how you should be able to use it: - * /** - * * @Route("/Blog") - * * / - * class Blog - * { - * /** - * * @Route("/", name="blog_index") - * * / - * public function index() - * { - * } - * /** - * * @Route("/{id}", name="blog_post", requirements = {"id" = "\d+"}) - * * / - * public function show() - * { - * } - * } * - * On PHP 8, the annotation class can be used as an attribute as well: * #[Route('/Blog')] * class Blog * { @@ -71,23 +52,55 @@ */ abstract class AnnotationClassLoader implements LoaderInterface { + /** + * @var Reader|null + * + * @deprecated in Symfony 6.4, this property will be removed in Symfony 7. + */ protected $reader; + + /** + * @var string|null + * + * @internal since Symfony 6.4, this property will be private in Symfony 7. + */ protected $env; /** * @var string + * + * @internal since Symfony 6.4, this property will be private in Symfony 7. */ protected $routeAnnotationClass = RouteAnnotation::class; /** * @var int + * + * @internal since Symfony 6.4, this property will be private in Symfony 7. */ protected $defaultRouteIndex = 0; - public function __construct(Reader $reader = null, string $env = null) + private bool $hasDeprecatedAnnotations = false; + + /** + * @param string|null $env + */ + public function __construct($env = null) { - $this->reader = $reader; - $this->env = $env; + if ($env instanceof Reader || null === $env && \func_num_args() > 1 && null !== func_get_arg(1)) { + trigger_deprecation('symfony/routing', '6.4', 'Passing an instance of "%s" as first and the environment as second argument to "%s" is deprecated. Pass the environment as first argument instead.', Reader::class, __METHOD__); + + $this->reader = $env; + $env = \func_num_args() > 1 ? func_get_arg(1) : null; + } + + if (\is_string($env) || null === $env) { + $this->env = $env; + } elseif ($env instanceof \Stringable || \is_scalar($env)) { + $this->env = (string) $env; + } else { + throw new \TypeError(__METHOD__.sprintf(': Parameter $env was expected to be a string or null, "%s" given.', get_debug_type($env))); + } } /** @@ -116,43 +129,48 @@ public function load(mixed $class, string $type = null): RouteCollection throw new \InvalidArgumentException(sprintf('Annotations from class "%s" cannot be read as it is abstract.', $class->getName())); } - $globals = $this->getGlobals($class); - - $collection = new RouteCollection(); - $collection->addResource(new FileResource($class->getFileName())); + $this->hasDeprecatedAnnotations = false; - if ($globals['env'] && $this->env !== $globals['env']) { - return $collection; - } + try { + $globals = $this->getGlobals($class); + $collection = new RouteCollection(); + $collection->addResource(new FileResource($class->getFileName())); + if ($globals['env'] && $this->env !== $globals['env']) { + return $collection; + } + $fqcnAlias = false; + foreach ($class->getMethods() as $method) { + $this->defaultRouteIndex = 0; + $routeNamesBefore = array_keys($collection->all()); + foreach ($this->getAnnotations($method) as $annot) { + $this->addRoute($collection, $annot, $globals, $class, $method); + if ('__invoke' === $method->name) { + $fqcnAlias = true; + } + } - $fqcnAlias = false; - foreach ($class->getMethods() as $method) { - $this->defaultRouteIndex = 0; - $routeNamesBefore = array_keys($collection->all()); - foreach ($this->getAnnotations($method) as $annot) { - $this->addRoute($collection, $annot, $globals, $class, $method); - if ('__invoke' === $method->name) { + if (1 === $collection->count() - \count($routeNamesBefore)) { + $newRouteName = current(array_diff(array_keys($collection->all()), $routeNamesBefore)); + $collection->addAlias(sprintf('%s::%s', $class->name, $method->name), $newRouteName); + } + } + if (0 === $collection->count() && $class->hasMethod('__invoke')) { + $globals = $this->resetGlobals(); + foreach ($this->getAnnotations($class) as $annot) { + $this->addRoute($collection, $annot, $globals, $class, $class->getMethod('__invoke')); $fqcnAlias = true; } } - - if (1 === $collection->count() - \count($routeNamesBefore)) { - $newRouteName = current(array_diff(array_keys($collection->all()), $routeNamesBefore)); - $collection->addAlias(sprintf('%s::%s', $class->name, $method->name), $newRouteName); + if ($fqcnAlias && 1 === $collection->count()) { + $collection->addAlias($class->name, $invokeRouteName = key($collection->all())); + $collection->addAlias(sprintf('%s::__invoke', $class->name), $invokeRouteName); } - } - if (0 === $collection->count() && $class->hasMethod('__invoke')) { - $globals = $this->resetGlobals(); - foreach ($this->getAnnotations($class) as $annot) { - $this->addRoute($collection, $annot, $globals, $class, $class->getMethod('__invoke')); - $fqcnAlias = true; + if ($this->hasDeprecatedAnnotations) { + trigger_deprecation('symfony/routing', '6.4', 'Class "%s" uses Doctrine Annotations to configure routes, which is deprecated. Use PHP attributes instead.', $class->getName()); } - } - - if ($fqcnAlias && 1 === $collection->count()) { - $collection->addAlias($class->name, $invokeRouteName = key($collection->all())); - $collection->addAlias(sprintf('%s::__invoke', $class->name), $invokeRouteName); + } finally { + $this->hasDeprecatedAnnotations = false; } return $collection; @@ -279,7 +297,7 @@ protected function getDefaultRouteName(\ReflectionClass $class, \ReflectionMetho } /** - * @return array + * @return array */ protected function getGlobals(\ReflectionClass $class) { @@ -289,8 +307,8 @@ protected function getGlobals(\ReflectionClass $class) if ($attribute = $class->getAttributes($this->routeAnnotationClass, \ReflectionAttribute::IS_INSTANCEOF)[0] ?? null) { $annot = $attribute->newInstance(); } - if (!$annot && $this->reader) { - $annot = $this->reader->getClassAnnotation($class, $this->routeAnnotationClass); + if (!$annot && $annot = $this->reader?->getClassAnnotation($class, $this->routeAnnotationClass)) { + $this->hasDeprecatedAnnotations = true; } if ($annot) { @@ -377,11 +395,9 @@ protected function createRoute(string $path, array $defaults, array $requirement abstract protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, object $annot); /** - * @param \ReflectionClass|\ReflectionMethod $reflection - * * @return iterable */ - private function getAnnotations(object $reflection): iterable + private function getAnnotations(\ReflectionClass|\ReflectionMethod $reflection): iterable { foreach ($reflection->getAttributes($this->routeAnnotationClass, \ReflectionAttribute::IS_INSTANCEOF) as $attribute) { yield $attribute->newInstance(); @@ -397,6 +413,8 @@ private function getAnnotations(object $reflection): iterable foreach ($annotations as $annotation) { if ($annotation instanceof $this->routeAnnotationClass) { + $this->hasDeprecatedAnnotations = true; + yield $annotation; } } diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/AnnotatedClasses/AbstractClass.php b/src/Symfony/Component/Routing/Tests/Fixtures/AnnotatedClasses/AbstractClass.php index bd7ea962c144c..c6de0161aac9b 100644 --- a/src/Symfony/Component/Routing/Tests/Fixtures/AnnotatedClasses/AbstractClass.php +++ b/src/Symfony/Component/Routing/Tests/Fixtures/AnnotatedClasses/AbstractClass.php @@ -11,10 +11,13 @@ namespace Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses; +use Symfony\Component\Routing\Annotation\Route; + abstract class AbstractClass { abstract public function abstractRouteAction(); + #[Route('/path/to/route/{arg1}')] public function routeAction($arg1, $arg2 = 'defaultValue2', $arg3 = 'defaultValue3') { } diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/OtherAnnotatedClasses/VariadicClass.php b/src/Symfony/Component/Routing/Tests/Fixtures/OtherAnnotatedClasses/VariadicClass.php index 729c9b4d07b38..01c14ed658294 100644 --- a/src/Symfony/Component/Routing/Tests/Fixtures/OtherAnnotatedClasses/VariadicClass.php +++ b/src/Symfony/Component/Routing/Tests/Fixtures/OtherAnnotatedClasses/VariadicClass.php @@ -11,8 +11,11 @@ namespace Symfony\Component\Routing\Tests\Fixtures\OtherAnnotatedClasses; +use Symfony\Component\Routing\Annotation\Route; + class VariadicClass { + #[Route('/path/to/{id}')] public function routeAction(...$params) { } diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/TraceableAnnotationClassLoader.php b/src/Symfony/Component/Routing/Tests/Fixtures/TraceableAnnotationClassLoader.php new file mode 100644 index 0000000000000..ebc37c840bb19 --- /dev/null +++ b/src/Symfony/Component/Routing/Tests/Fixtures/TraceableAnnotationClassLoader.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Tests\Fixtures; + +use Symfony\Component\Routing\Loader\AnnotationClassLoader; +use Symfony\Component\Routing\Route; +use Symfony\Component\Routing\RouteCollection; + +final class TraceableAnnotationClassLoader extends AnnotationClassLoader +{ + /** @var list */ + public array $foundClasses = []; + + public function load(mixed $class, string $type = null): RouteCollection + { + if (!is_string($class)) { + throw new \InvalidArgumentException(sprintf('Expected string, got "%s"', get_debug_type($class))); + } + + $this->foundClasses[] = $class; + + return parent::load($class, $type); + } + + protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, object $annot): void + { + } +} diff --git a/src/Symfony/Component/Routing/Tests/Loader/AbstractAnnotationLoaderTestCase.php b/src/Symfony/Component/Routing/Tests/Loader/AbstractAnnotationLoaderTestCase.php deleted file mode 100644 index e743ef2e35d50..0000000000000 --- a/src/Symfony/Component/Routing/Tests/Loader/AbstractAnnotationLoaderTestCase.php +++ /dev/null @@ -1,34 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Routing\Tests\Loader; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\Routing\Loader\AnnotationClassLoader; - -abstract class AbstractAnnotationLoaderTestCase extends TestCase -{ - public function getReader() - { - return $this->getMockBuilder(\Doctrine\Common\Annotations\Reader::class) - ->disableOriginalConstructor() - ->getMock() - ; - } - - public function getClassLoader($reader) - { - return $this->getMockBuilder(AnnotationClassLoader::class) - ->setConstructorArgs([$reader]) - ->getMockForAbstractClass() - ; - } -} diff --git a/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderTestCase.php b/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderTestCase.php index 75589835e48f9..f8e54d6a75da6 100644 --- a/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderTestCase.php +++ b/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderTestCase.php @@ -18,10 +18,7 @@ abstract class AnnotationClassLoaderTestCase extends TestCase { - /** - * @var AnnotationClassLoader - */ - protected $loader; + protected AnnotationClassLoader $loader; /** * @dataProvider provideTestSupportsChecksResource @@ -31,7 +28,7 @@ public function testSupportsChecksResource($resource, $expectedSupports) $this->assertSame($expectedSupports, $this->loader->supports($resource), '->supports() returns true if the resource is loadable'); } - public static function provideTestSupportsChecksResource() + public static function provideTestSupportsChecksResource(): array { return [ ['class', true], diff --git a/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderWithAnnotationsTest.php b/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderWithAnnotationsTest.php index 3988d4354a0d2..f53e4e3ef3baf 100644 --- a/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderWithAnnotationsTest.php +++ b/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderWithAnnotationsTest.php @@ -12,19 +12,17 @@ namespace Symfony\Component\Routing\Tests\Loader; use Doctrine\Common\Annotations\AnnotationReader; -use Symfony\Component\Routing\Loader\AnnotationClassLoader; -use Symfony\Component\Routing\Route; +use Symfony\Component\Routing\Tests\Fixtures\TraceableAnnotationClassLoader; +/** + * @group legacy + */ class AnnotationClassLoaderWithAnnotationsTest extends AnnotationClassLoaderTestCase { protected function setUp(string $env = null): void { $reader = new AnnotationReader(); - $this->loader = new class($reader, $env) extends AnnotationClassLoader { - protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, object $annot): void - { - } - }; + $this->loader = new TraceableAnnotationClassLoader($reader, $env); } public function testDefaultRouteName() diff --git a/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderWithAttributesTest.php b/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderWithAttributesTest.php index d613ba09b298b..2fe0f903189fd 100644 --- a/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderWithAttributesTest.php +++ b/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderWithAttributesTest.php @@ -11,18 +11,13 @@ namespace Symfony\Component\Routing\Tests\Loader; -use Symfony\Component\Routing\Loader\AnnotationClassLoader; -use Symfony\Component\Routing\Route; +use Symfony\Component\Routing\Tests\Fixtures\TraceableAnnotationClassLoader; class AnnotationClassLoaderWithAttributesTest extends AnnotationClassLoaderTestCase { protected function setUp(string $env = null): void { - $this->loader = new class(null, $env) extends AnnotationClassLoader { - protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, object $annot): void - { - } - }; + $this->loader = new TraceableAnnotationClassLoader($env); } public function testDefaultRouteName() diff --git a/src/Symfony/Component/Routing/Tests/Loader/AnnotationDirectoryLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/AnnotationDirectoryLoaderTest.php index 5a7bc8cbbda53..a7c7f957dfc36 100644 --- a/src/Symfony/Component/Routing/Tests/Loader/AnnotationDirectoryLoaderTest.php +++ b/src/Symfony/Component/Routing/Tests/Loader/AnnotationDirectoryLoaderTest.php @@ -11,63 +11,38 @@ namespace Symfony\Component\Routing\Tests\Loader; +use PHPUnit\Framework\TestCase; use Symfony\Component\Config\FileLocator; use Symfony\Component\Routing\Loader\AnnotationDirectoryLoader; +use Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass; +use Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BazClass; +use Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\EncodingClass; +use Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\FooClass; +use Symfony\Component\Routing\Tests\Fixtures\TraceableAnnotationClassLoader; -class AnnotationDirectoryLoaderTest extends AbstractAnnotationLoaderTestCase +class AnnotationDirectoryLoaderTest extends TestCase { - protected $loader; - protected $reader; + private AnnotationDirectoryLoader $loader; + private TraceableAnnotationClassLoader $classLoader; protected function setUp(): void { parent::setUp(); - $this->reader = $this->getReader(); - $this->loader = new AnnotationDirectoryLoader(new FileLocator(), $this->getClassLoader($this->reader)); + $this->classLoader = new TraceableAnnotationClassLoader(); + $this->loader = new AnnotationDirectoryLoader(new FileLocator(), $this->classLoader); } public function testLoad() { - $this->reader->expects($this->exactly(4))->method('getClassAnnotation'); - - $this->reader - ->expects($this->any()) - ->method('getMethodAnnotations') - ->willReturn([]) - ; - - $this->reader - ->expects($this->any()) - ->method('getClassAnnotations') - ->willReturn([]) - ; - $this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses'); - } - - public function testLoadIgnoresHiddenDirectories() - { - $this->expectAnnotationsToBeReadFrom([ - 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass', - 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BazClass', - 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\FooClass', - 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\EncodingClass', - ]); - - $this->reader - ->expects($this->any()) - ->method('getMethodAnnotations') - ->willReturn([]) - ; - - $this->reader - ->expects($this->any()) - ->method('getClassAnnotations') - ->willReturn([]) - ; - $this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses'); + self::assertSame([ + BarClass::class, + BazClass::class, + EncodingClass::class, + FooClass::class, + ], $this->classLoader->foundClasses); } public function testSupports() @@ -89,29 +64,13 @@ public function testItSupportsAnyAnnotation() public function testLoadFileIfLocatedResourceIsFile() { - $this->reader->expects($this->exactly(1))->method('getClassAnnotation'); - - $this->reader - ->expects($this->any()) - ->method('getMethodAnnotations') - ->willReturn([]) - ; - $this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses/FooClass.php'); + self::assertSame([FooClass::class], $this->classLoader->foundClasses); } public function testLoadAbstractClass() { - $this->reader->expects($this->never())->method('getClassAnnotation'); - $this->reader->expects($this->never())->method('getMethodAnnotations'); - - $this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses/AbstractClass.php'); - } - - private function expectAnnotationsToBeReadFrom(array $classes) - { - $this->reader->expects($this->exactly(\count($classes))) - ->method('getClassAnnotation') - ->with($this->callback(fn (\ReflectionClass $class) => \in_array($class->getName(), $classes))); + self::assertNull($this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses/AbstractClass.php')); + self::assertSame([], $this->classLoader->foundClasses); } } diff --git a/src/Symfony/Component/Routing/Tests/Loader/AnnotationFileLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/AnnotationFileLoaderTest.php index 473368156382f..d92760ae729cb 100644 --- a/src/Symfony/Component/Routing/Tests/Loader/AnnotationFileLoaderTest.php +++ b/src/Symfony/Component/Routing/Tests/Loader/AnnotationFileLoaderTest.php @@ -11,35 +11,45 @@ namespace Symfony\Component\Routing\Tests\Loader; +use Doctrine\Common\Annotations\AnnotationReader; +use PHPUnit\Framework\TestCase; use Symfony\Component\Config\FileLocator; -use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Loader\AnnotationFileLoader; - -class AnnotationFileLoaderTest extends AbstractAnnotationLoaderTestCase +use Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\FooClass; +use Symfony\Component\Routing\Tests\Fixtures\AttributesFixtures\AttributesClassParamAfterCommaController; +use Symfony\Component\Routing\Tests\Fixtures\AttributesFixtures\AttributesClassParamAfterParenthesisController; +use Symfony\Component\Routing\Tests\Fixtures\AttributesFixtures\AttributesClassParamInlineAfterCommaController; +use Symfony\Component\Routing\Tests\Fixtures\AttributesFixtures\AttributesClassParamInlineAfterParenthesisController; +use Symfony\Component\Routing\Tests\Fixtures\AttributesFixtures\AttributesClassParamInlineQuotedAfterCommaController; +use Symfony\Component\Routing\Tests\Fixtures\AttributesFixtures\AttributesClassParamInlineQuotedAfterParenthesisController; +use Symfony\Component\Routing\Tests\Fixtures\AttributesFixtures\AttributesClassParamQuotedAfterCommaController; +use Symfony\Component\Routing\Tests\Fixtures\AttributesFixtures\AttributesClassParamQuotedAfterParenthesisController; +use Symfony\Component\Routing\Tests\Fixtures\OtherAnnotatedClasses\VariadicClass; +use Symfony\Component\Routing\Tests\Fixtures\TraceableAnnotationClassLoader; + +class AnnotationFileLoaderTest extends TestCase { - protected $loader; - protected $reader; + private AnnotationFileLoader $loader; + private TraceableAnnotationClassLoader $classLoader; protected function setUp(): void { parent::setUp(); - $this->reader = $this->getReader(); - $this->loader = new AnnotationFileLoader(new FileLocator(), $this->getClassLoader($this->reader)); + $this->classLoader = new TraceableAnnotationClassLoader(); + $this->loader = new AnnotationFileLoader(new FileLocator(), $this->classLoader); } public function testLoad() { - $this->reader->expects($this->once())->method('getClassAnnotation'); - - $this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses/FooClass.php'); + self::assertCount(0, $this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses/FooClass.php')); + self::assertSame([FooClass::class], $this->classLoader->foundClasses); } public function testLoadTraitWithClassConstant() { - $this->reader->expects($this->never())->method('getClassAnnotation'); - - $this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses/FooTrait.php'); + self::assertCount(0, $this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses/FooTrait.php')); + self::assertSame([], $this->classLoader->foundClasses); } public function testLoadFileWithoutStartTag() @@ -51,28 +61,26 @@ public function testLoadFileWithoutStartTag() public function testLoadVariadic() { - $route = new Route('/path/to/{id}'); - $this->reader->expects($this->once())->method('getClassAnnotation'); - $this->reader->expects($this->once())->method('getMethodAnnotations') - ->willReturn([$route]); - - $this->loader->load(__DIR__.'/../Fixtures/OtherAnnotatedClasses/VariadicClass.php'); + self::assertCount(1, $this->loader->load(__DIR__.'/../Fixtures/OtherAnnotatedClasses/VariadicClass.php')); + self::assertSame([VariadicClass::class], $this->classLoader->foundClasses); } + /** + * @group legacy + */ public function testLoadAnonymousClass() { - $this->reader->expects($this->never())->method('getClassAnnotation'); - $this->reader->expects($this->never())->method('getMethodAnnotations'); + $this->classLoader = new TraceableAnnotationClassLoader(new AnnotationReader()); + $this->loader = new AnnotationFileLoader(new FileLocator(), $this->classLoader); - $this->loader->load(__DIR__.'/../Fixtures/OtherAnnotatedClasses/AnonymousClassInTrait.php'); + self::assertCount(0, $this->loader->load(__DIR__.'/../Fixtures/OtherAnnotatedClasses/AnonymousClassInTrait.php')); + self::assertSame([], $this->classLoader->foundClasses); } public function testLoadAbstractClass() { - $this->reader->expects($this->never())->method('getClassAnnotation'); - $this->reader->expects($this->never())->method('getMethodAnnotations'); - - $this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses/AbstractClass.php'); + self::assertNull($this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses/AbstractClass.php')); + self::assertSame([], $this->classLoader->foundClasses); } public function testSupports() @@ -89,57 +97,49 @@ public function testSupports() public function testLoadAttributesClassAfterComma() { - $this->reader->expects($this->once())->method('getClassAnnotation'); - - $this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamAfterCommaController.php'); + self::assertCount(0, $this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamAfterCommaController.php')); + self::assertSame([AttributesClassParamAfterCommaController::class], $this->classLoader->foundClasses); } public function testLoadAttributesInlineClassAfterComma() { - $this->reader->expects($this->once())->method('getClassAnnotation'); - - $this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamInlineAfterCommaController.php'); + self::assertCount(0, $this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamInlineAfterCommaController.php')); + self::assertSame([AttributesClassParamInlineAfterCommaController::class], $this->classLoader->foundClasses); } public function testLoadAttributesQuotedClassAfterComma() { - $this->reader->expects($this->once())->method('getClassAnnotation'); - - $this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamQuotedAfterCommaController.php'); + self::assertCount(0, $this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamQuotedAfterCommaController.php')); + self::assertSame([AttributesClassParamQuotedAfterCommaController::class], $this->classLoader->foundClasses); } public function testLoadAttributesInlineQuotedClassAfterComma() { - $this->reader->expects($this->once())->method('getClassAnnotation'); - - $this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamInlineQuotedAfterCommaController.php'); + self::assertCount(0, $this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamInlineQuotedAfterCommaController.php')); + self::assertSame([AttributesClassParamInlineQuotedAfterCommaController::class], $this->classLoader->foundClasses); } public function testLoadAttributesClassAfterParenthesis() { - $this->reader->expects($this->once())->method('getClassAnnotation'); - - $this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamAfterParenthesisController.php'); + self::assertCount(0, $this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamAfterParenthesisController.php')); + self::assertSame([AttributesClassParamAfterParenthesisController::class], $this->classLoader->foundClasses); } public function testLoadAttributesInlineClassAfterParenthesis() { - $this->reader->expects($this->once())->method('getClassAnnotation'); - - $this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamInlineAfterParenthesisController.php'); + self::assertCount(0, $this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamInlineAfterParenthesisController.php')); + self::assertSame([AttributesClassParamInlineAfterParenthesisController::class], $this->classLoader->foundClasses); } public function testLoadAttributesQuotedClassAfterParenthesis() { - $this->reader->expects($this->once())->method('getClassAnnotation'); - - $this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamQuotedAfterParenthesisController.php'); + self::assertCount(0, $this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamQuotedAfterParenthesisController.php')); + self::assertSame([AttributesClassParamQuotedAfterParenthesisController::class], $this->classLoader->foundClasses); } public function testLoadAttributesInlineQuotedClassAfterParenthesis() { - $this->reader->expects($this->once())->method('getClassAnnotation'); - - $this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamInlineQuotedAfterParenthesisController.php'); + self::assertCount(0, $this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamInlineQuotedAfterParenthesisController.php')); + self::assertSame([AttributesClassParamInlineQuotedAfterParenthesisController::class], $this->classLoader->foundClasses); } } diff --git a/src/Symfony/Component/Routing/Tests/Loader/DirectoryLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/DirectoryLoaderTest.php index d4f2fd3263b48..b78874195cc8e 100644 --- a/src/Symfony/Component/Routing/Tests/Loader/DirectoryLoaderTest.php +++ b/src/Symfony/Component/Routing/Tests/Loader/DirectoryLoaderTest.php @@ -11,28 +11,28 @@ namespace Symfony\Component\Routing\Tests\Loader; +use PHPUnit\Framework\TestCase; use Symfony\Component\Config\FileLocator; use Symfony\Component\Config\Loader\LoaderResolver; use Symfony\Component\Routing\Loader\AnnotationFileLoader; use Symfony\Component\Routing\Loader\DirectoryLoader; use Symfony\Component\Routing\Loader\YamlFileLoader; use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\Routing\Tests\Fixtures\TraceableAnnotationClassLoader; -class DirectoryLoaderTest extends AbstractAnnotationLoaderTestCase +class DirectoryLoaderTest extends TestCase { - private $loader; - private $reader; + private DirectoryLoader $loader; protected function setUp(): void { parent::setUp(); $locator = new FileLocator(); - $this->reader = $this->getReader(); $this->loader = new DirectoryLoader($locator); $resolver = new LoaderResolver([ new YamlFileLoader($locator), - new AnnotationFileLoader($locator, $this->getClassLoader($this->reader)), + new AnnotationFileLoader($locator, new TraceableAnnotationClassLoader()), $this->loader, ]); $this->loader->setResolver($resolver); diff --git a/src/Symfony/Component/Serializer/CHANGELOG.md b/src/Symfony/Component/Serializer/CHANGELOG.md index 8154d3688fce8..4ab3defddc1bb 100644 --- a/src/Symfony/Component/Serializer/CHANGELOG.md +++ b/src/Symfony/Component/Serializer/CHANGELOG.md @@ -1,6 +1,12 @@ CHANGELOG ========= +6.4 +--- + + * Deprecate Doctrine annotations support in favor of native attributes + * Deprecate passing an annotation reader to the constructor of `AnnotationLoader` + 6.3 --- diff --git a/src/Symfony/Component/Serializer/Mapping/Loader/AnnotationLoader.php b/src/Symfony/Component/Serializer/Mapping/Loader/AnnotationLoader.php index 6d03511cf57e2..94d0f45dcb1f7 100644 --- a/src/Symfony/Component/Serializer/Mapping/Loader/AnnotationLoader.php +++ b/src/Symfony/Component/Serializer/Mapping/Loader/AnnotationLoader.php @@ -46,6 +46,9 @@ class AnnotationLoader implements LoaderInterface public function __construct( private readonly ?Reader $reader = null, ) { + if ($reader) { + trigger_deprecation('symfony/validator', '6.4', 'Passing a "%s" instance as argument 1 to "%s()" is deprecated, pass null or omit the parameter instead.', get_debug_type($reader), __METHOD__); + } } public function loadClassMetadata(ClassMetadataInterface $classMetadata): bool @@ -163,10 +166,7 @@ public function loadClassMetadata(ClassMetadataInterface $classMetadata): bool return $loaded; } - /** - * @param \ReflectionClass|\ReflectionMethod|\ReflectionProperty $reflector - */ - public function loadAnnotations(object $reflector): iterable + public function loadAnnotations(\ReflectionMethod|\ReflectionClass|\ReflectionProperty $reflector): iterable { foreach ($reflector->getAttributes() as $attribute) { if ($this->isKnownAttribute($attribute->getName())) { @@ -193,13 +193,13 @@ public function loadAnnotations(object $reflector): iterable } if ($reflector instanceof \ReflectionClass) { - yield from $this->reader->getClassAnnotations($reflector); + yield from $this->getClassAnnotations($reflector); } if ($reflector instanceof \ReflectionMethod) { - yield from $this->reader->getMethodAnnotations($reflector); + yield from $this->getMethodAnnotations($reflector); } if ($reflector instanceof \ReflectionProperty) { - yield from $this->reader->getPropertyAnnotations($reflector); + yield from $this->getPropertyAnnotations($reflector); } } @@ -229,4 +229,49 @@ private function isKnownAttribute(string $attributeName): bool return false; } + + /** + * @return object[] + */ + private function getClassAnnotations(\ReflectionClass $reflector): array + { + if ($annotations = array_filter( + $this->reader->getClassAnnotations($reflector), + fn (object $annotation): bool => $this->isKnownAttribute($annotation::class), + )) { + trigger_deprecation('symfony/serializer', '6.4', 'Class "%s" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.', $reflector->getName()); + } + + return $annotations; + } + + /** + * @return object[] + */ + private function getMethodAnnotations(\ReflectionMethod $reflector): array + { + if ($annotations = array_filter( + $this->reader->getMethodAnnotations($reflector), + fn (object $annotation): bool => $this->isKnownAttribute($annotation::class), + )) { + trigger_deprecation('symfony/serializer', '6.4', 'Method "%s::%s()" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.', $reflector->getDeclaringClass()->getName(), $reflector->getName()); + } + + return $annotations; + } + + /** + * @return object[] + */ + private function getPropertyAnnotations(\ReflectionProperty $reflector): array + { + if ($annotations = array_filter( + $this->reader->getPropertyAnnotations($reflector), + fn (object $annotation): bool => $this->isKnownAttribute($annotation::class), + )) { + trigger_deprecation('symfony/serializer', '6.4', 'Property "%s::$%s" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.', $reflector->getDeclaringClass()->getName(), $reflector->getName()); + } + + return $annotations; + } } diff --git a/src/Symfony/Component/Serializer/Tests/Fixtures/Annotations/GroupDummy.php b/src/Symfony/Component/Serializer/Tests/Fixtures/Annotations/GroupDummy.php index 36a63e6f816c8..92935f49095ae 100644 --- a/src/Symfony/Component/Serializer/Tests/Fixtures/Annotations/GroupDummy.php +++ b/src/Symfony/Component/Serializer/Tests/Fixtures/Annotations/GroupDummy.php @@ -13,7 +13,7 @@ use Symfony\Component\Serializer\Annotation\Groups; use Symfony\Component\Serializer\Tests\Fixtures\ChildOfGroupsAnnotationDummy; -use Symfony\Component\Serializer\Tests\Fixtures\GroupDummyInterface; +use Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummyInterface; /** * @author Kévin Dunglas diff --git a/src/Symfony/Component/Serializer/Tests/Fixtures/GroupDummyInterface.php b/src/Symfony/Component/Serializer/Tests/Fixtures/Annotations/GroupDummyInterface.php similarity index 87% rename from src/Symfony/Component/Serializer/Tests/Fixtures/GroupDummyInterface.php rename to src/Symfony/Component/Serializer/Tests/Fixtures/Annotations/GroupDummyInterface.php index a60629e6dd509..c9a736bfa0b2e 100644 --- a/src/Symfony/Component/Serializer/Tests/Fixtures/GroupDummyInterface.php +++ b/src/Symfony/Component/Serializer/Tests/Fixtures/Annotations/GroupDummyInterface.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Symfony\Component\Serializer\Tests\Fixtures; +namespace Symfony\Component\Serializer\Tests\Fixtures\Annotations; use Symfony\Component\Serializer\Annotation\Groups; diff --git a/src/Symfony/Component/Serializer/Tests/Fixtures/Attributes/GroupDummy.php b/src/Symfony/Component/Serializer/Tests/Fixtures/Attributes/GroupDummy.php index 1cb2026d9161f..c0a6c6d8eabe6 100644 --- a/src/Symfony/Component/Serializer/Tests/Fixtures/Attributes/GroupDummy.php +++ b/src/Symfony/Component/Serializer/Tests/Fixtures/Attributes/GroupDummy.php @@ -13,7 +13,6 @@ use Symfony\Component\Serializer\Annotation\Groups; use Symfony\Component\Serializer\Tests\Fixtures\ChildOfGroupsAnnotationDummy; -use Symfony\Component\Serializer\Tests\Fixtures\GroupDummyInterface; /** * @author Kévin Dunglas diff --git a/src/Symfony/Component/Serializer/Tests/Fixtures/Annotations/GroupDummyChild.php b/src/Symfony/Component/Serializer/Tests/Fixtures/Attributes/GroupDummyChild.php similarity index 87% rename from src/Symfony/Component/Serializer/Tests/Fixtures/Annotations/GroupDummyChild.php rename to src/Symfony/Component/Serializer/Tests/Fixtures/Attributes/GroupDummyChild.php index 7e40818739cc4..7167a0b1836c8 100644 --- a/src/Symfony/Component/Serializer/Tests/Fixtures/Annotations/GroupDummyChild.php +++ b/src/Symfony/Component/Serializer/Tests/Fixtures/Attributes/GroupDummyChild.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Symfony\Component\Serializer\Tests\Fixtures\Annotations; +namespace Symfony\Component\Serializer\Tests\Fixtures\Attributes; class GroupDummyChild extends GroupDummy { diff --git a/src/Symfony/Component/Serializer/Tests/Fixtures/Attributes/GroupDummyInterface.php b/src/Symfony/Component/Serializer/Tests/Fixtures/Attributes/GroupDummyInterface.php new file mode 100644 index 0000000000000..7920173ae2b65 --- /dev/null +++ b/src/Symfony/Component/Serializer/Tests/Fixtures/Attributes/GroupDummyInterface.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Tests\Fixtures\Attributes; + +use Symfony\Component\Serializer\Annotation\Groups; + +/** + * @author Kévin Dunglas + */ +interface GroupDummyInterface +{ + #[Groups(['a', 'name_converter'])] + public function getSymfony(); +} diff --git a/src/Symfony/Component/Serializer/Tests/Fixtures/DummyMessageInterface.php b/src/Symfony/Component/Serializer/Tests/Fixtures/DummyMessageInterface.php index 55bb00bc8e253..8f7589085b448 100644 --- a/src/Symfony/Component/Serializer/Tests/Fixtures/DummyMessageInterface.php +++ b/src/Symfony/Component/Serializer/Tests/Fixtures/DummyMessageInterface.php @@ -14,13 +14,12 @@ use Symfony\Component\Serializer\Annotation\DiscriminatorMap; /** - * @DiscriminatorMap(typeProperty="type", mapping={ - * "one"="Symfony\Component\Serializer\Tests\Fixtures\DummyMessageNumberOne", - * "two"="Symfony\Component\Serializer\Tests\Fixtures\DummyMessageNumberTwo" - * }) - * * @author Samuel Roze */ +#[DiscriminatorMap(typeProperty: 'type', mapping: [ + 'one' => DummyMessageNumberOne::class, + 'two' => DummyMessageNumberTwo::class, +])] interface DummyMessageInterface { } diff --git a/src/Symfony/Component/Serializer/Tests/Fixtures/DummyMessageNumberOne.php b/src/Symfony/Component/Serializer/Tests/Fixtures/DummyMessageNumberOne.php index 200476b54232d..663961b3fd145 100644 --- a/src/Symfony/Component/Serializer/Tests/Fixtures/DummyMessageNumberOne.php +++ b/src/Symfony/Component/Serializer/Tests/Fixtures/DummyMessageNumberOne.php @@ -20,8 +20,6 @@ class DummyMessageNumberOne implements DummyMessageInterface { public $one; - /** - * @Groups({"two"}) - */ + #[Groups(['two'])] public $two; } diff --git a/src/Symfony/Component/Serializer/Tests/Fixtures/OtherSerializedNameDummy.php b/src/Symfony/Component/Serializer/Tests/Fixtures/OtherSerializedNameDummy.php index 1ac543ca69d76..58c5628e69d6c 100644 --- a/src/Symfony/Component/Serializer/Tests/Fixtures/OtherSerializedNameDummy.php +++ b/src/Symfony/Component/Serializer/Tests/Fixtures/OtherSerializedNameDummy.php @@ -19,9 +19,7 @@ */ class OtherSerializedNameDummy { - /** - * @Groups({"a"}) - */ + #[Groups(['a'])] private $buz; public function setBuz($buz) @@ -34,10 +32,7 @@ public function getBuz() return $this->buz; } - /** - * @Groups({"b"}) - * @SerializedName("buz") - */ + #[Groups(['b']), SerializedName('buz')] public function getBuzForExport() { return $this->buz.' Rocks'; diff --git a/src/Symfony/Component/Serializer/Tests/Fixtures/invalid-ignore.yml b/src/Symfony/Component/Serializer/Tests/Fixtures/invalid-ignore.yml index 00aa0fa962aae..f81636cc551f3 100644 --- a/src/Symfony/Component/Serializer/Tests/Fixtures/invalid-ignore.yml +++ b/src/Symfony/Component/Serializer/Tests/Fixtures/invalid-ignore.yml @@ -1,4 +1,4 @@ -'Symfony\Component\Serializer\Tests\Fixtures\Annotations\IgnoreDummy': +'Symfony\Component\Serializer\Tests\Fixtures\Attributes\IgnoreDummy': attributes: ignored1: ignore: foo diff --git a/src/Symfony/Component/Serializer/Tests/Fixtures/serialization.xml b/src/Symfony/Component/Serializer/Tests/Fixtures/serialization.xml index 5ca6ac412fc07..512736db4bbe4 100644 --- a/src/Symfony/Component/Serializer/Tests/Fixtures/serialization.xml +++ b/src/Symfony/Component/Serializer/Tests/Fixtures/serialization.xml @@ -4,7 +4,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/serializer-mapping https://symfony.com/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd"> - + group1 group2 @@ -15,41 +15,41 @@ - + - + - + - + - + - - + + - + - + dummy_parent_value @@ -62,7 +62,7 @@ - + value diff --git a/src/Symfony/Component/Serializer/Tests/Fixtures/serialization.yml b/src/Symfony/Component/Serializer/Tests/Fixtures/serialization.yml index e052d65a88779..4371016e34be3 100644 --- a/src/Symfony/Component/Serializer/Tests/Fixtures/serialization.yml +++ b/src/Symfony/Component/Serializer/Tests/Fixtures/serialization.yml @@ -1,47 +1,47 @@ -'Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy': +'Symfony\Component\Serializer\Tests\Fixtures\Attributes\GroupDummy': attributes: foo: groups: ['group1', 'group2'] bar: groups: ['group2'] -'Symfony\Component\Serializer\Tests\Fixtures\Annotations\MaxDepthDummy': +'Symfony\Component\Serializer\Tests\Fixtures\Attributes\MaxDepthDummy': attributes: foo: max_depth: 2 bar: max_depth: 3 -'Symfony\Component\Serializer\Tests\Fixtures\Annotations\SerializedNameDummy': +'Symfony\Component\Serializer\Tests\Fixtures\Attributes\SerializedNameDummy': attributes: foo: serialized_name: 'baz' bar: serialized_name: 'qux' -'Symfony\Component\Serializer\Tests\Fixtures\Annotations\SerializedPathDummy': +'Symfony\Component\Serializer\Tests\Fixtures\Attributes\SerializedPathDummy': attributes: three: serialized_path: '[one][two]' seven: serialized_path: '[three][four]' -'Symfony\Component\Serializer\Tests\Fixtures\Annotations\SerializedPathInConstructorDummy': +'Symfony\Component\Serializer\Tests\Fixtures\Attributes\SerializedPathInConstructorDummy': attributes: three: serialized_path: '[one][two]' -'Symfony\Component\Serializer\Tests\Fixtures\Annotations\AbstractDummy': +'Symfony\Component\Serializer\Tests\Fixtures\Attributes\AbstractDummy': discriminator_map: type_property: type mapping: - first: 'Symfony\Component\Serializer\Tests\Fixtures\Annotations\AbstractDummyFirstChild' - second: 'Symfony\Component\Serializer\Tests\Fixtures\Annotations\AbstractDummySecondChild' + first: 'Symfony\Component\Serializer\Tests\Fixtures\Attributes\AbstractDummyFirstChild' + second: 'Symfony\Component\Serializer\Tests\Fixtures\Attributes\AbstractDummySecondChild' attributes: foo: ~ -'Symfony\Component\Serializer\Tests\Fixtures\Annotations\IgnoreDummy': +'Symfony\Component\Serializer\Tests\Fixtures\Attributes\IgnoreDummy': attributes: ignored1: ignore: true ignored2: ignore: true -Symfony\Component\Serializer\Tests\Fixtures\Annotations\ContextDummyParent: +Symfony\Component\Serializer\Tests\Fixtures\Attributes\ContextDummyParent: attributes: parentProperty: contexts: @@ -50,7 +50,7 @@ Symfony\Component\Serializer\Tests\Fixtures\Annotations\ContextDummyParent: contexts: - { normalization_context: { prop: dummy_parent_value } } -Symfony\Component\Serializer\Tests\Fixtures\Annotations\ContextDummy: +Symfony\Component\Serializer\Tests\Fixtures\Attributes\ContextDummy: attributes: foo: contexts: diff --git a/src/Symfony/Component/Serializer/Tests/Mapping/ClassDiscriminatorMappingTest.php b/src/Symfony/Component/Serializer/Tests/Mapping/ClassDiscriminatorMappingTest.php index 4dcd64ecaee91..a8c736b8cda96 100644 --- a/src/Symfony/Component/Serializer/Tests/Mapping/ClassDiscriminatorMappingTest.php +++ b/src/Symfony/Component/Serializer/Tests/Mapping/ClassDiscriminatorMappingTest.php @@ -13,9 +13,9 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Serializer\Mapping\ClassDiscriminatorMapping; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\AbstractDummyFirstChild; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\AbstractDummySecondChild; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\AbstractDummyThirdChild; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\AbstractDummyFirstChild; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\AbstractDummySecondChild; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\AbstractDummyThirdChild; /** * @author Samuel Roze diff --git a/src/Symfony/Component/Serializer/Tests/Mapping/Factory/ClassMetadataFactoryCompilerTest.php b/src/Symfony/Component/Serializer/Tests/Mapping/Factory/ClassMetadataFactoryCompilerTest.php index 903612c684c0d..fc61b3752341c 100644 --- a/src/Symfony/Component/Serializer/Tests/Mapping/Factory/ClassMetadataFactoryCompilerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Mapping/Factory/ClassMetadataFactoryCompilerTest.php @@ -11,23 +11,19 @@ namespace Symfony\Component\Serializer\Tests\Mapping\Factory; -use Doctrine\Common\Annotations\AnnotationReader; use PHPUnit\Framework\TestCase; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryCompiler; use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\MaxDepthDummy; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\SerializedNameDummy; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\SerializedPathDummy; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\SerializedPathInConstructorDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\MaxDepthDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\SerializedNameDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\SerializedPathDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\SerializedPathInConstructorDummy; use Symfony\Component\Serializer\Tests\Fixtures\Dummy; final class ClassMetadataFactoryCompilerTest extends TestCase { - /** - * @var string - */ - private $dumpPath; + private string $dumpPath; protected function setUp(): void { @@ -41,7 +37,7 @@ protected function tearDown(): void public function testItDumpMetadata() { - $classMetatadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetatadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $dummyMetadata = $classMetatadataFactory->getMetadataFor(Dummy::class); $maxDepthDummyMetadata = $classMetatadataFactory->getMetadataFor(MaxDepthDummy::class); diff --git a/src/Symfony/Component/Serializer/Tests/Mapping/Factory/ClassMetadataFactoryTest.php b/src/Symfony/Component/Serializer/Tests/Mapping/Factory/ClassMetadataFactoryTest.php index bef034a8f83c1..d034a06c64f01 100644 --- a/src/Symfony/Component/Serializer/Tests/Mapping/Factory/ClassMetadataFactoryTest.php +++ b/src/Symfony/Component/Serializer/Tests/Mapping/Factory/ClassMetadataFactoryTest.php @@ -11,12 +11,14 @@ namespace Symfony\Component\Serializer\Tests\Mapping\Factory; -use Doctrine\Common\Annotations\AnnotationReader; use PHPUnit\Framework\TestCase; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface; use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; use Symfony\Component\Serializer\Mapping\Loader\LoaderChain; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\GroupDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\GroupDummyInterface; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\GroupDummyParent; use Symfony\Component\Serializer\Tests\Mapping\TestClassMetadataFactory; /** @@ -32,18 +34,18 @@ public function testInterface() public function testGetMetadataFor() { - $factory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); - $classMetadata = $factory->getMetadataFor('Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy'); + $factory = new ClassMetadataFactory(new AnnotationLoader()); + $classMetadata = $factory->getMetadataFor(GroupDummy::class); - $this->assertEquals(TestClassMetadataFactory::createClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\Annotations', true, true), $classMetadata); + $this->assertEquals(TestClassMetadataFactory::createClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\Attributes', true, true), $classMetadata); } public function testHasMetadataFor() { - $factory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); - $this->assertTrue($factory->hasMetadataFor('Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy')); - $this->assertTrue($factory->hasMetadataFor('Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummyParent')); - $this->assertTrue($factory->hasMetadataFor('Symfony\Component\Serializer\Tests\Fixtures\GroupDummyInterface')); + $factory = new ClassMetadataFactory(new AnnotationLoader()); + $this->assertTrue($factory->hasMetadataFor(GroupDummy::class)); + $this->assertTrue($factory->hasMetadataFor(GroupDummyParent::class)); + $this->assertTrue($factory->hasMetadataFor(GroupDummyInterface::class)); $this->assertFalse($factory->hasMetadataFor('Dunglas\Entity')); } } diff --git a/src/Symfony/Component/Serializer/Tests/Mapping/Factory/CompiledClassMetadataFactoryTest.php b/src/Symfony/Component/Serializer/Tests/Mapping/Factory/CompiledClassMetadataFactoryTest.php index d82431a8adec3..683f445dfe2b0 100644 --- a/src/Symfony/Component/Serializer/Tests/Mapping/Factory/CompiledClassMetadataFactoryTest.php +++ b/src/Symfony/Component/Serializer/Tests/Mapping/Factory/CompiledClassMetadataFactoryTest.php @@ -16,7 +16,7 @@ use Symfony\Component\Serializer\Mapping\ClassMetadata; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface; use Symfony\Component\Serializer\Mapping\Factory\CompiledClassMetadataFactory; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\SerializedNameDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\SerializedNameDummy; use Symfony\Component\Serializer\Tests\Fixtures\Dummy; /** diff --git a/src/Symfony/Component/Serializer/Tests/Mapping/Loader/AnnotationLoaderTestCase.php b/src/Symfony/Component/Serializer/Tests/Mapping/Loader/AnnotationLoaderTestCase.php index 2dbd03703a2ce..40d5e3cfee5de 100644 --- a/src/Symfony/Component/Serializer/Tests/Mapping/Loader/AnnotationLoaderTestCase.php +++ b/src/Symfony/Component/Serializer/Tests/Mapping/Loader/AnnotationLoaderTestCase.php @@ -172,7 +172,7 @@ public function testCanHandleUnrelatedIgnoredMethods() $loader->loadClassMetadata($metadata); } - public function testIgnoreGetterWirhRequiredParameterIfIgnoreAnnotationIsUsed() + public function testIgnoreGetterWithRequiredParameterIfIgnoreAnnotationIsUsed() { $classMetadata = new ClassMetadata($this->getNamespace().'\IgnoreDummyAdditionalGetter'); $this->getLoaderForContextMapping()->loadClassMetadata($classMetadata); @@ -182,7 +182,7 @@ public function testIgnoreGetterWirhRequiredParameterIfIgnoreAnnotationIsUsed() self::assertArrayHasKey('extraValue2', $attributes); } - public function testIgnoreGetterWirhRequiredParameterIfIgnoreAnnotationIsNotUsed() + public function testIgnoreGetterWithRequiredParameterIfIgnoreAnnotationIsNotUsed() { $classMetadata = new ClassMetadata($this->getNamespace().'\IgnoreDummyAdditionalGetterWithoutIgnoreAnnotations'); $this->getLoaderForContextMapping()->loadClassMetadata($classMetadata); diff --git a/src/Symfony/Component/Serializer/Tests/Mapping/Loader/AnnotationLoaderWithDoctrineAnnotationsTest.php b/src/Symfony/Component/Serializer/Tests/Mapping/Loader/AnnotationLoaderWithDoctrineAnnotationsTest.php index cfb1547c503cd..e055e52d700e6 100644 --- a/src/Symfony/Component/Serializer/Tests/Mapping/Loader/AnnotationLoaderWithDoctrineAnnotationsTest.php +++ b/src/Symfony/Component/Serializer/Tests/Mapping/Loader/AnnotationLoaderWithDoctrineAnnotationsTest.php @@ -12,10 +12,207 @@ namespace Symfony\Component\Serializer\Tests\Mapping\Loader; use Doctrine\Common\Annotations\AnnotationReader; +use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; class AnnotationLoaderWithDoctrineAnnotationsTest extends AnnotationLoaderTestCase { + use ExpectDeprecationTrait; + + protected function setUp(): void + { + $this->expectDeprecation('Since symfony/validator 6.4: Passing a "Doctrine\Common\Annotations\AnnotationReader" instance as argument 1 to "Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader::__construct()" is deprecated, pass null or omit the parameter instead.'); + + parent::setUp(); + } + + /** + * @group legacy + */ + public function testInterface() + { + parent::testInterface(); + } + + /** + * @group legacy + */ + public function testLoadClassMetadataReturnsTrueIfSuccessful() + { + $this->expectDeprecation('Since symfony/serializer 6.4: Property "Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy::$foo" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Property "Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy::$bar" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Property "Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy::$quux" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Method "Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy::setBar()" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Method "Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy::getBar()" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Method "Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy::isFooBar()" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + + parent::testLoadClassMetadataReturnsTrueIfSuccessful(); + } + + /** + * @group legacy + */ + public function testLoadGroups() + { + $this->expectDeprecation('Since symfony/serializer 6.4: Property "Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy::$foo" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Property "Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy::$bar" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Property "Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy::$quux" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Method "Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy::setBar()" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Method "Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy::getBar()" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Method "Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy::isFooBar()" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + + parent::testLoadGroups(); + } + + /** + * @group legacy + */ + public function testLoadDiscriminatorMap() + { + $this->expectDeprecation('Since symfony/serializer 6.4: Class "Symfony\Component\Serializer\Tests\Fixtures\Annotations\AbstractDummy" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + + parent::testLoadDiscriminatorMap(); + } + + /** + * @group legacy + */ + public function testLoadMaxDepth() + { + $this->expectDeprecation('Since symfony/serializer 6.4: Property "Symfony\Component\Serializer\Tests\Fixtures\Annotations\MaxDepthDummy::$foo" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Method "Symfony\Component\Serializer\Tests\Fixtures\Annotations\MaxDepthDummy::getBar()" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + + parent::testLoadMaxDepth(); + } + + /** + * @group legacy + */ + public function testLoadSerializedName() + { + $this->expectDeprecation('Since symfony/serializer 6.4: Property "Symfony\Component\Serializer\Tests\Fixtures\Annotations\SerializedNameDummy::$foo" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Method "Symfony\Component\Serializer\Tests\Fixtures\Annotations\SerializedNameDummy::getBar()" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + + parent::testLoadSerializedName(); + } + + /** + * @group legacy + */ + public function testLoadSerializedPath() + { + $this->expectDeprecation('Since symfony/serializer 6.4: Property "Symfony\Component\Serializer\Tests\Fixtures\Annotations\SerializedPathDummy::$three" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Method "Symfony\Component\Serializer\Tests\Fixtures\Annotations\SerializedPathDummy::getSeven()" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + + parent::testLoadSerializedPath(); + } + + /** + * @group legacy + */ + public function testLoadSerializedPathInConstructor() + { + $this->expectDeprecation('Since symfony/serializer 6.4: Property "Symfony\Component\Serializer\Tests\Fixtures\Annotations\SerializedPathInConstructorDummy::$three" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + + parent::testLoadSerializedPathInConstructor(); + } + + /** + * @group legacy + */ + public function testLoadClassMetadataAndMerge() + { + $this->expectDeprecation('Since symfony/serializer 6.4: Property "Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummyParent::$kevin" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Method "Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummyParent::getCoopTilleuls()" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Property "Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy::$foo" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Property "Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy::$bar" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Property "Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy::$quux" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Method "Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy::setBar()" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Method "Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy::getBar()" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Method "Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy::isFooBar()" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + + parent::testLoadClassMetadataAndMerge(); + } + + /** + * @group legacy + */ + public function testLoadIgnore() + { + $this->expectDeprecation('Since symfony/serializer 6.4: Property "Symfony\Component\Serializer\Tests\Fixtures\Annotations\IgnoreDummy::$ignored1" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Method "Symfony\Component\Serializer\Tests\Fixtures\Annotations\IgnoreDummy::getIgnored2()" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + + parent::testLoadIgnore(); + } + + /** + * @group legacy + */ + public function testLoadContexts() + { + $this->expectDeprecation('Since symfony/serializer 6.4: Property "Symfony\Component\Serializer\Tests\Fixtures\Annotations\ContextDummyParent::$parentProperty" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Property "Symfony\Component\Serializer\Tests\Fixtures\Annotations\ContextDummyParent::$overriddenParentProperty" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Property "Symfony\Component\Serializer\Tests\Fixtures\Annotations\ContextDummy::$foo" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Property "Symfony\Component\Serializer\Tests\Fixtures\Annotations\ContextDummy::$bar" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Property "Symfony\Component\Serializer\Tests\Fixtures\Annotations\ContextDummy::$overriddenParentProperty" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Method "Symfony\Component\Serializer\Tests\Fixtures\Annotations\ContextDummy::getMethodWithContext()" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + + parent::testLoadContexts(); + } + + /** + * @group legacy + */ + public function testLoadContextsPropertiesPromoted() + { + $this->expectDeprecation('Since symfony/serializer 6.4: Property "Symfony\Component\Serializer\Tests\Fixtures\Annotations\ContextDummyParent::$parentProperty" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Property "Symfony\Component\Serializer\Tests\Fixtures\Annotations\ContextDummyParent::$overriddenParentProperty" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Property "Symfony\Component\Serializer\Tests\Fixtures\Annotations\ContextDummyPromotedProperties::$foo" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Property "Symfony\Component\Serializer\Tests\Fixtures\Annotations\ContextDummyPromotedProperties::$bar" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Property "Symfony\Component\Serializer\Tests\Fixtures\Annotations\ContextDummyPromotedProperties::$overriddenParentProperty" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/serializer 6.4: Method "Symfony\Component\Serializer\Tests\Fixtures\Annotations\ContextDummyPromotedProperties::getMethodWithContext()" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + + parent::testLoadContextsPropertiesPromoted(); + } + + /** + * @group legacy + */ + public function testThrowsOnContextOnInvalidMethod() + { + $this->expectDeprecation('Since symfony/serializer 6.4: Method "Symfony\Component\Serializer\Tests\Fixtures\Annotations\BadMethodContextDummy::badMethod()" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + + parent::testThrowsOnContextOnInvalidMethod(); + } + + /** + * @group legacy + */ + public function testCanHandleUnrelatedIgnoredMethods() + { + $this->expectDeprecation('Since symfony/serializer 6.4: Method "Symfony\Component\Serializer\Tests\Fixtures\Annotations\Entity45016::badIgnore()" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + + parent::testCanHandleUnrelatedIgnoredMethods(); + } + + /** + * @group legacy + */ + public function testIgnoreGetterWithRequiredParameterIfIgnoreAnnotationIsUsed() + { + $this->expectDeprecation('Since symfony/serializer 6.4: Method "Symfony\Component\Serializer\Tests\Fixtures\Annotations\IgnoreDummyAdditionalGetter::getMyValue()" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.'); + + parent::testIgnoreGetterWithRequiredParameterIfIgnoreAnnotationIsUsed(); + } + + /** + * @group legacy + */ + public function testIgnoreGetterWithRequiredParameterIfIgnoreAnnotationIsNotUsed() + { + parent::testIgnoreGetterWithRequiredParameterIfIgnoreAnnotationIsNotUsed(); + } + protected function createLoader(): AnnotationLoader { return new AnnotationLoader(new AnnotationReader()); diff --git a/src/Symfony/Component/Serializer/Tests/Mapping/Loader/Features/ContextMappingTestTrait.php b/src/Symfony/Component/Serializer/Tests/Mapping/Loader/Features/ContextMappingTestTrait.php index 97c70c1499134..c33d8a9048fbf 100644 --- a/src/Symfony/Component/Serializer/Tests/Mapping/Loader/Features/ContextMappingTestTrait.php +++ b/src/Symfony/Component/Serializer/Tests/Mapping/Loader/Features/ContextMappingTestTrait.php @@ -14,8 +14,8 @@ use PHPUnit\Framework\Assert; use Symfony\Component\Serializer\Mapping\ClassMetadata; use Symfony\Component\Serializer\Mapping\Loader\LoaderInterface; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\ContextDummy; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\ContextDummyParent; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\ContextDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\ContextDummyParent; /** * @author Maxime Steinhausser @@ -29,7 +29,7 @@ public function testLoadContexts() $this->assertLoadedContexts(); } - public function assertLoadedContexts(string $dummyClass = ContextDummy::class, string $parentClass = ContextDummyParent::class) + public function assertLoadedContexts(string $dummyClass = ContextDummy::class, string $parentClass = ContextDummyParent::class): void { $loader = $this->getLoaderForContextMapping(); diff --git a/src/Symfony/Component/Serializer/Tests/Mapping/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/Serializer/Tests/Mapping/Loader/XmlFileLoaderTest.php index 202534f56fca5..c0298129efa59 100644 --- a/src/Symfony/Component/Serializer/Tests/Mapping/Loader/XmlFileLoaderTest.php +++ b/src/Symfony/Component/Serializer/Tests/Mapping/Loader/XmlFileLoaderTest.php @@ -17,10 +17,15 @@ use Symfony\Component\Serializer\Mapping\ClassMetadata; use Symfony\Component\Serializer\Mapping\Loader\LoaderInterface; use Symfony\Component\Serializer\Mapping\Loader\XmlFileLoader; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\AbstractDummy; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\AbstractDummyFirstChild; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\AbstractDummySecondChild; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\IgnoreDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\AbstractDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\AbstractDummyFirstChild; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\AbstractDummySecondChild; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\GroupDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\IgnoreDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\MaxDepthDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\SerializedNameDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\SerializedPathDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\SerializedPathInConstructorDummy; use Symfony\Component\Serializer\Tests\Mapping\Loader\Features\ContextMappingTestTrait; use Symfony\Component\Serializer\Tests\Mapping\TestClassMetadataFactory; @@ -31,20 +36,13 @@ class XmlFileLoaderTest extends TestCase { use ContextMappingTestTrait; - /** - * @var XmlFileLoader - */ - private $loader; - - /** - * @var ClassMetadata - */ - private $metadata; + private XmlFileLoader $loader; + private ClassMetadata $metadata; protected function setUp(): void { $this->loader = new XmlFileLoader(__DIR__.'/../../Fixtures/serialization.xml'); - $this->metadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy'); + $this->metadata = new ClassMetadata(GroupDummy::class); } public function testInterface() @@ -66,7 +64,7 @@ public function testLoadClassMetadata() public function testMaxDepth() { - $classMetadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\Annotations\MaxDepthDummy'); + $classMetadata = new ClassMetadata(MaxDepthDummy::class); $this->loader->loadClassMetadata($classMetadata); $attributesMetadata = $classMetadata->getAttributesMetadata(); @@ -76,7 +74,7 @@ public function testMaxDepth() public function testSerializedName() { - $classMetadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\Annotations\SerializedNameDummy'); + $classMetadata = new ClassMetadata(SerializedNameDummy::class); $this->loader->loadClassMetadata($classMetadata); $attributesMetadata = $classMetadata->getAttributesMetadata(); @@ -86,7 +84,7 @@ public function testSerializedName() public function testSerializedPath() { - $classMetadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\Annotations\SerializedPathDummy'); + $classMetadata = new ClassMetadata(SerializedPathDummy::class); $this->loader->loadClassMetadata($classMetadata); $attributesMetadata = $classMetadata->getAttributesMetadata(); @@ -96,7 +94,7 @@ public function testSerializedPath() public function testSerializedPathInConstructor() { - $classMetadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\Annotations\SerializedPathInConstructorDummy'); + $classMetadata = new ClassMetadata(SerializedPathInConstructorDummy::class); $this->loader->loadClassMetadata($classMetadata); $attributesMetadata = $classMetadata->getAttributesMetadata(); diff --git a/src/Symfony/Component/Serializer/Tests/Mapping/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/Serializer/Tests/Mapping/Loader/YamlFileLoaderTest.php index dcfd2b4afac51..ea81a9d8ad7cd 100644 --- a/src/Symfony/Component/Serializer/Tests/Mapping/Loader/YamlFileLoaderTest.php +++ b/src/Symfony/Component/Serializer/Tests/Mapping/Loader/YamlFileLoaderTest.php @@ -19,10 +19,15 @@ use Symfony\Component\Serializer\Mapping\ClassMetadata; use Symfony\Component\Serializer\Mapping\Loader\LoaderInterface; use Symfony\Component\Serializer\Mapping\Loader\YamlFileLoader; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\AbstractDummy; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\AbstractDummyFirstChild; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\AbstractDummySecondChild; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\IgnoreDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\AbstractDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\AbstractDummyFirstChild; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\AbstractDummySecondChild; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\GroupDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\IgnoreDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\MaxDepthDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\SerializedNameDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\SerializedPathDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\SerializedPathInConstructorDummy; use Symfony\Component\Serializer\Tests\Mapping\Loader\Features\ContextMappingTestTrait; use Symfony\Component\Serializer\Tests\Mapping\TestClassMetadataFactory; @@ -33,19 +38,13 @@ class YamlFileLoaderTest extends TestCase { use ContextMappingTestTrait; - /** - * @var YamlFileLoader - */ - private $loader; - /** - * @var ClassMetadata - */ - private $metadata; + private YamlFileLoader $loader; + private ClassMetadata $metadata; protected function setUp(): void { $this->loader = new YamlFileLoader(__DIR__.'/../../Fixtures/serialization.yml'); - $this->metadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy'); + $this->metadata = new ClassMetadata(GroupDummy::class); } public function testInterface() @@ -80,7 +79,7 @@ public function testLoadClassMetadata() public function testMaxDepth() { - $classMetadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\Annotations\MaxDepthDummy'); + $classMetadata = new ClassMetadata(MaxDepthDummy::class); $this->loader->loadClassMetadata($classMetadata); $attributesMetadata = $classMetadata->getAttributesMetadata(); @@ -90,7 +89,7 @@ public function testMaxDepth() public function testSerializedName() { - $classMetadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\Annotations\SerializedNameDummy'); + $classMetadata = new ClassMetadata(SerializedNameDummy::class); $this->loader->loadClassMetadata($classMetadata); $attributesMetadata = $classMetadata->getAttributesMetadata(); @@ -100,7 +99,7 @@ public function testSerializedName() public function testSerializedPath() { - $classMetadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\Annotations\SerializedPathDummy'); + $classMetadata = new ClassMetadata(SerializedPathDummy::class); $this->loader->loadClassMetadata($classMetadata); $attributesMetadata = $classMetadata->getAttributesMetadata(); @@ -110,7 +109,7 @@ public function testSerializedPath() public function testSerializedPathInConstructor() { - $classMetadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\Annotations\SerializedPathInConstructorDummy'); + $classMetadata = new ClassMetadata(SerializedPathInConstructorDummy::class); $this->loader->loadClassMetadata($classMetadata); $attributesMetadata = $classMetadata->getAttributesMetadata(); diff --git a/src/Symfony/Component/Serializer/Tests/Mapping/TestClassMetadataFactory.php b/src/Symfony/Component/Serializer/Tests/Mapping/TestClassMetadataFactory.php index a33ded3d8375e..61147316a68ed 100644 --- a/src/Symfony/Component/Serializer/Tests/Mapping/TestClassMetadataFactory.php +++ b/src/Symfony/Component/Serializer/Tests/Mapping/TestClassMetadataFactory.php @@ -13,6 +13,7 @@ use Symfony\Component\Serializer\Mapping\AttributeMetadata; use Symfony\Component\Serializer\Mapping\ClassMetadata; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\GroupDummy; /** * @author Kévin Dunglas @@ -70,7 +71,7 @@ public static function createClassMetadata(string $namespace, bool $withParent = public static function createXmlCLassMetadata(): ClassMetadata { - $expected = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy'); + $expected = new ClassMetadata(GroupDummy::class); $foo = new AttributeMetadata('foo'); $foo->addGroup('group1'); diff --git a/src/Symfony/Component/Serializer/Tests/NameConverter/MetadataAwareNameConverterTest.php b/src/Symfony/Component/Serializer/Tests/NameConverter/MetadataAwareNameConverterTest.php index 9491206eee254..9ee6fcdf723a1 100644 --- a/src/Symfony/Component/Serializer/Tests/NameConverter/MetadataAwareNameConverterTest.php +++ b/src/Symfony/Component/Serializer/Tests/NameConverter/MetadataAwareNameConverterTest.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Serializer\Tests\NameConverter; -use Doctrine\Common\Annotations\AnnotationReader; use PHPUnit\Framework\TestCase; use Symfony\Component\Serializer\Annotation\SerializedName; use Symfony\Component\Serializer\Annotation\SerializedPath; @@ -21,7 +20,7 @@ use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; use Symfony\Component\Serializer\NameConverter\MetadataAwareNameConverter; use Symfony\Component\Serializer\NameConverter\NameConverterInterface; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\SerializedNameDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\SerializedNameDummy; use Symfony\Component\Serializer\Tests\Fixtures\OtherSerializedNameDummy; /** @@ -39,9 +38,9 @@ public function testInterface() /** * @dataProvider attributeProvider */ - public function testNormalize($propertyName, $expected) + public function testNormalize(string|int $propertyName, string|int $expected) { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $nameConverter = new MetadataAwareNameConverter($classMetadataFactory); @@ -51,14 +50,14 @@ public function testNormalize($propertyName, $expected) /** * @dataProvider fallbackAttributeProvider */ - public function testNormalizeWithFallback($propertyName, $expected) + public function testNormalizeWithFallback(string|int $propertyName, string|int $expected) { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $fallback = $this->createMock(NameConverterInterface::class); $fallback ->method('normalize') - ->willReturnCallback(fn ($propertyName) => strtoupper($propertyName)) + ->willReturnCallback(static fn ($propertyName) => strtoupper($propertyName)) ; $nameConverter = new MetadataAwareNameConverter($classMetadataFactory, $fallback); @@ -69,9 +68,9 @@ public function testNormalizeWithFallback($propertyName, $expected) /** * @dataProvider attributeProvider */ - public function testDenormalize($expected, $propertyName) + public function testDenormalize(string|int $expected, string|int $propertyName) { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $nameConverter = new MetadataAwareNameConverter($classMetadataFactory); @@ -81,14 +80,14 @@ public function testDenormalize($expected, $propertyName) /** * @dataProvider fallbackAttributeProvider */ - public function testDenormalizeWithFallback($expected, $propertyName) + public function testDenormalizeWithFallback(string|int $expected, string|int $propertyName) { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $fallback = $this->createMock(NameConverterInterface::class); $fallback ->method('denormalize') - ->willReturnCallback(fn ($propertyName) => strtolower($propertyName)) + ->willReturnCallback(static fn ($propertyName) => strtolower($propertyName)) ; $nameConverter = new MetadataAwareNameConverter($classMetadataFactory, $fallback); @@ -119,9 +118,9 @@ public static function fallbackAttributeProvider(): array /** * @dataProvider attributeAndContextProvider */ - public function testNormalizeWithGroups($propertyName, $expected, $context = []) + public function testNormalizeWithGroups(string $propertyName, string $expected, array $context = []) { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $nameConverter = new MetadataAwareNameConverter($classMetadataFactory); @@ -131,16 +130,16 @@ public function testNormalizeWithGroups($propertyName, $expected, $context = []) /** * @dataProvider attributeAndContextProvider */ - public function testDenormalizeWithGroups($expected, $propertyName, $context = []) + public function testDenormalizeWithGroups(string $expected, string $propertyName, array $context = []) { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $nameConverter = new MetadataAwareNameConverter($classMetadataFactory); $this->assertEquals($expected, $nameConverter->denormalize($propertyName, OtherSerializedNameDummy::class, null, $context)); } - public static function attributeAndContextProvider() + public static function attributeAndContextProvider(): array { return [ ['buz', 'buz', ['groups' => ['a']]], @@ -154,7 +153,7 @@ public static function attributeAndContextProvider() public function testDenormalizeWithCacheContext() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $nameConverter = new MetadataAwareNameConverter($classMetadataFactory); @@ -165,7 +164,7 @@ public function testDenormalizeWithCacheContext() public function testDenormalizeWithNestedPathAndName() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $nameConverter = new MetadataAwareNameConverter($classMetadataFactory); $this->expectException(LogicException::class); $this->expectExceptionMessage('Found SerializedName and SerializedPath annotations on property "foo" of class "Symfony\Component\Serializer\Tests\NameConverter\NestedPathAndName".'); @@ -174,7 +173,7 @@ public function testDenormalizeWithNestedPathAndName() public function testNormalizeWithNestedPathAndName() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $nameConverter = new MetadataAwareNameConverter($classMetadataFactory); $this->expectException(LogicException::class); $this->expectExceptionMessage('Found SerializedName and SerializedPath annotations on property "foo" of class "Symfony\Component\Serializer\Tests\NameConverter\NestedPathAndName".'); @@ -184,10 +183,6 @@ public function testNormalizeWithNestedPathAndName() class NestedPathAndName { - /** - * @SerializedName("five") - * - * @SerializedPath("[one][two][three]") - */ + #[SerializedName('five'), SerializedPath('[one][two][three]')] public $foo; } diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractNormalizerTest.php index cf51ce840d8ff..74018ebb424b3 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractNormalizerTest.php @@ -27,7 +27,7 @@ use Symfony\Component\Serializer\Normalizer\PropertyNormalizer; use Symfony\Component\Serializer\Serializer; use Symfony\Component\Serializer\Tests\Fixtures\AbstractNormalizerDummy; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\IgnoreDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\IgnoreDummy; use Symfony\Component\Serializer\Tests\Fixtures\Dummy; use Symfony\Component\Serializer\Tests\Fixtures\NullableConstructorArgumentDummy; use Symfony\Component\Serializer\Tests\Fixtures\NullableOptionalConstructorArgumentDummy; diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php index bed7c33cecc19..42eed47eb021f 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Serializer\Tests\Normalizer; -use Doctrine\Common\Annotations\AnnotationReader; use PHPUnit\Framework\TestCase; use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor; use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor; @@ -42,9 +41,9 @@ use Symfony\Component\Serializer\Serializer; use Symfony\Component\Serializer\SerializerAwareInterface; use Symfony\Component\Serializer\SerializerInterface; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\AbstractDummy; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\AbstractDummyFirstChild; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\AbstractDummySecondChild; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\AbstractDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\AbstractDummyFirstChild; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\AbstractDummySecondChild; use Symfony\Component\Serializer\Tests\Fixtures\DummyFirstChildQuux; use Symfony\Component\Serializer\Tests\Fixtures\DummySecondChildQuux; use Symfony\Component\Serializer\Tests\Normalizer\Features\ObjectDummyWithContextAttribute; @@ -76,7 +75,7 @@ public function testDenormalizeWithExtraAttribute() { $this->expectException(ExtraAttributesException::class); $this->expectExceptionMessage('Extra attributes are not allowed ("fooFoo" is unknown).'); - $factory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $factory = new ClassMetadataFactory(new AnnotationLoader()); $normalizer = new AbstractObjectNormalizerDummy($factory); $normalizer->denormalize( ['fooFoo' => 'foo'], @@ -90,7 +89,7 @@ public function testDenormalizeWithExtraAttributes() { $this->expectException(ExtraAttributesException::class); $this->expectExceptionMessage('Extra attributes are not allowed ("fooFoo", "fooBar" are unknown).'); - $factory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $factory = new ClassMetadataFactory(new AnnotationLoader()); $normalizer = new AbstractObjectNormalizerDummy($factory); $normalizer->denormalize( ['fooFoo' => 'foo', 'fooBar' => 'bar'], @@ -228,7 +227,7 @@ public function testNormalizeWithNestedAttributesMixingArrayTypes() $foobar = new AlreadyPopulatedNestedDummy(); $foobar->foo = 'foo'; $foobar->bar = 'bar'; - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $normalizer = new ObjectNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory)); $normalizer->normalize($foobar, 'any'); } @@ -240,7 +239,7 @@ public function testNormalizeWithNestedAttributesElementAlreadySet() $foobar = new DuplicateValueNestedDummy(); $foobar->foo = 'foo'; $foobar->bar = 'bar'; - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $normalizer = new ObjectNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory)); $normalizer->normalize($foobar, 'any'); } @@ -262,7 +261,7 @@ public function testNormalizeWithNestedAttributes() 'foo' => 'notfoo', 'baz' => 'baz', ]; - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $normalizer = new ObjectNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory)); $test = $normalizer->normalize($foobar, 'any'); $this->assertSame($data, $test); @@ -288,7 +287,7 @@ public function testNormalizeWithNestedAttributesWithoutMetadata() public function testNormalizeWithNestedAttributesInConstructor() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $normalizer = new ObjectNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory)); $test = $normalizer->normalize(new NestedDummyWithConstructor('foo', 'quux', 'notfoo', 'baz'), 'any'); @@ -306,7 +305,7 @@ public function testNormalizeWithNestedAttributesInConstructor() public function testNormalizeWithNestedAttributesInConstructorAndDiscriminatorMap() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $normalizer = new ObjectNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory)); $test1 = $normalizer->normalize(new FirstNestedDummyWithConstructorAndDiscriminator('foo', 'notfoo', 'baz'), 'any'); @@ -449,7 +448,7 @@ private function getDenormalizerForStringCollection() public function testDenormalizeWithDiscriminatorMapUsesCorrectClassname() { - $factory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $factory = new ClassMetadataFactory(new AnnotationLoader()); $loaderMock = new class() implements ClassMetadataFactoryInterface { public function getMetadataFor($value): ClassMetadataInterface @@ -484,7 +483,7 @@ public function hasMetadataFor($value): bool public function testDenormalizeWithDiscriminatorMapAndObjectToPopulateUsesCorrectClassname() { - $factory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $factory = new ClassMetadataFactory(new AnnotationLoader()); $loaderMock = new class() implements ClassMetadataFactoryInterface { public function getMetadataFor($value): ClassMetadataInterface @@ -683,7 +682,7 @@ public function testDenormalizeRecursiveWithObjectAttributeWithStringValue() public function testDenormalizeUsesContextAttributeForPropertiesInConstructorWithSeralizedName() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $extractor = new PropertyInfoExtractor([], [new PhpDocExtractor(), new ReflectionExtractor()]); $normalizer = new ObjectNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory), null, $extractor); @@ -697,7 +696,7 @@ public function testDenormalizeUsesContextAttributeForPropertiesInConstructorWit public function testNormalizeUsesContextAttributeForPropertiesInConstructorWithSerializedPath() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $extractor = new PropertyInfoExtractor([], [new PhpDocExtractor(), new ReflectionExtractor()]); $normalizer = new ObjectNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory), null, $extractor); @@ -712,7 +711,7 @@ public function testNormalizeUsesContextAttributeForPropertiesInConstructorWithS public function testNormalizeUsesContextAttributeForProperties() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $extractor = new PropertyInfoExtractor([], [new PhpDocExtractor(), new ReflectionExtractor()]); $normalizer = new ObjectNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory), null, $extractor); @@ -792,27 +791,19 @@ class EmptyDummy class AlreadyPopulatedNestedDummy { - /** - * @SerializedPath("[one][two][three]") - */ + #[SerializedPath('[one][two][three]')] public $foo; - /** - * @SerializedPath("[one][two]") - */ + #[SerializedPath('[one][two]')] public $bar; } class DuplicateValueNestedDummy { - /** - * @SerializedPath("[one][two][three]") - */ + #[SerializedPath('[one][two][three]')] public $foo; - /** - * @SerializedPath("[one][two][three]") - */ + #[SerializedPath('[one][two][three]')] public $bar; public $baz; @@ -820,19 +811,13 @@ class DuplicateValueNestedDummy class NestedDummy { - /** - * @SerializedPath("[one][two][three]") - */ + #[SerializedPath('[one][two][three]')] public $foo; - /** - * @SerializedPath("[one][four]") - */ + #[SerializedPath('[one][four]')] public $quux; - /** - * @SerializedPath("[foo]") - */ + #[SerializedPath('[foo]')] public $notfoo; public $baz; @@ -841,19 +826,13 @@ class NestedDummy class NestedDummyWithConstructor { public function __construct( - /** - * @SerializedPath("[one][two][three]") - */ + #[SerializedPath('[one][two][three]')] public $foo, - /** - * @SerializedPath("[one][four]") - */ + #[SerializedPath('[one][four]')] public $quux, - /** - * @SerializedPath("[foo]") - */ + #[SerializedPath('[foo]')] public $notfoo, public $baz, @@ -861,18 +840,14 @@ public function __construct( } } -/** - * @DiscriminatorMap(typeProperty="type", mapping={ - * "first" = FirstNestedDummyWithConstructorAndDiscriminator::class, - * "second" = SecondNestedDummyWithConstructorAndDiscriminator::class, - * }) - */ +#[DiscriminatorMap(typeProperty: 'type', mapping: [ + 'first' => FirstNestedDummyWithConstructorAndDiscriminator::class, + 'second' => SecondNestedDummyWithConstructorAndDiscriminator::class, +])] abstract class AbstractNestedDummyWithConstructorAndDiscriminator { public function __construct( - /** - * @SerializedPath("[foo]") - */ + #[SerializedPath('[foo]')] public $notfoo, public $baz, @@ -883,9 +858,7 @@ public function __construct( class FirstNestedDummyWithConstructorAndDiscriminator extends AbstractNestedDummyWithConstructorAndDiscriminator { public function __construct( - /** - * @SerializedPath("[one][two][three]") - */ + #[SerializedPath('[one][two][three]')] public $foo, $notfoo, @@ -898,9 +871,7 @@ public function __construct( class SecondNestedDummyWithConstructorAndDiscriminator extends AbstractNestedDummyWithConstructorAndDiscriminator { public function __construct( - /** - * @SerializedPath("[one][four]") - */ + #[SerializedPath('[one][four]')] public $quux, $notfoo, @@ -912,14 +883,10 @@ public function __construct( class DuplicateKeyNestedDummy { - /** - * @SerializedPath("[one][four]") - */ + #[SerializedPath('[one][four]')] public $quux; - /** - * @SerializedName("quux") - */ + #[SerializedName('quux')] public $notquux; } @@ -946,7 +913,7 @@ class AbstractObjectNormalizerWithMetadata extends AbstractObjectNormalizer { public function __construct() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); parent::__construct($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory)); } @@ -1110,10 +1077,7 @@ public function deserialize($data, string $type, string $format, array $context class ArrayDenormalizerDummy implements DenormalizerInterface, SerializerAwareInterface { - /** - * @var SerializerInterface|DenormalizerInterface - */ - private $serializer; + private SerializerInterface&DenormalizerInterface $serializer; /** * @throws NotNormalizableValueException @@ -1143,6 +1107,7 @@ public function supportsDenormalization($data, string $type, string $format = nu public function setSerializer(SerializerInterface $serializer): void { + \assert($serializer instanceof DenormalizerInterface); $this->serializer = $serializer; } } diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/Features/ContextMetadataTestTrait.php b/src/Symfony/Component/Serializer/Tests/Normalizer/Features/ContextMetadataTestTrait.php index cb436dbc3b3b3..2eeb76a72f2bd 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/Features/ContextMetadataTestTrait.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/Features/ContextMetadataTestTrait.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Serializer\Tests\Normalizer\Features; -use Doctrine\Common\Annotations\AnnotationReader; use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor; use Symfony\Component\Serializer\Annotation\Context; use Symfony\Component\Serializer\Annotation\Groups; @@ -34,7 +33,7 @@ trait ContextMetadataTestTrait */ public function testContextMetadataNormalize(string $contextMetadataDummyClass) { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $normalizer = new ObjectNormalizer($classMetadataFactory, null, null, new PhpDocExtractor()); new Serializer([new DateTimeNormalizer(), $normalizer]); @@ -57,7 +56,7 @@ public function testContextMetadataNormalize(string $contextMetadataDummyClass) */ public function testContextMetadataContextDenormalize(string $contextMetadataDummyClass) { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $normalizer = new ObjectNormalizer($classMetadataFactory, null, null, new PhpDocExtractor()); new Serializer([new DateTimeNormalizer(), $normalizer]); @@ -78,7 +77,7 @@ public function testContextMetadataContextDenormalize(string $contextMetadataDum self::assertEquals('2011-07-28', $dummy->date->format('Y-m-d'), 'a specific denormalization context is used for this group'); } - public function contextMetadataDummyProvider() + public function contextMetadataDummyProvider(): array { return [ [ContextMetadataDummy::class], @@ -88,7 +87,7 @@ public function contextMetadataDummyProvider() public function testContextDenormalizeWithNameConverter() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $normalizer = new ObjectNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter(), null, new PhpDocExtractor()); new Serializer([new DateTimeNormalizer(), $normalizer]); @@ -102,19 +101,17 @@ class ContextMetadataDummy { /** * @var \DateTime - * - * @Groups({ "extended", "simple" }) - * - * @Context({ DateTimeNormalizer::FORMAT_KEY = \DateTimeInterface::RFC3339 }) - * @Context( - * normalizationContext = { DateTimeNormalizer::FORMAT_KEY = \DateTimeInterface::RFC3339_EXTENDED }, - * groups = {"extended"} - * ) - * @Context( - * denormalizationContext = { DateTimeNormalizer::FORMAT_KEY = "d/m/Y" }, - * groups = {"simple"} - * ) */ + #[Groups(['extended', 'simple'])] + #[Context([DateTimeNormalizer::FORMAT_KEY => \DateTimeInterface::RFC3339])] + #[Context( + normalizationContext: [DateTimeNormalizer::FORMAT_KEY => \DateTimeInterface::RFC3339_EXTENDED], + groups: ['extended'], + )] + #[Context( + denormalizationContext: [DateTimeNormalizer::FORMAT_KEY => 'd/m/Y'], + groups: ['simple'], + )] public $date; } @@ -122,19 +119,17 @@ class ContextChildMetadataDummy { /** * @var \DateTime - * - * @Groups({ "extended", "simple" }) - * - * @DummyContextChild({ DateTimeNormalizer::FORMAT_KEY = \DateTimeInterface::RFC3339 }) - * @DummyContextChild( - * normalizationContext = { DateTimeNormalizer::FORMAT_KEY = \DateTimeInterface::RFC3339_EXTENDED }, - * groups = {"extended"} - * ) - * @DummyContextChild( - * denormalizationContext = { DateTimeNormalizer::FORMAT_KEY = "d/m/Y" }, - * groups = {"simple"} - * ) */ + #[Groups(['extended', 'simple'])] + #[Context([DateTimeNormalizer::FORMAT_KEY => \DateTimeInterface::RFC3339])] + #[Context( + normalizationContext: [DateTimeNormalizer::FORMAT_KEY => \DateTimeInterface::RFC3339_EXTENDED], + groups: ['extended'], + )] + #[Context( + denormalizationContext: [DateTimeNormalizer::FORMAT_KEY => 'd/m/Y'], + groups: ['simple'], + )] public $date; } @@ -142,8 +137,7 @@ class ContextMetadataNamingDummy { /** * @var \DateTime - * - * @Context({ DateTimeNormalizer::FORMAT_KEY = "d/m/Y" }) */ + #[Context([DateTimeNormalizer::FORMAT_KEY => 'd/m/Y'])] public $createdAt; } diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/Features/GroupsTestTrait.php b/src/Symfony/Component/Serializer/Tests/Normalizer/Features/GroupsTestTrait.php index 294109736c11a..08d5e065a6440 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/Features/GroupsTestTrait.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/Features/GroupsTestTrait.php @@ -13,7 +13,7 @@ use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\GroupDummy; /** * Test AbstractNormalizer::GROUPS. diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/Features/MaxDepthTestTrait.php b/src/Symfony/Component/Serializer/Tests/Normalizer/Features/MaxDepthTestTrait.php index ef3123d58908b..46c7dfceb8a29 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/Features/MaxDepthTestTrait.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/Features/MaxDepthTestTrait.php @@ -12,7 +12,7 @@ namespace Symfony\Component\Serializer\Tests\Normalizer\Features; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\MaxDepthDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\MaxDepthDummy; /** * Covers AbstractObjectNormalizer::ENABLE_MAX_DEPTH and AbstractObjectNormalizer::MAX_DEPTH_HANDLER. diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/Features/TypedPropertiesObject.php b/src/Symfony/Component/Serializer/Tests/Normalizer/Features/TypedPropertiesObject.php index 49edde54cf432..e3acafdecd7ff 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/Features/TypedPropertiesObject.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/Features/TypedPropertiesObject.php @@ -15,18 +15,12 @@ class TypedPropertiesObject { - /** - * @Groups({"foo"}) - */ + #[Groups(['foo'])] public string $unInitialized; - /** - * @Groups({"foo"}) - */ + #[Groups(['foo'])] public string $initialized = 'value'; - /** - * @Groups({"bar"}) - */ + #[Groups(['bar'])] public string $initialized2 = 'value'; } diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/GetSetMethodNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/GetSetMethodNormalizerTest.php index e7ce846163e4d..5261b95e1464f 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/GetSetMethodNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/GetSetMethodNormalizerTest.php @@ -11,7 +11,7 @@ namespace Symfony\Component\Serializer\Tests\Normalizer; -use Doctrine\Common\Annotations\AnnotationReader; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor; use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor; @@ -28,8 +28,8 @@ use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use Symfony\Component\Serializer\Serializer; use Symfony\Component\Serializer\SerializerInterface; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy; use Symfony\Component\Serializer\Tests\Fixtures\Attributes\ClassWithIgnoreAttribute; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\GroupDummy; use Symfony\Component\Serializer\Tests\Fixtures\CircularReferenceDummy; use Symfony\Component\Serializer\Tests\Fixtures\SiblingHolder; use Symfony\Component\Serializer\Tests\Normalizer\Features\CacheableObjectAttributesTestTrait; @@ -57,21 +57,15 @@ class GetSetMethodNormalizerTest extends TestCase use SkipUninitializedValuesTestTrait; use TypeEnforcementTestTrait; - /** - * @var GetSetMethodNormalizer - */ - private $normalizer; - /** - * @var SerializerInterface - */ - private $serializer; + private GetSetMethodNormalizer $normalizer; + private SerializerInterface&NormalizerInterface&MockObject $serializer; protected function setUp(): void { $this->createNormalizer(); } - private function createNormalizer(array $defaultContext = []) + private function createNormalizer(array $defaultContext = []): void { $this->serializer = $this->createMock(SerializerNormalizer::class); $this->normalizer = new GetSetMethodNormalizer(null, null, null, null, null, $defaultContext); @@ -233,21 +227,21 @@ public function testConstructorWArgWithPrivateMutator() protected function getNormalizerForCallbacksWithPropertyTypeExtractor(): GetSetMethodNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); return new GetSetMethodNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory), $this->getCallbackPropertyTypeExtractor()); } protected function getNormalizerForCallbacks(): GetSetMethodNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); return new GetSetMethodNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory)); } protected function getNormalizerForCircularReference(array $defaultContext): GetSetMethodNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $normalizer = new GetSetMethodNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory), null, null, null, $defaultContext); new Serializer([$normalizer]); @@ -261,7 +255,7 @@ protected function getSelfReferencingModel() protected function getDenormalizerForConstructArguments(): GetSetMethodNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $denormalizer = new GetSetMethodNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory)); new Serializer([$denormalizer]); @@ -270,21 +264,21 @@ protected function getDenormalizerForConstructArguments(): GetSetMethodNormalize protected function getNormalizerForGroups(): GetSetMethodNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); return new GetSetMethodNormalizer($classMetadataFactory); } protected function getDenormalizerForGroups(): GetSetMethodNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); return new GetSetMethodNormalizer($classMetadataFactory); } public function testGroupsNormalizeWithNameConverter() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $this->normalizer = new GetSetMethodNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter()); $this->normalizer->setSerializer($this->serializer); @@ -305,7 +299,7 @@ public function testGroupsNormalizeWithNameConverter() public function testGroupsDenormalizeWithNameConverter() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $this->normalizer = new GetSetMethodNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter()); $this->normalizer->setSerializer($this->serializer); @@ -320,13 +314,13 @@ public function testGroupsDenormalizeWithNameConverter() 'foo_bar' => '@dunglas', 'symfony' => '@coopTilleuls', 'coop_tilleuls' => 'les-tilleuls.coop', - ], 'Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy', null, [GetSetMethodNormalizer::GROUPS => ['name_converter']]) + ], GroupDummy::class, null, [GetSetMethodNormalizer::GROUPS => ['name_converter']]) ); } protected function getNormalizerForMaxDepth(): NormalizerInterface { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $normalizer = new GetSetMethodNormalizer($classMetadataFactory); $serializer = new Serializer([$normalizer]); $normalizer->setSerializer($serializer); @@ -336,7 +330,7 @@ protected function getNormalizerForMaxDepth(): NormalizerInterface protected function getDenormalizerForObjectToPopulate(): DenormalizerInterface { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $normalizer = new GetSetMethodNormalizer($classMetadataFactory, null, new PhpDocExtractor()); new Serializer([$normalizer]); @@ -360,7 +354,7 @@ public function testRejectInvalidKey() protected function getNormalizerForIgnoredAttributes(): GetSetMethodNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $normalizer = new GetSetMethodNormalizer($classMetadataFactory, null, new PhpDocExtractor()); new Serializer([$normalizer]); @@ -369,7 +363,7 @@ protected function getNormalizerForIgnoredAttributes(): GetSetMethodNormalizer protected function getDenormalizerForIgnoredAttributes(): GetSetMethodNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $normalizer = new GetSetMethodNormalizer($classMetadataFactory, null, new PhpDocExtractor()); new Serializer([$normalizer]); @@ -493,7 +487,7 @@ protected function getNormalizerForCacheableObjectAttributesTest(): GetSetMethod protected function getNormalizerForSkipUninitializedValues(): NormalizerInterface { - return new GetSetMethodNormalizer(new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()))); + return new GetSetMethodNormalizer(new ClassMetadataFactory(new AnnotationLoader())); } } diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/MapDenormalizationTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/MapDenormalizationTest.php index 6c32fb925b0ff..8131e9707a5f8 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/MapDenormalizationTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/MapDenormalizationTest.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Serializer\Tests\Normalizer; -use Doctrine\Common\Annotations\AnnotationReader; use PHPUnit\Framework\TestCase; use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor; use Symfony\Component\Serializer\Exception\InvalidArgumentException; @@ -210,7 +209,7 @@ public function hasMetadataFor($value): bool } }; - $factory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $factory = new ClassMetadataFactory(new AnnotationLoader()); $normalizer = new ObjectNormalizer($factory, null, null, new PhpDocExtractor(), new ClassDiscriminatorFromClassMetadata($loaderMock)); $serializer = new Serializer([$normalizer, new ArrayDenormalizer()]); $normalizer->setSerializer($serializer); diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php index d87b7a67a6f80..ffa029fa5b790 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php @@ -11,8 +11,8 @@ namespace Symfony\Component\Serializer\Tests\Normalizer; -use Doctrine\Common\Annotations\AnnotationReader; use PHPStan\PhpDocParser\Parser\PhpDocParser; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor; use Symfony\Component\PropertyInfo\Extractor\PhpStanExtractor; @@ -34,7 +34,7 @@ use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; use Symfony\Component\Serializer\Serializer; use Symfony\Component\Serializer\SerializerInterface; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\GroupDummy; use Symfony\Component\Serializer\Tests\Fixtures\CircularReferenceDummy; use Symfony\Component\Serializer\Tests\Fixtures\DummyPrivatePropertyWithoutGetter; use Symfony\Component\Serializer\Tests\Fixtures\FormatAndContextAwareNormalizer; @@ -79,21 +79,15 @@ class ObjectNormalizerTest extends TestCase use SkipUninitializedValuesTestTrait; use TypeEnforcementTestTrait; - /** - * @var ObjectNormalizer - */ - private $normalizer; - /** - * @var SerializerInterface - */ - private $serializer; + private ObjectNormalizer $normalizer; + private SerializerInterface&NormalizerInterface&MockObject $serializer; protected function setUp(): void { $this->createNormalizer(); } - private function createNormalizer(array $defaultContext = [], ClassMetadataFactoryInterface $classMetadataFactory = null) + private function createNormalizer(array $defaultContext = [], ClassMetadataFactoryInterface $classMetadataFactory = null): void { $this->serializer = $this->createMock(ObjectSerializerNormalizer::class); $this->normalizer = new ObjectNormalizer($classMetadataFactory, null, null, null, null, null, $defaultContext); @@ -342,7 +336,7 @@ protected function getNormalizerForAttributes(): ObjectNormalizer protected function getDenormalizerForAttributes(): ObjectNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $normalizer = new ObjectNormalizer($classMetadataFactory, null, null, new ReflectionExtractor()); new Serializer([$normalizer]); @@ -368,7 +362,7 @@ public function testAttributesContextDenormalizeConstructor() public function testNormalizeSameObjectWithDifferentAttributes() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $this->normalizer = new ObjectNormalizer($classMetadataFactory); $serializer = new Serializer([$this->normalizer]); $this->normalizer->setSerializer($serializer); @@ -443,7 +437,7 @@ public function testSiblingReference() protected function getDenormalizerForConstructArguments(): ObjectNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $denormalizer = new ObjectNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory)); $serializer = new Serializer([$denormalizer]); $denormalizer->setSerializer($serializer); @@ -455,7 +449,7 @@ protected function getDenormalizerForConstructArguments(): ObjectNormalizer protected function getNormalizerForGroups(): ObjectNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $normalizer = new ObjectNormalizer($classMetadataFactory); // instantiate a serializer with the normalizer to handle normalizing recursive structures new Serializer([$normalizer]); @@ -465,14 +459,14 @@ protected function getNormalizerForGroups(): ObjectNormalizer protected function getDenormalizerForGroups(): ObjectNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); return new ObjectNormalizer($classMetadataFactory); } public function testGroupsNormalizeWithNameConverter() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $this->normalizer = new ObjectNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter()); $this->normalizer->setSerializer($this->serializer); @@ -493,7 +487,7 @@ public function testGroupsNormalizeWithNameConverter() public function testGroupsDenormalizeWithNameConverter() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $this->normalizer = new ObjectNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter()); $this->normalizer->setSerializer($this->serializer); @@ -508,13 +502,13 @@ public function testGroupsDenormalizeWithNameConverter() 'foo_bar' => '@dunglas', 'symfony' => '@coopTilleuls', 'coop_tilleuls' => 'les-tilleuls.coop', - ], 'Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy', null, [ObjectNormalizer::GROUPS => ['name_converter']]) + ], GroupDummy::class, null, [ObjectNormalizer::GROUPS => ['name_converter']]) ); } public function testGroupsDenormalizeWithMetaDataNameConverter() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $this->normalizer = new ObjectNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory)); $this->normalizer->setSerializer($this->serializer); @@ -542,7 +536,7 @@ protected function getNormalizerForIgnoredAttributes(): ObjectNormalizer protected function getDenormalizerForIgnoredAttributes(): ObjectNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $normalizer = new ObjectNormalizer($classMetadataFactory, null, null, new ReflectionExtractor()); new Serializer([$normalizer]); @@ -553,7 +547,7 @@ protected function getDenormalizerForIgnoredAttributes(): ObjectNormalizer protected function getNormalizerForMaxDepth(): ObjectNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $normalizer = new ObjectNormalizer($classMetadataFactory); $serializer = new Serializer([$normalizer]); $normalizer->setSerializer($serializer); @@ -565,7 +559,7 @@ protected function getNormalizerForMaxDepth(): ObjectNormalizer protected function getDenormalizerForObjectToPopulate(): ObjectNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $normalizer = new ObjectNormalizer($classMetadataFactory, null, null, new PhpDocExtractor()); new Serializer([$normalizer]); @@ -583,7 +577,7 @@ protected function getNormalizerForSkipNullValues(): ObjectNormalizer protected function getNormalizerForSkipUninitializedValues(): ObjectNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); return new ObjectNormalizer($classMetadataFactory); } diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/PropertyNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/PropertyNormalizerTest.php index f1401158fb140..b424e41564065 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/PropertyNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/PropertyNormalizerTest.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Serializer\Tests\Normalizer; -use Doctrine\Common\Annotations\AnnotationReader; use PHPUnit\Framework\TestCase; use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor; use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor; @@ -28,8 +27,8 @@ use Symfony\Component\Serializer\Normalizer\PropertyNormalizer; use Symfony\Component\Serializer\Serializer; use Symfony\Component\Serializer\SerializerInterface; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummyChild; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\GroupDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\GroupDummyChild; use Symfony\Component\Serializer\Tests\Fixtures\Dummy; use Symfony\Component\Serializer\Tests\Fixtures\Php74Dummy; use Symfony\Component\Serializer\Tests\Fixtures\PropertyCircularReferenceDummy; @@ -59,22 +58,15 @@ class PropertyNormalizerTest extends TestCase use SkipUninitializedValuesTestTrait; use TypeEnforcementTestTrait; - /** - * @var PropertyNormalizer - */ - private $normalizer; - - /** - * @var SerializerInterface - */ - private $serializer; + private PropertyNormalizer $normalizer; + private SerializerInterface $serializer; protected function setUp(): void { $this->createNormalizer(); } - private function createNormalizer(array $defaultContext = []) + private function createNormalizer(array $defaultContext = []): void { $this->serializer = $this->createMock(SerializerInterface::class); $this->normalizer = new PropertyNormalizer(null, null, null, null, null, $defaultContext); @@ -272,7 +264,7 @@ public function testSiblingReference() protected function getDenormalizerForConstructArguments(): PropertyNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $denormalizer = new PropertyNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory)); $serializer = new Serializer([$denormalizer]); $denormalizer->setSerializer($serializer); @@ -282,21 +274,21 @@ protected function getDenormalizerForConstructArguments(): PropertyNormalizer protected function getNormalizerForGroups(): PropertyNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); return new PropertyNormalizer($classMetadataFactory); } protected function getDenormalizerForGroups(): PropertyNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); return new PropertyNormalizer($classMetadataFactory); } public function testGroupsNormalizeWithNameConverter() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $this->normalizer = new PropertyNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter()); $this->normalizer->setSerializer($this->serializer); @@ -317,7 +309,7 @@ public function testGroupsNormalizeWithNameConverter() public function testGroupsDenormalizeWithNameConverter() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $this->normalizer = new PropertyNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter()); $this->normalizer->setSerializer($this->serializer); @@ -332,7 +324,7 @@ public function testGroupsDenormalizeWithNameConverter() 'foo_bar' => '@dunglas', 'symfony' => '@coopTilleuls', 'coop_tilleuls' => 'les-tilleuls.coop', - ], 'Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy', null, [PropertyNormalizer::GROUPS => ['name_converter']]) + ], GroupDummy::class, null, [PropertyNormalizer::GROUPS => ['name_converter']]) ); } @@ -361,7 +353,7 @@ public function testIgnoredAttributesContextDenormalizeInherit() protected function getNormalizerForMaxDepth(): PropertyNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $normalizer = new PropertyNormalizer($classMetadataFactory); $serializer = new Serializer([$normalizer]); $normalizer->setSerializer($serializer); @@ -371,7 +363,7 @@ protected function getNormalizerForMaxDepth(): PropertyNormalizer protected function getDenormalizerForObjectToPopulate(): PropertyNormalizer { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $normalizer = new PropertyNormalizer($classMetadataFactory, null, new PhpDocExtractor()); new Serializer([$normalizer]); @@ -500,7 +492,7 @@ protected function getNormalizerForCacheableObjectAttributesTest(): AbstractObje protected function getNormalizerForSkipUninitializedValues(): NormalizerInterface { - return new PropertyNormalizer(new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()))); + return new PropertyNormalizer(new ClassMetadataFactory(new AnnotationLoader())); } } diff --git a/src/Symfony/Component/Serializer/Tests/SerializerTest.php b/src/Symfony/Component/Serializer/Tests/SerializerTest.php index 73d183f191b76..8c5c89a674d24 100644 --- a/src/Symfony/Component/Serializer/Tests/SerializerTest.php +++ b/src/Symfony/Component/Serializer/Tests/SerializerTest.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Serializer\Tests; -use Doctrine\Common\Annotations\AnnotationReader; use PHPUnit\Framework\TestCase; use Symfony\Component\PropertyAccess\PropertyAccessor; use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor; @@ -47,9 +46,9 @@ use Symfony\Component\Serializer\Normalizer\UidNormalizer; use Symfony\Component\Serializer\Normalizer\UnwrappingDenormalizer; use Symfony\Component\Serializer\Serializer; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\AbstractDummy; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\AbstractDummyFirstChild; -use Symfony\Component\Serializer\Tests\Fixtures\Annotations\AbstractDummySecondChild; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\AbstractDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\AbstractDummyFirstChild; +use Symfony\Component\Serializer\Tests\Fixtures\Attributes\AbstractDummySecondChild; use Symfony\Component\Serializer\Tests\Fixtures\DenormalizableDummy; use Symfony\Component\Serializer\Tests\Fixtures\DummyFirstChildQuux; use Symfony\Component\Serializer\Tests\Fixtures\DummyMessageInterface; @@ -720,7 +719,7 @@ public function testDeserializeWrappedScalar() public function testUnionTypeDeserializable() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $extractor = new PropertyInfoExtractor([], [new PhpDocExtractor(), new ReflectionExtractor()]); $serializer = new Serializer( [ @@ -752,7 +751,7 @@ public function testUnionTypeDeserializable() public function testUnionTypeDeserializableWithoutAllowedExtraAttributes() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); $extractor = new PropertyInfoExtractor([], [new PhpDocExtractor(), new ReflectionExtractor()]); $serializer = new Serializer( [ @@ -813,7 +812,7 @@ public function testTrueBuiltInTypes() private function serializerWithClassDiscriminator() { - $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader()); return new Serializer([new ObjectNormalizer($classMetadataFactory, null, null, new ReflectionExtractor(), new ClassDiscriminatorFromClassMetadata($classMetadataFactory))], ['json' => new JsonEncoder()]); } @@ -1279,11 +1278,11 @@ public function testNoCollectDenormalizationErrorsWithWrongEnumOnConstructor() } } - public static function provideCollectDenormalizationErrors() + public static function provideCollectDenormalizationErrors(): array { return [ [null], - [new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()))], + [new ClassMetadataFactory(new AnnotationLoader())], ]; } diff --git a/src/Symfony/Component/Validator/CHANGELOG.md b/src/Symfony/Component/Validator/CHANGELOG.md index b971464397dc6..6d8b2a6c5a998 100644 --- a/src/Symfony/Component/Validator/CHANGELOG.md +++ b/src/Symfony/Component/Validator/CHANGELOG.md @@ -6,6 +6,10 @@ CHANGELOG * Allow single integer for the `versions` option of the `Uuid` constraint * Allow single constraint to be passed to the `constraints` option of the `When` constraint + * Deprecate Doctrine annotations support in favor of native attributes + * Deprecate passing an annotation reader to the constructor signature of `AnnotationLoader` + * Deprecate `ValidatorBuilder::setDoctrineAnnotationReader()` + * Deprecate `ValidatorBuilder::addDefaultDoctrineAnnotationReader()` 6.3 --- diff --git a/src/Symfony/Component/Validator/Constraints/GroupSequence.php b/src/Symfony/Component/Validator/Constraints/GroupSequence.php index 522c5fdf59d11..ae222ace2e4cd 100644 --- a/src/Symfony/Component/Validator/Constraints/GroupSequence.php +++ b/src/Symfony/Component/Validator/Constraints/GroupSequence.php @@ -28,9 +28,7 @@ * * When adding metadata to a class, you can override the "Default" group of * that class with a group sequence: - * /** - * * @GroupSequence({"Address", "Strict"}) - * *\/ + * #[GroupSequence(['Address', 'Strict'])] * class Address * { * // ... diff --git a/src/Symfony/Component/Validator/Constraints/GroupSequenceProvider.php b/src/Symfony/Component/Validator/Constraints/GroupSequenceProvider.php index 489a449e83830..69437ac331cd4 100644 --- a/src/Symfony/Component/Validator/Constraints/GroupSequenceProvider.php +++ b/src/Symfony/Component/Validator/Constraints/GroupSequenceProvider.php @@ -12,7 +12,7 @@ namespace Symfony\Component\Validator\Constraints; /** - * Annotation to define a group sequence provider. + * Attribute to define a group sequence provider. * * @Annotation * @Target({"CLASS", "ANNOTATION"}) diff --git a/src/Symfony/Component/Validator/Mapping/Loader/AnnotationLoader.php b/src/Symfony/Component/Validator/Mapping/Loader/AnnotationLoader.php index b0252afc3d208..a3cdfb12047ea 100644 --- a/src/Symfony/Component/Validator/Mapping/Loader/AnnotationLoader.php +++ b/src/Symfony/Component/Validator/Mapping/Loader/AnnotationLoader.php @@ -27,10 +27,19 @@ */ class AnnotationLoader implements LoaderInterface { + /** + * @deprecated since Symfony 6.4, this property will be removed in 7.0 + * + * @var Reader|null + */ protected $reader; public function __construct(Reader $reader = null) { + if ($reader) { + trigger_deprecation('symfony/validator', '6.4', 'Passing a "%s" instance as argument 1 to "%s()" is deprecated, pass null or omit the parameter instead.', get_debug_type($reader), __METHOD__); + } + $this->reader = $reader; } @@ -87,10 +96,7 @@ public function loadClassMetadata(ClassMetadata $metadata): bool return $success; } - /** - * @param \ReflectionClass|\ReflectionMethod|\ReflectionProperty $reflection - */ - private function getAnnotations(object $reflection): iterable + private function getAnnotations(\ReflectionMethod|\ReflectionClass|\ReflectionProperty $reflection): iterable { $dedup = []; @@ -112,14 +118,14 @@ private function getAnnotations(object $reflection): iterable $annotations = []; - if ($reflection instanceof \ReflectionClass) { - $annotations = $this->reader->getClassAnnotations($reflection); + if ($reflection instanceof \ReflectionClass && $annotations = $this->reader->getClassAnnotations($reflection)) { + trigger_deprecation('symfony/validator', '6.4', 'Class "%s" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.', $reflection->getName()); } - if ($reflection instanceof \ReflectionMethod) { - $annotations = $this->reader->getMethodAnnotations($reflection); + if ($reflection instanceof \ReflectionMethod && $annotations = $this->reader->getMethodAnnotations($reflection)) { + trigger_deprecation('symfony/validator', '6.4', 'Method "%s::%s()" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.', $reflection->getDeclaringClass()->getName(), $reflection->getName()); } - if ($reflection instanceof \ReflectionProperty) { - $annotations = $this->reader->getPropertyAnnotations($reflection); + if ($reflection instanceof \ReflectionProperty && $annotations = $this->reader->getPropertyAnnotations($reflection)) { + trigger_deprecation('symfony/validator', '6.4', 'Property "%s::$%s" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.', $reflection->getDeclaringClass()->getName(), $reflection->getName()); } foreach ($dedup as $annotation) { diff --git a/src/Symfony/Component/Validator/Tests/Command/DebugCommandTest.php b/src/Symfony/Component/Validator/Tests/Command/DebugCommandTest.php index 81dfa30794c63..c245cc80972b7 100644 --- a/src/Symfony/Component/Validator/Tests/Command/DebugCommandTest.php +++ b/src/Symfony/Component/Validator/Tests/Command/DebugCommandTest.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Validator\Tests\Command; -use Doctrine\Common\Annotations\AnnotationReader; use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Tester\CommandTester; use Symfony\Component\Validator\Command\DebugCommand; @@ -27,7 +26,7 @@ class DebugCommandTest extends TestCase { public function testOutputWithClassArgument() { - $command = new DebugCommand(new LazyLoadingMetadataFactory(new AnnotationLoader(new AnnotationReader()))); + $command = new DebugCommand(new LazyLoadingMetadataFactory(new AnnotationLoader())); $tester = new CommandTester($command); $tester->execute(['class' => DummyClassOne::class], ['decorated' => false]); @@ -68,7 +67,7 @@ public function testOutputWithClassArgument() public function testOutputWithPathArgument() { - $command = new DebugCommand(new LazyLoadingMetadataFactory(new AnnotationLoader(new AnnotationReader()))); + $command = new DebugCommand(new LazyLoadingMetadataFactory(new AnnotationLoader())); $tester = new CommandTester($command); $tester->execute(['class' => __DIR__.'/../Dummy'], ['decorated' => false]); diff --git a/src/Symfony/Component/Validator/Tests/Constraints/ExpressionValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/ExpressionValidatorTest.php index b313040e959ab..f427604725a2f 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/ExpressionValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/ExpressionValidatorTest.php @@ -15,7 +15,7 @@ use Symfony\Component\Validator\Constraints\Expression; use Symfony\Component\Validator\Constraints\ExpressionValidator; use Symfony\Component\Validator\Test\ConstraintValidatorTestCase; -use Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity; +use Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity; use Symfony\Component\Validator\Tests\Fixtures\ToString; class ExpressionValidatorTest extends ConstraintValidatorTestCase diff --git a/src/Symfony/Component/Validator/Tests/Constraints/ValidValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/ValidValidatorTest.php index 2b4dd8d215bee..8c625949feb13 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/ValidValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/ValidValidatorTest.php @@ -13,7 +13,6 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Validator\Constraints as Assert; -use Symfony\Component\Validator\Constraints\ValidValidator; use Symfony\Component\Validator\ValidatorBuilder; class ValidValidatorTest extends TestCase @@ -21,7 +20,7 @@ class ValidValidatorTest extends TestCase public function testPropertyPathsArePassedToNestedContexts() { $validatorBuilder = new ValidatorBuilder(); - $validator = $validatorBuilder->enableAnnotationMapping()->addDefaultDoctrineAnnotationReader()->getValidator(); + $validator = $validatorBuilder->enableAnnotationMapping()->getValidator(); $violations = $validator->validate(new Foo(), null, ['nested']); @@ -32,7 +31,7 @@ public function testPropertyPathsArePassedToNestedContexts() public function testNullValues() { $validatorBuilder = new ValidatorBuilder(); - $validator = $validatorBuilder->enableAnnotationMapping()->addDefaultDoctrineAnnotationReader()->getValidator(); + $validator = $validatorBuilder->enableAnnotationMapping()->getValidator(); $foo = new Foo(); $foo->fooBar = null; @@ -40,18 +39,11 @@ public function testNullValues() $this->assertCount(0, $violations); } - - protected function createValidator() - { - return new ValidValidator(); - } } class Foo { - /** - * @Assert\Valid(groups={"nested"}) - */ + #[Assert\Valid(groups: ['nested'])] public $fooBar; public function __construct() @@ -62,9 +54,7 @@ public function __construct() class FooBar { - /** - * @Assert\Valid(groups={"nested"}) - */ + #[Assert\Valid(groups: ['nested'])] public $fooBarBaz; public function __construct() @@ -75,8 +65,6 @@ public function __construct() class FooBarBaz { - /** - * @Assert\NotBlank(groups={"nested"}) - */ + #[Assert\NotBlank(groups: ['nested'])] public $foo; } diff --git a/src/Symfony/Component/Validator/Tests/Constraints/WhenTest.php b/src/Symfony/Component/Validator/Tests/Constraints/WhenTest.php index e057d6b0c43bc..b3305b3c4fe86 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/WhenTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/WhenTest.php @@ -13,6 +13,7 @@ use Doctrine\Common\Annotations\AnnotationReader; use PHPUnit\Framework\TestCase; +use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Component\Validator\Constraints\Callback; use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\NotNull; @@ -25,6 +26,8 @@ final class WhenTest extends TestCase { + use ExpectDeprecationTrait; + public function testMissingOptionsExceptionIsThrown() { $this->expectException(MissingOptionsException::class); @@ -42,11 +45,22 @@ public function testNonConstraintsAreRejected() ]); } + /** + * @group legacy + */ public function testAnnotations() { + $this->expectDeprecation('Since symfony/validator 6.4: Passing a "Doctrine\Common\Annotations\AnnotationReader" instance as argument 1 to "Symfony\Component\Validator\Mapping\Loader\AnnotationLoader::__construct()" is deprecated, pass null or omit the parameter instead.'); + $loader = new AnnotationLoader(new AnnotationReader()); $metadata = new ClassMetadata(WhenTestWithAnnotations::class); + $this->expectDeprecation('Since symfony/validator 6.4: Class "Symfony\Component\Validator\Tests\Constraints\WhenTestWithAnnotations" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Property "Symfony\Component\Validator\Tests\Constraints\WhenTestWithAnnotations::$foo" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Property "Symfony\Component\Validator\Tests\Constraints\WhenTestWithAnnotations::$bar" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Property "Symfony\Component\Validator\Tests\Constraints\WhenTestWithAnnotations::$qux" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Method "Symfony\Component\Validator\Tests\Constraints\WhenTestWithAnnotations::getBaz()" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + self::assertTrue($loader->loadClassMetadata($metadata)); [$classConstraint] = $metadata->getConstraints(); @@ -114,12 +128,9 @@ public function testAnnotations() self::assertSame(['Default', 'WhenTestWithAnnotations'], $bazConstraint->groups); } - /** - * @requires PHP 8.1 - */ public function testAttributes() { - $loader = new AnnotationLoader(new AnnotationReader()); + $loader = new AnnotationLoader(); $metadata = new ClassMetadata(WhenTestWithAttributes::class); self::assertTrue($loader->loadClassMetadata($metadata)); diff --git a/src/Symfony/Component/Validator/Tests/Dummy/DummyClassOne.php b/src/Symfony/Component/Validator/Tests/Dummy/DummyClassOne.php index 92def37e0e9fe..969f5244de21e 100644 --- a/src/Symfony/Component/Validator/Tests/Dummy/DummyClassOne.php +++ b/src/Symfony/Component/Validator/Tests/Dummy/DummyClassOne.php @@ -13,22 +13,18 @@ use Symfony\Component\Validator\Constraints as Assert; -/** - * @Assert\Expression(expression="1 + 1 = 2") - */ +#[Assert\Expression(expression: '1 + 1 = 2')] class DummyClassOne { /** * @var string|null - * - * @Assert\NotBlank */ + #[Assert\NotBlank] public $code; /** * @var string|null - * - * @Assert\Email */ + #[Assert\Email] public $email; } diff --git a/src/Symfony/Component/Validator/Tests/Dummy/DummyClassTwo.php b/src/Symfony/Component/Validator/Tests/Dummy/DummyClassTwo.php index cd136a9dd301e..8c35555da7776 100644 --- a/src/Symfony/Component/Validator/Tests/Dummy/DummyClassTwo.php +++ b/src/Symfony/Component/Validator/Tests/Dummy/DummyClassTwo.php @@ -13,22 +13,18 @@ use Symfony\Component\Validator\Constraints as Assert; -/** - * @Assert\Expression(expression="1 + 1 = 2") - */ +#[Assert\Expression(expression: '1 + 1 = 2')] class DummyClassTwo { /** * @var string|null - * - * @Assert\NotBlank */ + #[Assert\NotBlank] public $code; /** * @var string|null - * - * @Assert\Email */ + #[Assert\Email] public $email; } diff --git a/src/Symfony/Component/Validator/Tests/Fixtures/GroupSequenceProviderChildEntity.php b/src/Symfony/Component/Validator/Tests/Fixtures/GroupSequenceProviderChildEntity.php index ee8f718748d95..cd6ca1ea55f75 100644 --- a/src/Symfony/Component/Validator/Tests/Fixtures/GroupSequenceProviderChildEntity.php +++ b/src/Symfony/Component/Validator/Tests/Fixtures/GroupSequenceProviderChildEntity.php @@ -11,7 +11,7 @@ namespace Symfony\Component\Validator\Tests\Fixtures; -use Symfony\Component\Validator\Tests\Fixtures\Annotation\GroupSequenceProviderEntity; +use Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\GroupSequenceProviderEntity; class GroupSequenceProviderChildEntity extends GroupSequenceProviderEntity { diff --git a/src/Symfony/Component/Validator/Tests/Fixtures/NestedAttribute/Entity.php b/src/Symfony/Component/Validator/Tests/Fixtures/NestedAttribute/Entity.php index cb4a924a97e1a..43ea51a51186a 100644 --- a/src/Symfony/Component/Validator/Tests/Fixtures/NestedAttribute/Entity.php +++ b/src/Symfony/Component/Validator/Tests/Fixtures/NestedAttribute/Entity.php @@ -13,7 +13,6 @@ use Symfony\Component\Validator\Constraints as Assert; use Symfony\Component\Validator\Context\ExecutionContextInterface; -use Symfony\Component\Validator\Tests\Fixtures\Attribute\EntityParent; use Symfony\Component\Validator\Tests\Fixtures\EntityInterfaceB; use Symfony\Component\Validator\Tests\Fixtures\CallbackClass; use Symfony\Component\Validator\Tests\Fixtures\ConstraintA; @@ -67,7 +66,7 @@ class Entity extends EntityParent implements EntityInterfaceB new Assert\Range(min: 5), ]), ] - public string $firstName; + public $firstName; #[Assert\Valid] public $childA; #[Assert\Valid] diff --git a/src/Symfony/Component/Validator/Tests/Fixtures/PropertyInfoLoaderEntity.php b/src/Symfony/Component/Validator/Tests/Fixtures/PropertyInfoLoaderEntity.php index 2cc46e77de295..174f8ee988431 100644 --- a/src/Symfony/Component/Validator/Tests/Fixtures/PropertyInfoLoaderEntity.php +++ b/src/Symfony/Component/Validator/Tests/Fixtures/PropertyInfoLoaderEntity.php @@ -25,34 +25,24 @@ class PropertyInfoLoaderEntity public $collection; public $collectionOfUnknown; - /** - * @Assert\Type(type="int") - */ + #[Assert\Type(type: 'int')] public $alreadyMappedType; - /** - * @Assert\NotNull - */ + #[Assert\NotNull] public $alreadyMappedNotNull; - /** - * @Assert\NotBlank - */ + #[Assert\NotBlank] public $alreadyMappedNotBlank; - /** - * @Assert\All({ - * @Assert\Type(type="string"), - * @Assert\Iban - * }) - */ + #[Assert\All([ + new Assert\Type(type: 'string'), + new Assert\Iban(), + ])] public $alreadyPartiallyMappedCollection; public $readOnly; - /** - * @Assert\DisableAutoMapping - */ + #[Assert\DisableAutoMapping] public $noAutoMapping; public function setNonExistentField() diff --git a/src/Symfony/Component/Validator/Tests/Fixtures/PropertyInfoLoaderNoAutoMappingEntity.php b/src/Symfony/Component/Validator/Tests/Fixtures/PropertyInfoLoaderNoAutoMappingEntity.php index d14cb7c7c7ca0..3271cf0c84caa 100644 --- a/src/Symfony/Component/Validator/Tests/Fixtures/PropertyInfoLoaderNoAutoMappingEntity.php +++ b/src/Symfony/Component/Validator/Tests/Fixtures/PropertyInfoLoaderNoAutoMappingEntity.php @@ -14,16 +14,13 @@ use Symfony\Component\Validator\Constraints as Assert; /** - * @Assert\DisableAutoMapping - * * @author Kévin Dunglas */ +#[Assert\DisableAutoMapping] class PropertyInfoLoaderNoAutoMappingEntity { public $string; - /** - * @Assert\EnableAutoMapping - */ + #[Assert\EnableAutoMapping] public $autoMappingExplicitlyEnabled; } diff --git a/src/Symfony/Component/Validator/Tests/Mapping/ClassMetadataTest.php b/src/Symfony/Component/Validator/Tests/Mapping/ClassMetadataTest.php index 13636dc7b8f40..136751bcdd590 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/ClassMetadataTest.php +++ b/src/Symfony/Component/Validator/Tests/Mapping/ClassMetadataTest.php @@ -21,13 +21,14 @@ use Symfony\Component\Validator\Exception\GroupDefinitionException; use Symfony\Component\Validator\Mapping\CascadingStrategy; use Symfony\Component\Validator\Mapping\ClassMetadata; -use Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity; -use Symfony\Component\Validator\Tests\Fixtures\Annotation\EntityParent; -use Symfony\Component\Validator\Tests\Fixtures\Annotation\GroupSequenceProviderEntity; +use Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity; +use Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\EntityParent; +use Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\GroupSequenceProviderEntity; use Symfony\Component\Validator\Tests\Fixtures\CascadingEntity; use Symfony\Component\Validator\Tests\Fixtures\ClassConstraint; use Symfony\Component\Validator\Tests\Fixtures\ConstraintA; use Symfony\Component\Validator\Tests\Fixtures\ConstraintB; +use Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderChildEntity; use Symfony\Component\Validator\Tests\Fixtures\PropertyConstraint; class ClassMetadataTest extends TestCase @@ -35,7 +36,7 @@ class ClassMetadataTest extends TestCase private const CLASSNAME = Entity::class; private const PARENTCLASS = EntityParent::class; private const PROVIDERCLASS = GroupSequenceProviderEntity::class; - private const PROVIDERCHILDCLASS = 'Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderChildEntity'; + private const PROVIDERCHILDCLASS = GroupSequenceProviderChildEntity::class; protected $metadata; diff --git a/src/Symfony/Component/Validator/Tests/Mapping/Factory/LazyLoadingMetadataFactoryTest.php b/src/Symfony/Component/Validator/Tests/Mapping/Factory/LazyLoadingMetadataFactoryTest.php index f9b4381c65fbf..6d0e872d19fc6 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/Factory/LazyLoadingMetadataFactoryTest.php +++ b/src/Symfony/Component/Validator/Tests/Mapping/Factory/LazyLoadingMetadataFactoryTest.php @@ -20,8 +20,8 @@ use Symfony\Component\Validator\Mapping\ClassMetadata; use Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory; use Symfony\Component\Validator\Mapping\Loader\LoaderInterface; -use Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity; -use Symfony\Component\Validator\Tests\Fixtures\Annotation\EntityParent; +use Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity; +use Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\EntityParent; use Symfony\Component\Validator\Tests\Fixtures\ConstraintA; use Symfony\Component\Validator\Tests\Fixtures\PropertyGetter; use Symfony\Component\Validator\Tests\Fixtures\PropertyGetterInterface; diff --git a/src/Symfony/Component/Validator/Tests/Mapping/GetterMetadataTest.php b/src/Symfony/Component/Validator/Tests/Mapping/GetterMetadataTest.php index 3128fbb6b1ab1..2a36605729b90 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/GetterMetadataTest.php +++ b/src/Symfony/Component/Validator/Tests/Mapping/GetterMetadataTest.php @@ -14,7 +14,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Validator\Exception\ValidatorException; use Symfony\Component\Validator\Mapping\GetterMetadata; -use Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity; +use Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity; class GetterMetadataTest extends TestCase { @@ -62,7 +62,7 @@ public function testGetPropertyValueFromHasser() public function testUndefinedMethodNameThrowsException() { $this->expectException(ValidatorException::class); - $this->expectExceptionMessage('The "hasLastName()" method does not exist in class "Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity".'); + $this->expectExceptionMessage('The "hasLastName()" method does not exist in class "Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity".'); new GetterMetadata(self::CLASSNAME, 'lastName', 'hasLastName'); } } diff --git a/src/Symfony/Component/Validator/Tests/Mapping/Loader/AnnotationLoaderTest.php b/src/Symfony/Component/Validator/Tests/Mapping/Loader/AnnotationLoaderTest.php index 7f09a5267947c..474064274bb37 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/Loader/AnnotationLoaderTest.php +++ b/src/Symfony/Component/Validator/Tests/Mapping/Loader/AnnotationLoaderTest.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Validator\Tests\Mapping\Loader; -use Doctrine\Common\Annotations\AnnotationReader; use PHPUnit\Framework\TestCase; use Symfony\Component\Validator\Constraints\All; use Symfony\Component\Validator\Constraints\AtLeastOneOf; @@ -31,34 +30,31 @@ use Symfony\Component\Validator\Constraints\Valid; use Symfony\Component\Validator\Mapping\ClassMetadata; use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader; -use Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity; use Symfony\Component\Validator\Tests\Fixtures\ConstraintA; class AnnotationLoaderTest extends TestCase { public function testLoadClassMetadataReturnsTrueIfSuccessful() { - $reader = new AnnotationReader(); - $loader = new AnnotationLoader($reader); - $metadata = new ClassMetadata(Entity::class); + $loader = $this->createAnnotationLoader(); + $metadata = new ClassMetadata($this->getFixtureNamespace().'\Entity'); $this->assertTrue($loader->loadClassMetadata($metadata)); } public function testLoadClassMetadataReturnsFalseIfNotSuccessful() { - $loader = new AnnotationLoader(new AnnotationReader()); + $loader = $this->createAnnotationLoader(); $metadata = new ClassMetadata('\stdClass'); $this->assertFalse($loader->loadClassMetadata($metadata)); } - /** - * @dataProvider provideNamespaces - */ - public function testLoadClassMetadata(string $namespace) + public function testLoadClassMetadata() { - $loader = new AnnotationLoader(new AnnotationReader()); + $loader = $this->createAnnotationLoader(); + $namespace = $this->getFixtureNamespace(); + $metadata = new ClassMetadata($namespace.'\Entity'); $loader->loadClassMetadata($metadata); @@ -109,12 +105,11 @@ public function testLoadClassMetadata(string $namespace) /** * Test MetaData merge with parent annotation. - * - * @dataProvider provideNamespaces */ - public function testLoadParentClassMetadata(string $namespace) + public function testLoadParentClassMetadata() { - $loader = new AnnotationLoader(new AnnotationReader()); + $loader = $this->createAnnotationLoader(); + $namespace = $this->getFixtureNamespace(); // Load Parent MetaData $parent_metadata = new ClassMetadata($namespace.'\EntityParent'); @@ -129,12 +124,11 @@ public function testLoadParentClassMetadata(string $namespace) /** * Test MetaData merge with parent annotation. - * - * @dataProvider provideNamespaces */ - public function testLoadClassMetadataAndMerge(string $namespace) + public function testLoadClassMetadataAndMerge() { - $loader = new AnnotationLoader(new AnnotationReader()); + $loader = $this->createAnnotationLoader(); + $namespace = $this->getFixtureNamespace(); // Load Parent MetaData $parent_metadata = new ClassMetadata($namespace.'\EntityParent'); @@ -201,12 +195,10 @@ public function testLoadClassMetadataAndMerge(string $namespace) $this->assertInstanceOf(NotNull::class, $otherMetadata[1]->getConstraints()[0]); } - /** - * @dataProvider provideNamespaces - */ - public function testLoadGroupSequenceProviderAnnotation(string $namespace) + public function testLoadGroupSequenceProviderAnnotation() { - $loader = new AnnotationLoader(new AnnotationReader()); + $loader = $this->createAnnotationLoader(); + $namespace = $this->getFixtureNamespace(); $metadata = new ClassMetadata($namespace.'\GroupSequenceProviderEntity'); $loader->loadClassMetadata($metadata); @@ -218,10 +210,13 @@ public function testLoadGroupSequenceProviderAnnotation(string $namespace) $this->assertEquals($expected, $metadata); } - public static function provideNamespaces(): iterable + protected function createAnnotationLoader(): AnnotationLoader + { + return new AnnotationLoader(); + } + + protected function getFixtureNamespace(): string { - yield 'annotations' => ['Symfony\Component\Validator\Tests\Fixtures\Annotation']; - yield 'attributes' => ['Symfony\Component\Validator\Tests\Fixtures\Attribute']; - yield 'nested_attributes' => ['Symfony\Component\Validator\Tests\Fixtures\NestedAttribute']; + return 'Symfony\Component\Validator\Tests\Fixtures\NestedAttribute'; } } diff --git a/src/Symfony/Component/Validator/Tests/Mapping/Loader/AnnotationLoaderWithHybridAnnotationsTest.php b/src/Symfony/Component/Validator/Tests/Mapping/Loader/AnnotationLoaderWithHybridAnnotationsTest.php new file mode 100644 index 0000000000000..464019ca82b5c --- /dev/null +++ b/src/Symfony/Component/Validator/Tests/Mapping/Loader/AnnotationLoaderWithHybridAnnotationsTest.php @@ -0,0 +1,97 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Tests\Mapping\Loader; + +use Doctrine\Common\Annotations\AnnotationReader; +use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; +use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader; + +class AnnotationLoaderWithHybridAnnotationsTest extends AnnotationLoaderTest +{ + use ExpectDeprecationTrait; + + /** + * @group legacy + */ + public function testLoadClassMetadataReturnsTrueIfSuccessful() + { + $this->expectDeprecation('Since symfony/validator 6.4: Passing a "Doctrine\Common\Annotations\AnnotationReader" instance as argument 1 to "Symfony\Component\Validator\Mapping\Loader\AnnotationLoader::__construct()" is deprecated, pass null or omit the parameter instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Class "Symfony\Component\Validator\Tests\Fixtures\Attribute\Entity" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Property "Symfony\Component\Validator\Tests\Fixtures\Attribute\Entity::$firstName" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + + parent::testLoadClassMetadataReturnsTrueIfSuccessful(); + } + + /** + * @group legacy + */ + public function testLoadClassMetadataReturnsFalseIfNotSuccessful() + { + $this->expectDeprecation('Since symfony/validator 6.4: Passing a "Doctrine\Common\Annotations\AnnotationReader" instance as argument 1 to "Symfony\Component\Validator\Mapping\Loader\AnnotationLoader::__construct()" is deprecated, pass null or omit the parameter instead.'); + + parent::testLoadClassMetadataReturnsFalseIfNotSuccessful(); + } + + /** + * @group legacy + */ + public function testLoadClassMetadata() + { + $this->expectDeprecation('Since symfony/validator 6.4: Passing a "Doctrine\Common\Annotations\AnnotationReader" instance as argument 1 to "Symfony\Component\Validator\Mapping\Loader\AnnotationLoader::__construct()" is deprecated, pass null or omit the parameter instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Class "Symfony\Component\Validator\Tests\Fixtures\Attribute\Entity" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Property "Symfony\Component\Validator\Tests\Fixtures\Attribute\Entity::$firstName" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + + parent::testLoadClassMetadata(); + } + + /** + * @group legacy + */ + public function testLoadParentClassMetadata() + { + $this->expectDeprecation('Since symfony/validator 6.4: Passing a "Doctrine\Common\Annotations\AnnotationReader" instance as argument 1 to "Symfony\Component\Validator\Mapping\Loader\AnnotationLoader::__construct()" is deprecated, pass null or omit the parameter instead.'); + + parent::testLoadParentClassMetadata(); + } + + /** + * @group legacy + */ + public function testLoadClassMetadataAndMerge() + { + $this->expectDeprecation('Since symfony/validator 6.4: Passing a "Doctrine\Common\Annotations\AnnotationReader" instance as argument 1 to "Symfony\Component\Validator\Mapping\Loader\AnnotationLoader::__construct()" is deprecated, pass null or omit the parameter instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Class "Symfony\Component\Validator\Tests\Fixtures\Attribute\Entity" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Property "Symfony\Component\Validator\Tests\Fixtures\Attribute\Entity::$firstName" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + + parent::testLoadClassMetadataAndMerge(); + } + + /** + * @group legacy + */ + public function testLoadGroupSequenceProviderAnnotation() + { + $this->expectDeprecation('Since symfony/validator 6.4: Passing a "Doctrine\Common\Annotations\AnnotationReader" instance as argument 1 to "Symfony\Component\Validator\Mapping\Loader\AnnotationLoader::__construct()" is deprecated, pass null or omit the parameter instead.'); + + parent::testLoadGroupSequenceProviderAnnotation(); + } + + protected function createAnnotationLoader(): AnnotationLoader + { + return new AnnotationLoader(new AnnotationReader()); + } + + protected function getFixtureNamespace(): string + { + return 'Symfony\Component\Validator\Tests\Fixtures\Attribute'; + } +} diff --git a/src/Symfony/Component/Validator/Tests/Mapping/Loader/AnnotationLoaderWithLegacyAnnotationsTest.php b/src/Symfony/Component/Validator/Tests/Mapping/Loader/AnnotationLoaderWithLegacyAnnotationsTest.php new file mode 100644 index 0000000000000..314bce7b7331c --- /dev/null +++ b/src/Symfony/Component/Validator/Tests/Mapping/Loader/AnnotationLoaderWithLegacyAnnotationsTest.php @@ -0,0 +1,121 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Tests\Mapping\Loader; + +use Doctrine\Common\Annotations\AnnotationReader; +use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; +use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader; + +class AnnotationLoaderWithLegacyAnnotationsTest extends AnnotationLoaderTest +{ + use ExpectDeprecationTrait; + + /** + * @group legacy + */ + public function testLoadClassMetadataReturnsTrueIfSuccessful() + { + $this->expectDeprecation('Since symfony/validator 6.4: Passing a "Doctrine\Common\Annotations\AnnotationReader" instance as argument 1 to "Symfony\Component\Validator\Mapping\Loader\AnnotationLoader::__construct()" is deprecated, pass null or omit the parameter instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Class "Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Property "Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity::$firstName" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Property "Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity::$childA" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Property "Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity::$childB" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Method "Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity::getLastName()" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Method "Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity::isValid()" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Method "Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity::hasPermissions()" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Method "Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity::validateMe()" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Method "Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity::validateMeStatic()" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + + parent::testLoadClassMetadataReturnsTrueIfSuccessful(); + } + + /** + * @group legacy + */ + public function testLoadClassMetadataReturnsFalseIfNotSuccessful() + { + $this->expectDeprecation('Since symfony/validator 6.4: Passing a "Doctrine\Common\Annotations\AnnotationReader" instance as argument 1 to "Symfony\Component\Validator\Mapping\Loader\AnnotationLoader::__construct()" is deprecated, pass null or omit the parameter instead.'); + + parent::testLoadClassMetadataReturnsFalseIfNotSuccessful(); + } + + /** + * @group legacy + */ + public function testLoadClassMetadata() + { + $this->expectDeprecation('Since symfony/validator 6.4: Passing a "Doctrine\Common\Annotations\AnnotationReader" instance as argument 1 to "Symfony\Component\Validator\Mapping\Loader\AnnotationLoader::__construct()" is deprecated, pass null or omit the parameter instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Class "Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Property "Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity::$firstName" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Property "Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity::$childA" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Property "Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity::$childB" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Method "Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity::getLastName()" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Method "Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity::isValid()" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Method "Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity::hasPermissions()" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Method "Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity::validateMe()" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Method "Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity::validateMeStatic()" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + + parent::testLoadClassMetadata(); + } + + /** + * @group legacy + */ + public function testLoadParentClassMetadata() + { + $this->expectDeprecation('Since symfony/validator 6.4: Passing a "Doctrine\Common\Annotations\AnnotationReader" instance as argument 1 to "Symfony\Component\Validator\Mapping\Loader\AnnotationLoader::__construct()" is deprecated, pass null or omit the parameter instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Property "Symfony\Component\Validator\Tests\Fixtures\Annotation\EntityParent::$other" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + + parent::testLoadParentClassMetadata(); + } + + /** + * @group legacy + */ + public function testLoadClassMetadataAndMerge() + { + $this->expectDeprecation('Since symfony/validator 6.4: Passing a "Doctrine\Common\Annotations\AnnotationReader" instance as argument 1 to "Symfony\Component\Validator\Mapping\Loader\AnnotationLoader::__construct()" is deprecated, pass null or omit the parameter instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Property "Symfony\Component\Validator\Tests\Fixtures\Annotation\EntityParent::$other" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Class "Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Property "Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity::$firstName" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Property "Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity::$childA" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Property "Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity::$childB" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Method "Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity::getLastName()" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Method "Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity::isValid()" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Method "Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity::hasPermissions()" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Method "Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity::validateMe()" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Method "Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity::validateMeStatic()" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + + parent::testLoadClassMetadataAndMerge(); + } + + /** + * @group legacy + */ + public function testLoadGroupSequenceProviderAnnotation() + { + $this->expectDeprecation('Since symfony/validator 6.4: Passing a "Doctrine\Common\Annotations\AnnotationReader" instance as argument 1 to "Symfony\Component\Validator\Mapping\Loader\AnnotationLoader::__construct()" is deprecated, pass null or omit the parameter instead.'); + $this->expectDeprecation('Since symfony/validator 6.4: Class "Symfony\Component\Validator\Tests\Fixtures\Annotation\GroupSequenceProviderEntity" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.'); + + parent::testLoadGroupSequenceProviderAnnotation(); + } + + protected function createAnnotationLoader(): AnnotationLoader + { + return new AnnotationLoader(new AnnotationReader()); + } + + protected function getFixtureNamespace(): string + { + return 'Symfony\Component\Validator\Tests\Fixtures\Annotation'; + } +} diff --git a/src/Symfony/Component/Validator/Tests/Mapping/Loader/FilesLoaderTest.php b/src/Symfony/Component/Validator/Tests/Mapping/Loader/FilesLoaderTest.php index ea5e947be880b..c9865dbb95e65 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/Loader/FilesLoaderTest.php +++ b/src/Symfony/Component/Validator/Tests/Mapping/Loader/FilesLoaderTest.php @@ -14,7 +14,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Validator\Mapping\ClassMetadata; use Symfony\Component\Validator\Mapping\Loader\LoaderInterface; -use Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity; +use Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity; use Symfony\Component\Validator\Tests\Fixtures\FilesLoader; class FilesLoaderTest extends TestCase diff --git a/src/Symfony/Component/Validator/Tests/Mapping/Loader/PropertyInfoLoaderTest.php b/src/Symfony/Component/Validator/Tests/Mapping/Loader/PropertyInfoLoaderTest.php index f41d4c55443a9..95cdee8c7dde0 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/Loader/PropertyInfoLoaderTest.php +++ b/src/Symfony/Component/Validator/Tests/Mapping/Loader/PropertyInfoLoaderTest.php @@ -23,7 +23,7 @@ use Symfony\Component\Validator\Mapping\ClassMetadata; use Symfony\Component\Validator\Mapping\Loader\PropertyInfoLoader; use Symfony\Component\Validator\Mapping\PropertyMetadata; -use Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity; +use Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity; use Symfony\Component\Validator\Tests\Fixtures\PropertyInfoLoaderEntity; use Symfony\Component\Validator\Tests\Fixtures\PropertyInfoLoaderNoAutoMappingEntity; use Symfony\Component\Validator\Validation; @@ -92,8 +92,7 @@ public function testLoadClassMetadata() $propertyInfoLoader = new PropertyInfoLoader($propertyInfoStub, $propertyInfoStub, $propertyInfoStub, '{.*}'); $validator = Validation::createValidatorBuilder() - ->enableAnnotationMapping(true) - ->addDefaultDoctrineAnnotationReader() + ->enableAnnotationMapping() ->addLoader($propertyInfoLoader) ->getValidator() ; @@ -205,7 +204,7 @@ public function testClassValidator(bool $expected, string $classValidatorRegexp $this->assertSame($expected, $propertyInfoLoader->loadClassMetadata($classMetadata)); } - public static function regexpProvider() + public static function regexpProvider(): array { return [ [false, null], @@ -231,8 +230,7 @@ public function testClassNoAutoMapping() $propertyInfoLoader = new PropertyInfoLoader($propertyInfoStub, $propertyInfoStub, $propertyInfoStub, '{.*}'); $validator = Validation::createValidatorBuilder() - ->enableAnnotationMapping(true) - ->addDefaultDoctrineAnnotationReader() + ->enableAnnotationMapping() ->addLoader($propertyInfoLoader) ->getValidator() ; diff --git a/src/Symfony/Component/Validator/Tests/Mapping/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/Validator/Tests/Mapping/Loader/XmlFileLoaderTest.php index 792b775fd32a0..51cc89bc2e5f0 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/Loader/XmlFileLoaderTest.php +++ b/src/Symfony/Component/Validator/Tests/Mapping/Loader/XmlFileLoaderTest.php @@ -24,8 +24,8 @@ use Symfony\Component\Validator\Exception\MappingException; use Symfony\Component\Validator\Mapping\ClassMetadata; use Symfony\Component\Validator\Mapping\Loader\XmlFileLoader; -use Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity; -use Symfony\Component\Validator\Tests\Fixtures\Annotation\GroupSequenceProviderEntity; +use Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity; +use Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\GroupSequenceProviderEntity; use Symfony\Component\Validator\Tests\Fixtures\ConstraintA; use Symfony\Component\Validator\Tests\Fixtures\ConstraintB; use Symfony\Component\Validator\Tests\Fixtures\ConstraintWithRequiredArgument; diff --git a/src/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php index cf3dd46d8634d..faaf64dbc8ce0 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php +++ b/src/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php @@ -21,8 +21,8 @@ use Symfony\Component\Validator\Constraints\Range; use Symfony\Component\Validator\Mapping\ClassMetadata; use Symfony\Component\Validator\Mapping\Loader\YamlFileLoader; -use Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity; -use Symfony\Component\Validator\Tests\Fixtures\Annotation\GroupSequenceProviderEntity; +use Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity; +use Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\GroupSequenceProviderEntity; use Symfony\Component\Validator\Tests\Fixtures\ConstraintA; use Symfony\Component\Validator\Tests\Fixtures\ConstraintB; use Symfony\Component\Validator\Tests\Fixtures\ConstraintWithRequiredArgument; diff --git a/src/Symfony/Component/Validator/Tests/Mapping/Loader/bad-format.yml b/src/Symfony/Component/Validator/Tests/Mapping/Loader/bad-format.yml index 8709d232715c8..46d09d746d4d4 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/Loader/bad-format.yml +++ b/src/Symfony/Component/Validator/Tests/Mapping/Loader/bad-format.yml @@ -1,7 +1,7 @@ namespaces: custom: Symfony\Component\Validator\Tests\Fixtures\ -Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity: +Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity: constraints: # Custom constraint - Symfony\Component\Validator\Tests\Fixtures\ConstraintA: ~ diff --git a/src/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping-non-strings.xml b/src/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping-non-strings.xml index 02fbeb431151e..406aaad7644be 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping-non-strings.xml +++ b/src/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping-non-strings.xml @@ -6,7 +6,7 @@ Symfony\Component\Validator\Tests\Fixtures\ - + diff --git a/src/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.xml b/src/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.xml index 114d7fc34e453..0b949554025df 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.xml +++ b/src/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.xml @@ -6,7 +6,7 @@ Symfony\Component\Validator\Tests\Fixtures\ - + Foo @@ -115,7 +115,7 @@ - + diff --git a/src/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.yml b/src/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.yml index 5a62b38334d35..4d2a694c3de86 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.yml +++ b/src/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.yml @@ -1,7 +1,7 @@ namespaces: custom: Symfony\Component\Validator\Tests\Fixtures\ -Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity: +Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity: group_sequence: - Foo - Entity @@ -58,5 +58,5 @@ Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity: permissions: - "IsTrue": ~ -Symfony\Component\Validator\Tests\Fixtures\Annotation\GroupSequenceProviderEntity: +Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\GroupSequenceProviderEntity: group_sequence_provider: true diff --git a/src/Symfony/Component/Validator/Tests/Mapping/Loader/mapping-with-constants.yml b/src/Symfony/Component/Validator/Tests/Mapping/Loader/mapping-with-constants.yml index afdda0478554a..97f8805989080 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/Loader/mapping-with-constants.yml +++ b/src/Symfony/Component/Validator/Tests/Mapping/Loader/mapping-with-constants.yml @@ -1,7 +1,7 @@ namespaces: custom: Symfony\Component\Validator\Tests\Fixtures\ -Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity: +Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity: properties: firstName: - Range: diff --git a/src/Symfony/Component/Validator/Tests/Mapping/Loader/withdoctype.xml b/src/Symfony/Component/Validator/Tests/Mapping/Loader/withdoctype.xml index ae7037c562e9a..db4529482e038 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/Loader/withdoctype.xml +++ b/src/Symfony/Component/Validator/Tests/Mapping/Loader/withdoctype.xml @@ -3,5 +3,5 @@ - + diff --git a/src/Symfony/Component/Validator/Tests/Mapping/MemberMetadataTest.php b/src/Symfony/Component/Validator/Tests/Mapping/MemberMetadataTest.php index 701741e011d34..f115251690d85 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/MemberMetadataTest.php +++ b/src/Symfony/Component/Validator/Tests/Mapping/MemberMetadataTest.php @@ -18,7 +18,7 @@ use Symfony\Component\Validator\Constraints\Valid; use Symfony\Component\Validator\Exception\ConstraintDefinitionException; use Symfony\Component\Validator\Mapping\MemberMetadata; -use Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity; +use Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity; use Symfony\Component\Validator\Tests\Fixtures\ClassConstraint; use Symfony\Component\Validator\Tests\Fixtures\ConstraintA; use Symfony\Component\Validator\Tests\Fixtures\ConstraintB; diff --git a/src/Symfony/Component/Validator/Tests/Mapping/PropertyMetadataTest.php b/src/Symfony/Component/Validator/Tests/Mapping/PropertyMetadataTest.php index 85f580cff533f..883ef41eed46b 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/PropertyMetadataTest.php +++ b/src/Symfony/Component/Validator/Tests/Mapping/PropertyMetadataTest.php @@ -14,8 +14,8 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Validator\Exception\ValidatorException; use Symfony\Component\Validator\Mapping\PropertyMetadata; -use Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity; -use Symfony\Component\Validator\Tests\Fixtures\Annotation\EntityParent; +use Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity; +use Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\EntityParent; use Symfony\Component\Validator\Tests\Fixtures\Entity_74; use Symfony\Component\Validator\Tests\Fixtures\Entity_74_Proxy; diff --git a/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php b/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php index 010536e661f19..469d73bfb08f8 100644 --- a/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php @@ -44,9 +44,9 @@ use Symfony\Component\Validator\ObjectInitializerInterface; use Symfony\Component\Validator\Tests\Constraints\Fixtures\ChildA; use Symfony\Component\Validator\Tests\Constraints\Fixtures\ChildB; -use Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity; -use Symfony\Component\Validator\Tests\Fixtures\Annotation\EntityParent; -use Symfony\Component\Validator\Tests\Fixtures\Annotation\GroupSequenceProviderEntity; +use Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity; +use Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\EntityParent; +use Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\GroupSequenceProviderEntity; use Symfony\Component\Validator\Tests\Fixtures\CascadedChild; use Symfony\Component\Validator\Tests\Fixtures\CascadingEntity; use Symfony\Component\Validator\Tests\Fixtures\EntityWithGroupedConstraintOnMethods; diff --git a/src/Symfony/Component/Validator/Tests/ValidatorBuilderTest.php b/src/Symfony/Component/Validator/Tests/ValidatorBuilderTest.php index 5ac368119a7fd..9d0b1b5140bda 100644 --- a/src/Symfony/Component/Validator/Tests/ValidatorBuilderTest.php +++ b/src/Symfony/Component/Validator/Tests/ValidatorBuilderTest.php @@ -15,6 +15,7 @@ use Doctrine\Common\Annotations\Reader; use PHPUnit\Framework\TestCase; use Psr\Cache\CacheItemPoolInterface; +use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Component\Validator\ConstraintValidatorFactoryInterface; use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader; use Symfony\Component\Validator\ObjectInitializerInterface; @@ -24,10 +25,9 @@ class ValidatorBuilderTest extends TestCase { - /** - * @var ValidatorBuilder - */ - protected $builder; + use ExpectDeprecationTrait; + + private ValidatorBuilder $builder; protected function setUp(): void { @@ -36,7 +36,7 @@ protected function setUp(): void protected function tearDown(): void { - $this->builder = null; + unset($this->builder); } public function testAddObjectInitializer() @@ -81,9 +81,14 @@ public function testAddMethodMappings() $this->assertSame($this->builder, $this->builder->addMethodMappings([])); } + /** + * @group legacy + */ public function testEnableAnnotationMappingWithDefaultDoctrineAnnotationReader() { $this->assertSame($this->builder, $this->builder->enableAnnotationMapping()); + + $this->expectDeprecation('Since symfony/validator 6.4: Method "Symfony\Component\Validator\ValidatorBuilder::addDefaultDoctrineAnnotationReader()" is deprecated without replacement.'); $this->assertSame($this->builder, $this->builder->addDefaultDoctrineAnnotationReader()); $loaders = $this->builder->getLoaders(); @@ -95,11 +100,16 @@ public function testEnableAnnotationMappingWithDefaultDoctrineAnnotationReader() $this->assertInstanceOf(PsrCachedReader::class, $r->getValue($loaders[0])); } + /** + * @group legacy + */ public function testEnableAnnotationMappingWithCustomDoctrineAnnotationReader() { $reader = $this->createMock(Reader::class); $this->assertSame($this->builder, $this->builder->enableAnnotationMapping()); + + $this->expectDeprecation('Since symfony/validator 6.4: Method "Symfony\Component\Validator\ValidatorBuilder::setDoctrineAnnotationReader()" is deprecated without replacement.'); $this->assertSame($this->builder, $this->builder->setDoctrineAnnotationReader($reader)); $loaders = $this->builder->getLoaders(); diff --git a/src/Symfony/Component/Validator/ValidatorBuilder.php b/src/Symfony/Component/Validator/ValidatorBuilder.php index fc2a5e30cebbb..88fd21645c180 100644 --- a/src/Symfony/Component/Validator/ValidatorBuilder.php +++ b/src/Symfony/Component/Validator/ValidatorBuilder.php @@ -216,20 +216,28 @@ public function disableAnnotationMapping(): static } /** + * @deprecated since Symfony 6.4 without replacement + * * @return $this */ public function setDoctrineAnnotationReader(?Reader $reader): static { + trigger_deprecation('symfony/validator', '6.4', 'Method "%s()" is deprecated without replacement.', __METHOD__); + $this->annotationReader = $reader; return $this; } /** + * @deprecated since Symfony 6.4 without replacement + * * @return $this */ public function addDefaultDoctrineAnnotationReader(): static { + trigger_deprecation('symfony/validator', '6.4', 'Method "%s()" is deprecated without replacement.', __METHOD__); + $this->annotationReader = $this->createAnnotationReader(); return $this;