Skip to content

Commit 52c92a2

Browse files
committed
[ObjectMapper] allow owning ObjectMapper object
1 parent deac4c6 commit 52c92a2

File tree

3 files changed

+78
-1
lines changed

3 files changed

+78
-1
lines changed

src/Symfony/Component/ObjectMapper/ObjectMapper.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,11 @@ public function __construct(
4040
private readonly ?PropertyAccessorInterface $propertyAccessor = null,
4141
private readonly ?ContainerInterface $transformCallableLocator = null,
4242
private readonly ?ContainerInterface $conditionCallableLocator = null,
43+
private ?ObjectMapperInterface $objectMapper = null,
4344
) {
45+
if (!$objectMapper) {
46+
$objectMapper = $this;
47+
}
4448
}
4549

4650
public function map(object $source, object|string|null $target = null): object
@@ -203,7 +207,7 @@ private function getSourceValue(object $source, object $target, mixed $value, \S
203207
} elseif ($objectMap->contains($value)) {
204208
$value = $objectMap[$value];
205209
} else {
206-
$value = $this->map($value, $mapTo->target);
210+
$value = $this->objectMapper->map($value, $mapTo->target);
207211
}
208212
}
209213

@@ -319,4 +323,9 @@ private function getSourceReflectionClass(object $source, \ReflectionClass $targ
319323

320324
return $targetRefl;
321325
}
326+
327+
public function setObjectMapper(ObjectMapperInterface $objectMapper): void
328+
{
329+
$this->objectMapper = $objectMapper;
330+
}
322331
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\ObjectMapper;
13+
14+
/**
15+
* @experimental
16+
*
17+
* @author Antoine Bluchet <soyuka@gmail.com>
18+
*/
19+
interface ObjectMapperAwareInterface
20+
{
21+
/**
22+
* Sets the owning ObjectMapper object.
23+
*/
24+
public function setObjectMapper(ObjectMapperInterface $objectMapper): void;
25+
}
26+

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

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use Symfony\Component\ObjectMapper\Metadata\ObjectMapperMetadataFactoryInterface;
2121
use Symfony\Component\ObjectMapper\Metadata\ReflectionObjectMapperMetadataFactory;
2222
use Symfony\Component\ObjectMapper\ObjectMapper;
23+
use Symfony\Component\ObjectMapper\ObjectMapperInterface;
2324
use Symfony\Component\ObjectMapper\Tests\Fixtures\A;
2425
use Symfony\Component\ObjectMapper\Tests\Fixtures\B;
2526
use Symfony\Component\ObjectMapper\Tests\Fixtures\C;
@@ -345,4 +346,45 @@ public function testDefaultValueStdClassWithPropertyInfo()
345346
$this->assertSame('abc', $b->id);
346347
$this->assertNull($b->optional);
347348
}
349+
350+
public function testDecorateObjectMapper(): void
351+
{
352+
$mapper = new ObjectMapper();
353+
$myMapper = new class($mapper) implements ObjectMapperInterface {
354+
private ?\SplObjectStorage $embededMap = null;
355+
356+
public function __construct(private readonly ObjectMapperInterface $mapper)
357+
{
358+
$this->embededMap = new \SplObjectStorage();
359+
}
360+
361+
public function map(object $source, object|string|null $target = null): object
362+
{
363+
if (isset($this->embededMap[$source])) {
364+
$target = $this->embededMap[$source];
365+
}
366+
367+
$mapped = $this->mapper->map($source, $target);
368+
$this->embededMap[$source] = $mapped;
369+
return $mapped;
370+
}
371+
};
372+
373+
$mapper->setObjectMapper($myMapper);
374+
375+
$d = new D(baz: 'foo', bat: 'bar');
376+
$c = new C(foo: 'foo', bar: 'bar');
377+
$myNewD = $myMapper->map($c);
378+
379+
$a = new A();
380+
$a->foo = 'test';
381+
$a->transform = 'test';
382+
$a->baz = 'me';
383+
$a->notinb = 'test';
384+
$a->relation = $c;
385+
$a->relationNotMapped = $d;
386+
387+
$b = $mapper->map($a);
388+
$this->assertSame($myNewD, $b->relation);
389+
}
348390
}

0 commit comments

Comments
 (0)