Skip to content

Commit f1f7ef0

Browse files
authored
Merge pull request #316 from jolicode/feat/invokable-transformer
feat(transformer): allow to pass invokable object in transformer
2 parents 6c8aff8 + 1a5ea0e commit f1f7ef0

File tree

5 files changed

+47
-1
lines changed

5 files changed

+47
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414
- [GH#304](https://github.com/jolicode/automapper/pull/304) ; Allow to override source and/or target property type
1515
- Add support for static callable in attribute transformer
1616
- Initial support for nested properties
17+
- Add support for object invokable transformer in attribute transformer
1718

1819
### Changed
1920
- [BC Break] `PropertyTransformerSupportInterface` does not use a `TypesMatching` anymore, you can get the type directly from `SourcePropertyMetadata` or `TargetPropertyMetadata`.

src/EventListener/MapListener.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,10 @@ protected function getTransformerFromMapAttribute(string $class, MapTo|MapFrom $
4747
$transformer = new ReferenceTransformer($reference);
4848
} elseif (\is_string($transformerCallable) && $this->serviceLocator->has($transformerCallable) && ($customTransformer = $this->serviceLocator->get($transformerCallable)) && $customTransformer instanceof PropertyTransformerInterface) {
4949
$transformer = new PropertyTransformer($transformerCallable);
50-
} elseif (\is_callable($transformerCallable, false, $callableName)) {
50+
} elseif (!\is_object($transformerCallable) && \is_callable($transformerCallable, false, $callableName)) {
5151
$transformer = new CallableTransformer($callableName);
52+
} elseif (\is_object($transformerCallable) && \is_callable($transformerCallable)) {
53+
$transformer = new ReferenceTransformer($reference);
5254
} elseif (\is_string($transformerCallable) && method_exists($class, $transformerCallable)) {
5355
$reflMethod = new \ReflectionMethod($class, $transformerCallable);
5456

tests/AutoMapperTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
use AutoMapper\Tests\Fixtures\Dog;
3131
use AutoMapper\Tests\Fixtures\Fish;
3232
use AutoMapper\Tests\Fixtures\FooGenerator;
33+
use AutoMapper\Tests\Fixtures\FooTransformerObjectCallable;
3334
use AutoMapper\Tests\Fixtures\FooTransformerStaticCallable;
3435
use AutoMapper\Tests\Fixtures\HasDateTime;
3536
use AutoMapper\Tests\Fixtures\HasDateTimeImmutable;
@@ -1388,6 +1389,16 @@ public function testStaticCallable(): void
13881389
self::assertSame(['foo' => 'bar'], $array);
13891390
}
13901391

1392+
public function testObjectInvokableCallable(): void
1393+
{
1394+
$foo = new FooTransformerObjectCallable();
1395+
$foo->foo = 'foo';
1396+
1397+
$array = $this->autoMapper->map($foo, 'array');
1398+
1399+
self::assertSame(['foo' => 'test'], $array);
1400+
}
1401+
13911402
public static function provideAutoMapperFixturesTests(): iterable
13921403
{
13931404
$directories = (new Finder())
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace AutoMapper\Tests\Fixtures;
6+
7+
use AutoMapper\Attribute\MapTo;
8+
use AutoMapper\Tests\Fixtures\Transformer\CustomTransformer\InvokableTransformer;
9+
10+
class FooTransformerObjectCallable
11+
{
12+
#[MapTo(target: 'array', transformer: new InvokableTransformer('test'))]
13+
public string $foo;
14+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace AutoMapper\Tests\Fixtures\Transformer\CustomTransformer;
6+
7+
class InvokableTransformer
8+
{
9+
public function __construct(
10+
private string $value,
11+
) {
12+
}
13+
14+
public function __invoke(mixed $value, object|array $source, array $context): string
15+
{
16+
return $this->value;
17+
}
18+
}

0 commit comments

Comments
 (0)