Skip to content
This repository has been archived by the owner on May 16, 2024. It is now read-only.

Commit

Permalink
feat(transformer): tag custom transfer to be automatically injected
Browse files Browse the repository at this point in the history
  • Loading branch information
joelwurtz committed Mar 12, 2024
1 parent aa31e55 commit 472a37d
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 16 deletions.
3 changes: 0 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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/"
Expand Down
5 changes: 5 additions & 0 deletions src/DependencyInjection/AutoMapperExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
11 changes: 11 additions & 0 deletions src/DependencyInjection/Compiler/TransformerFactoryPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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]);
}
}
}
}
5 changes: 5 additions & 0 deletions src/Resources/config/custom_transformers.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,10 @@

<services>
<service id="AutoMapper\Transformer\CustomTransformer\CustomTransformersRegistry" />

<service id="AutoMapper\Transformer\CustomTransformer\CustomTransformerFactory">
<argument type="service" id="AutoMapper\Transformer\CustomTransformer\CustomTransformersRegistry" />
<tag name="automapper.transformer_factory" priority="1003" />
</service>
</services>
</container>
55 changes: 42 additions & 13 deletions tests/Resources/App/AppKernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
{
}
}

Expand Down
1 change: 1 addition & 0 deletions tests/Resources/App/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ services:
_defaults:
autoconfigure: true

DummyApp\YearOfBirthTransformer: ~
DummyApp\UserMapperConfiguration: ~
DummyApp\IdNameConverter: ~
AutoMapper\Bundle\Tests\Resources\App\Transformer\MoneyTransformerFactory: ~

0 comments on commit 472a37d

Please sign in to comment.