diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 0b66e79..2170aa9 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -52,4 +52,4 @@ jobs:
env:
SYMFONY_REQUIRE: "${{ matrix.symfony-versions }}"
- name: tests
- run: vendor/bin/phpunit
+ run: SYMFONY_DEPRECATIONS_HELPER="disabled=1" vendor/bin/simple-phpunit
diff --git a/composer.json b/composer.json
index 3445174..8336438 100644
--- a/composer.json
+++ b/composer.json
@@ -23,14 +23,14 @@
},
"require-dev": {
"moneyphp/money": "^4.2",
- "phpunit/phpunit": "^8.0",
+ "nikic/php-parser": "^4.18 || ^5.0",
"symfony/framework-bundle": "^6.0 || ^7.0",
+ "symfony/phpunit-bridge": "^7.0",
"symfony/uid": "^6.3 || ^7.0",
"symfony/yaml": "^6.3 || ^7.0"
},
"conflict": {
- "symfony/framework-bundle": "5.1.0",
- "jolicode/automapper": ">=8.2"
+ "symfony/framework-bundle": "5.1.0"
},
"autoload": {
"psr-4": {
diff --git a/src/DependencyInjection/AutoMapperExtension.php b/src/DependencyInjection/AutoMapperExtension.php
index aad57e0..3adc52b 100644
--- a/src/DependencyInjection/AutoMapperExtension.php
+++ b/src/DependencyInjection/AutoMapperExtension.php
@@ -2,6 +2,7 @@
namespace AutoMapper\Bundle\DependencyInjection;
+use AutoMapper\Bundle\AutoMapper;
use AutoMapper\Bundle\CacheWarmup\CacheWarmerLoaderInterface;
use AutoMapper\Bundle\CacheWarmup\ConfigurationCacheWarmerLoader;
use AutoMapper\Bundle\Configuration\MapperConfigurationInterface;
@@ -12,6 +13,8 @@
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;
use Symfony\Component\Config\Definition\ConfigurationInterface;
@@ -38,7 +41,16 @@ public function load(array $configs, ContainerBuilder $container): void
$container->registerForAutoconfiguration(MapperConfigurationInterface::class)->addTag('automapper.mapper_configuration');
$loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
- $loader->load('services.xml');
+
+ if (class_exists(Generator::class)) {
+ $loader->load('generator.xml');
+ $loader->load('services.xml');
+ } else {
+ // AutoMapper 8.2
+ $loader->load('mapper_generator.xml');
+ $loader->load('custom_transformers.xml');
+ $loader->load('services_82.xml');
+ }
$container->getDefinition(MapperGeneratorMetadataFactory::class)
->replaceArgument(5, $config['date_time_format'])
@@ -48,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)
@@ -70,7 +86,16 @@ public function load(array $configs, ContainerBuilder $container): void
->addArgument(new Reference($config['name_converter']));
}
- if ($config['allow_readonly_target_to_populate']) {
+ if (class_exists(CustomTransformersRegistry::class)) {
+ $autoMapperDefinition = $container->getDefinition(AutoMapper::class);
+
+ $mapperDefinition = $autoMapperDefinition->getArgument(2);
+
+ $autoMapperDefinition->replaceArgument(2, new Reference(CustomTransformersRegistry::class));
+ $autoMapperDefinition->addArgument($mapperDefinition);
+ }
+
+ if (class_exists(Generator::class) && $config['allow_readonly_target_to_populate']) {
$container
->getDefinition(Generator::class)
->replaceArgument(2, $config['allow_readonly_target_to_populate']);
diff --git a/src/DependencyInjection/Compiler/PropertyInfoPass.php b/src/DependencyInjection/Compiler/PropertyInfoPass.php
index 1a2f1e8..a268f82 100644
--- a/src/DependencyInjection/Compiler/PropertyInfoPass.php
+++ b/src/DependencyInjection/Compiler/PropertyInfoPass.php
@@ -25,6 +25,10 @@ public function process(ContainerBuilder $container): void
new Definition(
ReflectionExtractor::class,
[
+ '$mutatorPrefixes' => null,
+ '$accessorPrefixes' => null,
+ '$arrayMutatorPrefixes' => null,
+ '$enableConstructorExtraction' => true,
'$accessFlags' => ReflectionExtractor::ALLOW_PUBLIC | ReflectionExtractor::ALLOW_PROTECTED | ReflectionExtractor::ALLOW_PRIVATE,
]
)
diff --git a/src/DependencyInjection/Compiler/TransformerFactoryPass.php b/src/DependencyInjection/Compiler/TransformerFactoryPass.php
index a12e69a..49c900d 100644
--- a/src/DependencyInjection/Compiler/TransformerFactoryPass.php
+++ b/src/DependencyInjection/Compiler/TransformerFactoryPass.php
@@ -2,7 +2,10 @@
namespace AutoMapper\Bundle\DependencyInjection\Compiler;
+use AutoMapper\Generator\Generator;
use AutoMapper\Transformer\ChainTransformerFactory;
+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;
@@ -13,10 +16,28 @@ class TransformerFactoryPass implements CompilerPassInterface
public function process(ContainerBuilder $container): void
{
+ $selectors = [];
+
+ foreach ($this->findAndSortTaggedServices('automapper.transformer_factory', $container) as $definition) {
+ $selectors[] = $definition;
+ }
+
$definition = $container->getDefinition(ChainTransformerFactory::class);
- foreach ($this->findAndSortTaggedServices('automapper.transformer_factory', $container) as $factory) {
- $definition->addMethodCall('addTransformerFactory', [$factory]);
+ if (class_exists(Generator::class)) {
+ foreach ($selectors as $selector) {
+ $definition->addMethodCall('addTransformerFactory', [$selector]);
+ }
+ } 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
new file mode 100644
index 0000000..d8aded4
--- /dev/null
+++ b/src/Resources/config/custom_transformers.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Resources/config/generator.xml b/src/Resources/config/generator.xml
new file mode 100644
index 0000000..a175e05
--- /dev/null
+++ b/src/Resources/config/generator.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+ %automapper.cache_dir%
+
+
+
+
+ null
+
+ false
+
+
+
diff --git a/src/Resources/config/mapper_generator.xml b/src/Resources/config/mapper_generator.xml
new file mode 100644
index 0000000..2b6a8c3
--- /dev/null
+++ b/src/Resources/config/mapper_generator.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+ %automapper.cache_dir%
+
+
+
+
+
+ false
+
+
+
+
+
+
+
diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml
index eba5e4b..ed61a68 100644
--- a/src/Resources/config/services.xml
+++ b/src/Resources/config/services.xml
@@ -46,20 +46,9 @@
-
-
- %automapper.cache_dir%
-
-
-
- null
-
- false
-
-
-
+
diff --git a/src/Resources/config/services_82.xml b/src/Resources/config/services_82.xml
new file mode 100644
index 0000000..a364ad5
--- /dev/null
+++ b/src/Resources/config/services_82.xml
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Symfony_Mapper_
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ %automapper.cache_dir%
+
+
+
+
+
+
+
+
+
diff --git a/tests/Resources/App/AppKernel.php b/tests/Resources/App/AppKernel.php
index f015b49..aa5c462 100644
--- a/tests/Resources/App/AppKernel.php
+++ b/tests/Resources/App/AppKernel.php
@@ -13,14 +13,12 @@
use AutoMapper\Bundle\Tests\Fixtures\UserDTO;
use AutoMapper\MapperGeneratorMetadataInterface;
use AutoMapper\MapperMetadata;
+use AutoMapper\Transformer\CustomTransformer\CustomPropertyTransformerInterface;
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
-use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Kernel;
-use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
-use Symfony\Component\Routing\Route;
use Symfony\Component\Serializer\NameConverter\AdvancedNameConverterInterface;
class AppKernel extends Kernel
@@ -37,49 +35,63 @@ public function registerBundles(): array
return $bundles;
}
- private function configureRoutes(RoutingConfigurator $routes): void
- {
- $route = new Route('/', ['_controller' => 'kernel::indexAction']);
- $routes->collection->add('index_action', $route);
- }
-
protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader): void
{
$loader->load(__DIR__ . '/config.yml');
}
- public function indexAction(): Response
- {
- return new Response();
- }
-
public function getProjectDir(): string
{
return __DIR__ . '/..';
}
}
-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: ~
diff --git a/tests/ServiceInstantiationTest.php b/tests/ServiceInstantiationTest.php
index 510b211..481d069 100644
--- a/tests/ServiceInstantiationTest.php
+++ b/tests/ServiceInstantiationTest.php
@@ -44,7 +44,7 @@ public function testWarmup(): void
self::assertInstanceOf(\Symfony_Mapper_AutoMapper_Bundle_Tests_Fixtures_AddressDTO_array::class, new \Symfony_Mapper_AutoMapper_Bundle_Tests_Fixtures_AddressDTO_array());
}
- public function testAutoMapper()
+ public function testAutoMapper(): void
{
static::bootKernel();
$container = static::$kernel->getContainer();