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

Skip to content

Commit 2da896a

Browse files
committed
[ObjectMapper] embed collection transformer
1 parent 94f4d7a commit 2da896a

File tree

6 files changed

+103
-0
lines changed

6 files changed

+103
-0
lines changed
Lines changed: 13 additions & 0 deletions
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+
}
Lines changed: 9 additions & 0 deletions
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+
}
Lines changed: 14 additions & 0 deletions
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+
}
Lines changed: 10 additions & 0 deletions
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

Lines changed: 15 additions & 0 deletions
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
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, plea 9E88 se view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\ObjectMapper\Transform;
13+
14+
use Symfony\Component\ObjectMapper\Exception\MappingException;
15+
use Symfony\Component\ObjectMapper\ObjectMapper;
16+
use Symfony\Component\ObjectMapper\ObjectMapperInterface;
17+
use Symfony\Component\ObjectMapper\TransformCallableInterface;
18+
19+
/**
20+
* @template T of object
21+
*
22+
* @implements TransformCallableInterface<object, T>
23+
*/
24+
class MapCollection implements TransformCallableInterface
25+
{
26+
public function __construct(private ?ObjectMapperInterface $objectMapper = new ObjectMapper())
27+
{
28+
}
29+
30+
public function __invoke(mixed $value, object $source, ?object $target): mixed
31+
{
32+
if (!is_iterable($value)) {
33+
throw new MappingException(sprintf('The MapCollection transform expects an iterable, "%s" given.', get_debug_type($value)));
34+
}
35+
36+
foreach ($value as &$v) {
37+
$v = $this->objectMapper->map($v);
38+
}
39+
40+
return $value;
41+
}
42+
}

0 commit comments

Comments
 (0)
0