8000 [ObjectMapper] embed collection transformer · symfony/symfony@15526dd · GitHub
[go: up one dir, main page]

Skip to content

Commit 15526dd

Browse files
committed
[ObjectMapper] embed collection transformer
1 parent 94f4d7a commit 15526dd

File tree

6 files changed

+95
-0
lines changed

6 files changed

+95
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace Symfony\Component\ObjectMapper\Tests\Fixtures\TransformCollection;
4+
5+
use Symfony\Component\ObjectMapper\Attribute\Map;
6+
use Symfony\Component\ObjectMapper\Transform\MapCollection;
7+
8+
class A
9+
{
10+
#[Map(transform: new MapCollection())]
11+
/** @var C[] */
12+
public array $foo;
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace Symfony\Component\ObjectMapper\Tests\Fixtures\TransformCollection;
4+
5+
class B
6+
{
7+
/** @var D[] */
8+
public array $foo;
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace Symfony\Component\ObjectMapper\Tests\Fixtures\TransformCollection;
4+
5+
use Symfony\Component\ObjectMapper\Attribute\Map;
6+
7+
#[Map(target: D::class)]
8+
class C
9+
{
10+
public function __construct(
11+
#[Map(target: 'baz')]
12+
public string $bar
13+
) {}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Symfony\Component\ObjectMapper\Tests\Fixtures\TransformCollection;
4+
5+
class D
6+
{
7+
public function __construct(
8+
public string $baz
9+
) {}
10+
}

src/Symfony/Component/ObjectMapper/Tests/ObjectMapperTest.php

+15
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@
5151
use Symfony\Component\ObjectMapper\Tests\Fixtures\ServiceLocator\B as ServiceLocatorB;
5252
use Symfony\Component\ObjectMapper\Tests\Fixtures\ServiceLocator\ConditionCallable;
5353
use Symfony\Component\ObjectMapper\Tests\Fixtures\ServiceLocator\TransformCallable;
54+
use Symfony\Component\ObjectMapper\Tests\Fixtures\TransformCollection\A as TransformCollectionA;
55+
use Symfony\Component\ObjectMapper\Tests\Fixtures\TransformCollection\B as TransformCollectionB;
56+
use Symfony\Component\ObjectMapper\Tests\Fixtures\TransformCollection\C as TransformCollectionC;
57+
use Symfony\Component\ObjectMapper\Tests\Fixtures\TransformCollection\D as TransformCollectionD;
5458
use Symfony\Component\PropertyAccess\PropertyAccess;
5559

5660
final class ObjectMapperTest extends TestCase
@@ -291,4 +295,15 @@ public function testMultipleTargetMapProperty()
291295
$this->assertEquals($c->foo, 'donotmap');
292296
$this->assertEquals($c->doesNotExistInTargetB, 'foo');
293297
}
298+
299+
public function testTransformCollection()
300+
{
301+
$u = new TransformCollectionA();
302+
$u->foo = [new TransformCollectionC('a'), new TransformCollectionC('b')];
303+
$mapper = new ObjectMapper();
304+
305+
$transformed = $mapper->map($u, TransformCollectionB::class);
306+
307+
$this->assertEquals($transformed->foo, [new TransformCollectionD('a'), new TransformCollectionD('b')]);
308+
}
294309
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
namespace Symfony\Component\ObjectMapper\Transform;
4+
5+
use Symfony\Component\ObjectMapper\Exception\MappingException;
6+
use Symfony\Component\ObjectMapper\ObjectMapper;
7+
use Symfony\Component\ObjectMapper\ObjectMapperInterface;
8+
use Symfony\Component\ObjectMapper\TransformCallableInterface;
9+
10+
/**
11+
* @template T of object
12+
*
13+
* @implements TransformCallableInterface<object, T>
14+
*/
15+
class MapCollection implements TransformCallableInterface
16+
{
17+
public function __construct(private ?ObjectMapperInterface $objectMapper = null)
18+
{
19+
$this->objectMapper ??= new ObjectMapper();
20+
}
21+
22+
public function __invoke(mixed $value, object $source, ?object $target): mixed
23+
{
24+
if (!is_iterable($value)) {
25+
throw new MappingException(sprintf('The MapCollection transform expects an iterable, "%s" given.', get_debug_type($value)));
26+
}
27+
28+
foreach ($value as &$v) {
29+
$v = $this->objectMapper->map($v);
30+
}
31+
32+
return $value;
33+
}
34+
}

0 commit comments

Comments
 (0)
0