Skip to content

Commit 50e177d

Browse files
committed
[ObjectMapper] read source metadata before transform
fixes #61027
1 parent b4e3bca commit 50e177d

File tree

4 files changed

+67
-0
lines changed

4 files changed

+67
-0
lines changed

src/Symfony/Component/ObjectMapper/ObjectMapper.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@ public function map(object $source, object|string|null $target = null): object
7272
}
7373

7474
$mappedTarget = $mappingToObject ? $target : $targetRefl->newInstanceWithoutConstructor();
75+
76+
if (!$metadata && ($targetMetadata = $this->metadataFactory->create($mappedTarget))) {
77+
$metadata = $targetMetadata;
78+
$map = $this->getMapTarget($metadata, null, $source, null);
79+
}
80+
7581
if ($map && $map->transform) {
7682
$mappedTarget = $this->applyTransforms($map, $mappedTarget, $source, null);
7783

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
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\Tests\Fixtures\TargetTransform;
13+
14+
class SourceEntity
15+
{
16+
public string $name;
17+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
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\Tests\Fixtures\TargetTransform;
13+
14+
use Symfony\Component\ObjectMapper\Attribute\Map;
15+
16+
#[Map(source: SourceEntity::class, transform: [self::class, 't'])]
17+
class TargetDto
18+
{
19+
#[Map(if: false)]
20+
public bool $transformed;
21+
public string $name;
22+
23+
public static function t(mixed $value, object $source, ?object $target)
24+
{
25+
$value->transformed = true;
26+
27+
return $value;
28+
}
29+
}

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@
6464
use Symfony\Component\ObjectMapper\Tests\Fixtures\ServiceLocator\B as ServiceLocatorB;
6565
use Symfony\Component\ObjectMapper\Tests\Fixtures\ServiceLocator\ConditionCallable;
6666
use Symfony\Component\ObjectMapper\Tests\Fixtures\ServiceLocator\TransformCallable;
67+
use Symfony\Component\ObjectMapper\Tests\Fixtures\TargetTransform\SourceEntity;
68+
use Symfony\Component\ObjectMapper\Tests\Fixtures\TargetTransform\TargetDto as TargetTransformTargetDto;
6769
use Symfony\Component\PropertyAccess\PropertyAccess;
6870

6971
final class ObjectMapperTest extends TestCase
@@ -447,4 +449,17 @@ public static function validPartialInputProvider(): iterable
447449

448450
yield [$p, $f];
449451
}
452+
453+
public function testMapWithSourceTransform()
454+
{
455+
$source = new SourceEntity();
456+
$source->name = 'test';
457+
458+
$mapper = new ObjectMapper();
459+
$target = $mapper->map($source, TargetTransformTargetDto::class);
460+
461+
$this->assertInstanceOf(TargetTransformTargetDto::class, $target);
462+
$this->assertTrue($target->transformed);
463+
$this->assertSame('test', $target->name);
464+
}
450465
}

0 commit comments

Comments
 (0)