Skip to content

Commit 51ee4ed

Browse files
committed
bug #61233 [ObjectMapper] skip reading uninitialized values (soyuka)
This PR was merged into the 7.3 branch. Discussion ---------- [ObjectMapper] skip reading uninitialized values | Q | A | ------------- | --- | Branch? | 7.3 | Bug fix? | yes | Issues | Fix #60786 | License | MIT The mapper would read uninitialized properties, for example this would throw trying to read `name`: ```php #[Map(target: FinalInput::class)] class PartialInput { public string $uuid; public string $name; public ?string $email; public ?string $website; } $p = new PartialInput; $p->uuid = '6a9eb6dd-c4dc-4746-bb99-f6bad716acb2'; $p->website = 'https://updated.website.com'; $mapper = new ObjectMapper(); $mapper->map($p); ``` Commits ------- b7bd80f [ObjectMapper] skip reading uninitialized values
2 parents cf7da9e + b7bd80f commit 51ee4ed

File tree

4 files changed

+75
-0
lines changed

4 files changed

+75
-0
lines changed

src/Symfony/Component/ObjectMapper/ObjectMapper.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@ public function map(object $source, object|string|null $target = null): object
144144
}
145145

146146
if (!$mappings && $targetRefl->hasProperty($propertyName)) {
147+
$sourceProperty = $refl->getProperty($propertyName);
148+
if ($refl->isInstance($source) && !$sourceProperty->isInitialized($source)) {
149+
continue;
150+
}
151+
147152
$value = $this->getSourceValue($source, $mappedTarget, $this->getRawValue($source, $propertyName), $this->objectMap);
148153
$this->storeValue($propertyName, $mapToProperties, $ctorArguments, $value);
149154
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Symfony\Component\ObjectMapper\Tests\Fixtures\PartialInput;
4+
5+
class FinalInput
6+
{
7+
public string $uuid;
8+
public string $name;
9+
public ?string $email = null;
10+
public ?string $website = null;
11+
}
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\PartialInput;
4+
5+
use Symfony\Component\ObjectMapper\Attribute\Map;
6+
7+
#[Map(target: FinalInput::class)]
8+
class PartialInput
9+
{
10+
public string $uuid;
11+
public string $name;
12+
public ?string $email;
13+
public ?string $website;
14+
}

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

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@
5454
use Symfony\Component\ObjectMapper\Tests\Fixtures\MultipleTargets\A as MultipleTargetsA;
5555
use Symfony\Component\ObjectMapper\Tests\Fixtures\MultipleTargets\C as MultipleTargetsC;
5656
use Symfony\Component\ObjectMapper\Tests\Fixtures\MyProxy;
57+
use Symfony\Component\ObjectMapper\Tests\Fixtures\PartialInput\FinalInput;
58+
use Symfony\Component\ObjectMapper\Tests\Fixtures\PartialInput\PartialInput;
5759
use Symfony\Component\ObjectMapper\Tests\Fixtures\PromotedConstructor\Source as PromotedConstructorSource;
5860
use Symfony\Component\ObjectMapper\Tests\Fixtures\PromotedConstructor\Target as PromotedConstructorTarget;
5961
use Symfony\Component\ObjectMapper\Tests\Fixtures\Recursion\AB;
@@ -402,4 +404,47 @@ public function testMapInitializesNativePhp84LazyObject()
402404
$this->assertSame('test', $d->name);
403405
$this->assertTrue($initialized);
404406
}
407+
408+
/**
409+
* @dataProvider validPartialInputProvider
410+
*/
411+
public function testMapPartially(PartialInput $actual, FinalInput $expected)
412+
{
413+
$mapper = new ObjectMapper();
414+
$this->assertEquals($expected, $mapper->map($actual));
415+
}
416+
417+
public static function validPartialInputProvider(): iterable
418+
{
419+
$p = new PartialInput();
420+
$p->uuid = '6a9eb6dd-c4dc-4746-bb99-f6bad716acb2';
421+
$p->website = 'https://updated.website.com';
422+
423+
$f = new FinalInput();
424+
$f->uuid = $p->uuid;
425+
$f->website = $p->website;
426+
427+
yield [$p, $f];
428+
429+
$p = new PartialInput();
430+
$p->uuid = '6a9eb6dd-c4dc-4746-bb99-f6bad716acb2';
431+
$p->website = null;
432+
433+
$f = new FinalInput();
434+
$f->uuid = $p->uuid;
435+
436+
yield [$p, $f];
437+
438+
$p = new PartialInput();
439+
$p->uuid = '6a9eb6dd-c4dc-4746-bb99-f6bad716acb2';
440+
$p->website = 'https://updated.website.com';
441+
$p->email = 'updated@email.com';
442+
443+
$f = new FinalInput();
444+
$f->uuid = $p->uuid;
445+
$f->website = $p->website;
446+
$f->email = $p->email;
447+
448+
yield [$p, $f];
449+
}
405450
}

0 commit comments

Comments
 (0)