From 472a37d832656c033245beb63d9d3f5ce84b5531 Mon Sep 17 00:00:00 2001 From: Joel Wurtz Date: Tue, 12 Mar 2024 21:55:43 +0100 Subject: [PATCH] feat(transformer): tag custom transfer to be automatically injected --- composer.json | 3 - .../AutoMapperExtension.php | 5 ++ .../Compiler/TransformerFactoryPass.php | 11 ++++ src/Resources/config/custom_transformers.xml | 5 ++ tests/Resources/App/AppKernel.php | 55 ++++++++++++++----- tests/Resources/App/config.yml | 1 + 6 files changed, 64 insertions(+), 16 deletions(-) diff --git a/composer.json b/composer.json index 8336438..ccc4e1d 100644 --- a/composer.json +++ b/composer.json @@ -29,9 +29,6 @@ "symfony/uid": "^6.3 || ^7.0", "symfony/yaml": "^6.3 || ^7.0" }, - "conflict": { - "symfony/framework-bundle": "5.1.0" - }, "autoload": { "psr-4": { "AutoMapper\\Bundle\\": "src/" diff --git a/src/DependencyInjection/AutoMapperExtension.php b/src/DependencyInjection/AutoMapperExtension.php index ae492fc..3adc52b 100644 --- a/src/DependencyInjection/AutoMapperExtension.php +++ b/src/DependencyInjection/AutoMapperExtension.php @@ -13,6 +13,7 @@ use AutoMapper\MapperGeneratorMetadataFactory; use AutoMapper\MapperGeneratorMetadataInterface; use AutoMapper\Normalizer\AutoMapperNormalizer; +use AutoMapper\Transformer\CustomTransformer\CustomTransformerInterface; use AutoMapper\Transformer\CustomTransformer\CustomTransformersRegistry; use AutoMapper\Transformer\SymfonyUidTransformerFactory; use AutoMapper\Transformer\TransformerFactoryInterface; @@ -59,6 +60,10 @@ public function load(array $configs, ContainerBuilder $container): void $container->getDefinition(FileLoader::class)->replaceArgument(2, $config['hot_reload']); $container->registerForAutoconfiguration(TransformerFactoryInterface::class)->addTag('automapper.transformer_factory'); + if (interface_exists(CustomTransformerInterface::class)) { + $container->registerForAutoconfiguration(CustomTransformerInterface::class)->addTag('automapper.custom_transformer'); + } + if (class_exists(AbstractUid::class)) { $container ->getDefinition(SymfonyUidTransformerFactory::class) diff --git a/src/DependencyInjection/Compiler/TransformerFactoryPass.php b/src/DependencyInjection/Compiler/TransformerFactoryPass.php index 8bb4fad..fd02ce9 100644 --- a/src/DependencyInjection/Compiler/TransformerFactoryPass.php +++ b/src/DependencyInjection/Compiler/TransformerFactoryPass.php @@ -4,6 +4,9 @@ use AutoMapper\Generator\Generator; use AutoMapper\Transformer\ChainTransformerFactory; +use AutoMapper\Transformer\CustomTransformer\CustomTransformerFactory; +use AutoMapper\Transformer\CustomTransformer\CustomTransformerInterface; +use AutoMapper\Transformer\CustomTransformer\CustomTransformersRegistry; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -29,5 +32,13 @@ public function process(ContainerBuilder $container): void } else { $definition->replaceArgument(0, $selectors); } + + if (interface_exists(CustomTransformerInterface::class)) { + $registry = $container->getDefinition(CustomTransformersRegistry::class); + + foreach ($this->findAndSortTaggedServices('automapper.custom_transformer', $container) as $definition) { + $registry->addMethodCall('addCustomTransformer', [$definition]); + } + } } } diff --git a/src/Resources/config/custom_transformers.xml b/src/Resources/config/custom_transformers.xml index 9cfc64c..d8aded4 100644 --- a/src/Resources/config/custom_transformers.xml +++ b/src/Resources/config/custom_transformers.xml @@ -5,5 +5,10 @@ + + + + + diff --git a/tests/Resources/App/AppKernel.php b/tests/Resources/App/AppKernel.php index f015b49..329522a 100644 --- a/tests/Resources/App/AppKernel.php +++ b/tests/Resources/App/AppKernel.php @@ -13,6 +13,9 @@ use AutoMapper\Bundle\Tests\Fixtures\UserDTO; use AutoMapper\MapperGeneratorMetadataInterface; use AutoMapper\MapperMetadata; +use AutoMapper\Transformer\CustomTransformer\CustomModelTransformer; +use AutoMapper\Transformer\CustomTransformer\CustomModelTransformerInterface; +use AutoMapper\Transformer\CustomTransformer\CustomPropertyTransformerInterface; use Symfony\Bundle\FrameworkBundle\FrameworkBundle; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\Config\Loader\LoaderInterface; @@ -59,27 +62,53 @@ public function getProjectDir(): string } } -class UserMapperConfiguration implements MapperConfigurationInterface -{ - public function getSource(): string +if (interface_exists(CustomPropertyTransformerInterface::class)) { + class YearOfBirthTransformer implements CustomPropertyTransformerInterface { - return User::class; + public function transform(object|array $user): mixed + { + assert($user instanceof User); + + return ((int) date('Y')) - ((int) $user->age); + } + + public function supports(string $source, string $target, string $propertyName): bool + { + return User::class === $source && UserDTO::class === $target && 'yearOfBirth' === $propertyName; + } } - public function getTarget(): string + class UserMapperConfiguration { - return UserDTO::class; - } - public function process(MapperGeneratorMetadataInterface $metadata): void + } +} else { + class UserMapperConfiguration implements MapperConfigurationInterface { - if (!$metadata instanceof MapperMetadata) { - return; + public function getSource(): string + { + return User::class; } - $metadata->forMember('yearOfBirth', function (User $user) { - return ((int) date('Y')) - ((int) $user->age); - }); + public function getTarget(): string + { + return UserDTO::class; + } + + public function process(MapperGeneratorMetadataInterface $metadata): void + { + if (!$metadata instanceof MapperMetadata) { + return; + } + + $metadata->forMember('yearOfBirth', function (User $user) { + return ((int) date('Y')) - ((int) $user->age); + }); + } + } + + class YearOfBirthTransformer + { } } diff --git a/tests/Resources/App/config.yml b/tests/Resources/App/config.yml index 6894e6a..42c8b34 100644 --- a/tests/Resources/App/config.yml +++ b/tests/Resources/App/config.yml @@ -14,6 +14,7 @@ services: _defaults: autoconfigure: true + DummyApp\YearOfBirthTransformer: ~ DummyApp\UserMapperConfiguration: ~ DummyApp\IdNameConverter: ~ AutoMapper\Bundle\Tests\Resources\App\Transformer\MoneyTransformerFactory: ~