Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 377a6a6

Browse filesBrowse files
committed
[ObjectMapper] condition on the target class name
1 parent d9e5036 commit 377a6a6
Copy full SHA for 377a6a6

File tree

9 files changed

+98
-8
lines changed
Filter options

9 files changed

+98
-8
lines changed

‎src/Symfony/Component/ObjectMapper/Attribute/Map.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/ObjectMapper/Attribute/Map.php
+3-3
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222
readonly class Map
2323
{
2424
/**
25-
* @param string|class-string|null $source The property or the class to map from
26-
* @param string|class-string|null $target The property or the class to map to
27-
* @param string|bool|callable(mixed, object): bool|null $if A boolean, a service id or a callable that instructs whether to map
25+
* @param string|class-string|null $source The property or the class to map from
26+
* @param string|class-string|null $target The property or the class to map to
27+
* @param class-string|string|bool|callable(mixed, object): bool|null $if A boolean, a service id or a callable that instructs whether to map
2828
* @param (string|callable(mixed, object): mixed)|(string|callable(mixed, object): mixed)[]|null $transform A service id or a callable that transforms the value during mapping
2929
*/
3030
public function __construct(

‎src/Symfony/Component/ObjectMapper/ConditionCallableInterface.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/ObjectMapper/ConditionCallableInterface.php
+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ interface ConditionCallableInterface
2424
{
2525
/**
2626
* @param mixed $value The value being mapped
27-
* @param T $object The object we're working on
27+
* @param T $source The object we're working on
2828
*/
29-
public function __invoke(mixed $value, object $object): bool;
29+
public function __invoke(mixed $value, object $source): bool;
3030
}

‎src/Symfony/Component/ObjectMapper/Metadata/Mapping.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/ObjectMapper/Metadata/Mapping.php
+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
/**
2424
* @param string|class-string|null $source The property or the class to map from
2525
* @param string|class-string|null $target The property or the class to map to
26-
* @param string|bool|callable(mixed, object): bool|null $if A boolean, Symfony service name or a callable that instructs whether to map
26+
* @param class-string|string|bool|callable(mixed, object): bool|null $if A boolean, Symfony service name or a callable that instructs whether to map
2727
* @param (string|callable(mixed, object): mixed)|(string|callable(mixed, object): mixed)[]|null $transform A service id or a callable that transform the value during mapping
2828
*/
2929
public function __construct(

‎src/Symfony/Component/ObjectMapper/ObjectMapper.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/ObjectMapper/ObjectMapper.php
+4
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ public function map(object $source, object|string|null $target = null): object
117117
$propertyName = $property->getName();
118118
$mappings = $this->metadataFactory->create($readMetadataFrom, $propertyName);
119119
foreach ($mappings as $mapping) {
120+
if (\is_string($mapping->if) && class_exists($mapping->if) && !$this->conditionCallableLocator?->has($mapping->if) && !is_a($mapping->if, $target, true)) {
121+
continue;
122+
}
123+
120124
$sourcePropertyName = $propertyName;
121125
if ($mapping->source && (!$refl->hasProperty($propertyName) || !isset($source->$propertyName))) {
122126
$sourcePropertyName = $mapping->source;

‎src/Symfony/Component/ObjectMapper/Tests/Fixtures/ClassWithoutTarget.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/ObjectMapper/Tests/Fixtures/ClassWithoutTarget.php
+9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
<?php
22

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+
312
namespace Symfony\Component\ObjectMapper\Tests\Fixtures;
413

514
class ClassWithoutTarget
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\Tests\Fixtures\MultipleTargetProperty;
13+
14+
use Symfony\Component\ObjectMapper\Attribute\Map;
15+
16+
#[Map(target: B::class)]
17+
#[Map(target: C::class)]
18+
class A
19+
{
20+
#[Map(target: 'foo', transform: 'strtoupper', if: B::class)]
21+
#[Map(target: 'bar')]
22+
public string $something = 'test';
23+
24+
public string $doesNotExistInTargetB = 'foo';
25+
}
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\MultipleTargetProperty;
13+
14+
class B
15+
{
16+
public string $foo;
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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\MultipleTargetProperty;
13+
14+
class C
15+
{
16+
public string $foo = 'donotmap';
17+
public string $bar;
18+
public string $doesNotExistInTargetB;
19+
}

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/ObjectMapper/Tests/ObjectMapperTest.php
+18-2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@
3838
use Symfony\Component\ObjectMapper\Tests\Fixtures\MapStruct\MapStructMapperMetadataFactory;
3939
use Symfony\Component\ObjectMapper\Tests\Fixtures\MapStruct\Source;
4040
use Symfony\Component\ObjectMapper\Tests\Fixtures\MapStruct\Target;
41+
use Symfony\Component\ObjectMapper\Tests\Fixtures\MultipleTargetProperty\A as MultipleTargetPropertyA;
42+
use Symfony\Component\ObjectMapper\Tests\Fixtures\MultipleTargetProperty\B as MultipleTargetPropertyB;
43+
use Symfony\Component\ObjectMapper\Tests\Fixtures\MultipleTargetProperty\C as MultipleTargetPropertyC;
4144
use Symfony\Component\ObjectMapper\Tests\Fixtures\MultipleTargets\A as MultipleTargetsA;
4245
use Symfony\Component\ObjectMapper\Tests\Fixtures\MultipleTargets\C as MultipleTargetsC;
4346
use Symfony\Component\ObjectMapper\Tests\Fixtures\Recursion\AB;
@@ -194,7 +197,7 @@ public function testServiceLocator()
194197

195198
protected function getServiceLocator(array $factories): ContainerInterface
196199
{
197-
return new class ($factories) implements ContainerInterface {
200+
return new class($factories) implements ContainerInterface {
198201
public function __construct(private array $factories)
199202
{
200203
}
@@ -244,7 +247,7 @@ public function testTransformToWrongValueType()
244247
$u->foo = 'bar';
245248

246249
$metadata = $this->createStub(ObjectMapperMetadataFactoryInterface::class);
247-
$metadata->method('create')->with($u)->willReturn([new Mapping(target: \stdClass::class, transform: fn() => 'str')]);
250+
$metadata->method('create')->with($u)->willReturn([new Mapping(target: \stdClass::class, transform: fn () => 'str')]);
248251
$mapper = new ObjectMapper($metadata);
249252
$mapper->map($u);
250253
}
@@ -262,4 +265,17 @@ public function testTransformToWrongObject()
262265
$mapper = new ObjectMapper($metadata);
263266
$mapper->map($u);
264267
}
268+
269+
public function testMultipleTargetMapProperty(): void
270+
{
271+
$u = new MultipleTargetPropertyA();
272+
273+
$mapper = new ObjectMapper();
274+
$this->assertInstanceOf(MultipleTargetPropertyB::class, $mapper->map($u, MultipleTargetPropertyB::class));
275+
$c = $mapper->map($u, MultipleTargetPropertyC::class);
276+
$this->assertInstanceOf(MultipleTargetPropertyC::class, $c);
277+
$this->assertEquals($c->bar, 'test');
278+
$this->assertEquals($c->foo, 'donotmap');
279+
$this->assertEquals($c->doesNotExistInTargetB, 'foo');
280+
}
265281
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.