Skip to content

Commit deabf9a

Browse files
committed
[ObjectMapper] allow owning ObjectMapper object
1 parent 2f180d4 commit deabf9a

File tree

4 files changed

+84
-2
lines changed

4 files changed

+84
-2
lines changed

src/Symfony/Component/ObjectMapper/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
7.4
5+
---
6+
7+
* ObjectMapperAwareInterface to set the owning object mapper instance
8+
49
7.3
510
---
611

src/Symfony/Component/ObjectMapper/ObjectMapper.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
*
2929
* @author Antoine Bluchet <soyuka@gmail.com>
3030
*/
31-
final class ObjectMapper implements ObjectMapperInterface
31+
final class ObjectMapper implements ObjectMapperInterface, ObjectMapperAwareInterface
3232
{
3333
/**
3434
* Tracks recursive references.
@@ -40,6 +40,7 @@ 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
) {
4445
}
4546

@@ -203,7 +204,7 @@ private function getSourceValue(object $source, object $target, mixed $value, \S
203204
} elseif ($objectMap->contains($value)) {
204205
$value = $objectMap[$value];
205206
} else {
206-
$value = $this->map($value, $mapTo->target);
207+
$value = ($this->objectMapper ?? $this)->map($value, $mapTo->target);
207208
}
208209
}
209210

@@ -319,4 +320,12 @@ private function getSourceReflectionClass(object $source, \ReflectionClass $targ
319320

320321
return $targetRefl;
321322
}
323+
324+
public function withObjectMapper(ObjectMapperInterface $objectMapper): static
325+
{
326+
$clone = clone $this;
327+
$clone->objectMapper = $objectMapper;
328+
329+
return $clone;
330+
}
322331
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
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 withObjectMapper(ObjectMapperInterface $objectMapper): static;
25+
}

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

Lines changed: 43 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,46 @@ public function testDefaultValueStdClassWithPropertyInfo()
345346
$this->assertSame('abc', $b->id);
346347
$this->assertNull($b->optional);
347348
}
349+
350+
public function testDecorateObjectMapper()
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+
370+
return $mapped;
371+
}
372+
};
373+
374+
$mapper = $mapper->withObjectMapper($myMapper);
375+
376+
$d = new D(baz: 'foo', bat: 'bar');
377+
$c = new C(foo: 'foo', bar: 'bar');
378+
$myNewD = $myMapper->map($c);
379+
380+
$a = new A();
381+
$a->foo = 'test';
382+
$a->transform = 'test';
383+
$a->baz = 'me';
384+
$a->notinb = 'test';
385+
$a->relation = $c;
386+
$a->relationNotMapped = $d;
387+
388+
$b = $mapper->map($a);
389+
$this->assertSame($myNewD, $b->relation);
390+
}
348391
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy