Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1c82070

Browse files
committed
[ObjectMapper] initialize lazy objects
1 parent deac4c6 commit 1c82070

File tree

5 files changed

+96
-1
lines changed

5 files changed

+96
-1
lines changed

src/Symfony/Component/ObjectMapper/ObjectMapper.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use Symfony\Component\ObjectMapper\Metadata\ReflectionObjectMapperMetadataFactory;
2121
use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException as PropertyAccessorNoSuchPropertyException;
2222
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
23+
use Symfony\Component\VarExporter\LazyObjectInterface;
2324

2425
/**
2526
* Object to object mapper.
@@ -300,6 +301,12 @@ private function getCallable(string|callable $fn, ?ContainerInterface $locator =
300301
*/
301302
private function getSourceReflectionClass(object $source, \ReflectionClass $targetRefl): \ReflectionClass
302303
{
304+
if ($source instanceof LazyObjectInterface) {
305+
$source->initializeLazyObject();
306+
} elseif (\PHP_VERSION_ID >= 80400) {
307+
(new \ReflectionClass($source))->initializeLazyObject($source);
308+
}
309+
303310
$metadata = $this->metadataFactory->create($source);
304311
try {
305312
$refl = new \ReflectionClass($source);
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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;
13+
14+
use Symfony\Component\VarExporter\Internal\LazyDecoratorTrait;
15+
use Symfony\Component\VarExporter\LazyObjectInterface;
16+
17+
class LazyFoo extends \stdClass implements LazyObjectInterface
18+
{
19+
use LazyDecoratorTrait;
20+
21+
public string $name = 'foo';
22+
private ?bool $initialized;
23+
24+
public function initializeLazyObject(): static
25+
{
26+
$this->initialized = true;
27+
28+
return $this;
29+
}
30+
31+
public function getInitialized(): ?bool
32+
{
33+
return $this->initialized;
34+
}
35+
}
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 <[email protected]>
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;
13+
14+
class MyProxy
15+
{
16+
public string $name;
17+
}

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
use Symfony\Component\ObjectMapper\Tests\Fixtures\InstanceCallback\B as InstanceCallbackB;
4141
use Symfony\Component\ObjectMapper\Tests\Fixtures\InstanceCallbackWithArguments\A as InstanceCallbackWithArgumentsA;
4242
use Symfony\Component\ObjectMapper\Tests\Fixtures\InstanceCallbackWithArguments\B as InstanceCallbackWithArgumentsB;
43+
use Symfony\Component\ObjectMapper\Tests\Fixtures\LazyFoo;
4344
use Symfony\Component\ObjectMapper\Tests\Fixtures\MapStruct\AToBMapper;
4445
use Symfony\Component\ObjectMapper\Tests\Fixtures\MapStruct\MapStructMapperMetadataFactory;
4546
use Symfony\Component\ObjectMapper\Tests\Fixtures\MapStruct\Source;
@@ -51,6 +52,7 @@
5152
use Symfony\Component\ObjectMapper\Tests\Fixtures\MultipleTargetProperty\C as MultipleTargetPropertyC;
5253
use Symfony\Component\ObjectMapper\Tests\Fixtures\MultipleTargets\A as MultipleTargetsA;
5354
use Symfony\Component\ObjectMapper\Tests\Fixtures\MultipleTargets\C as MultipleTargetsC;
55+
use Symfony\Component\ObjectMapper\Tests\Fixtures\MyProxy;
5456
use Symfony\Component\ObjectMapper\Tests\Fixtures\Recursion\AB;
5557
use Symfony\Component\ObjectMapper\Tests\Fixtures\Recursion\Dto;
5658
use Symfony\Component\ObjectMapper\Tests\Fixtures\ServiceLocator\A as ServiceLocatorA;
@@ -345,4 +347,37 @@ public function testDefaultValueStdClassWithPropertyInfo()
345347
$this->assertSame('abc', $b->id);
346348
$this->assertNull($b->optional);
347349
}
350+
351+
public function testMapInitializesLazyObject()
352+
{
353+
$lazy = new LazyFoo();
354+
$mapper = new ObjectMapper();
355+
$mapper->map($lazy, \stdClass::class);
356+
$this->assertTrue($lazy->getInitialized());
357+
}
358+
359+
public function testMapInitializesNativePhp84LazyObject()
360+
{
361+
if (\PHP_VERSION_ID < 80400) {
362+
$this->markTestSkipped('Native lazy objects require PHP 8.4 or higher.');
363+
}
364+
365+
$initialized = false;
366+
$initializer = function () use (&$initialized) {
367+
$initialized = true;
368+
369+
$p = new MyProxy();
370+
$p->name = 'test';
371+
372+
return $p;
373+
};
374+
375+
$r = new \ReflectionClass(MyProxy::class);
376+
$lazyObj = $r->newLazyProxy($initializer);
377+
$this->assertFalse($initialized);
378+
$mapper = new ObjectMapper();
379+
$d = $mapper->map($lazyObj, MyProxy::class);
380+
$this->assertSame('test', $d->name);
381+
$this->assertTrue($initialized);
382+
}
348383
}

src/Symfony/Component/ObjectMapper/composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
"psr/container": "^2.0"
2121
},
2222
"require-dev": {
23-
"symfony/property-access": "^7.2"
23+
"symfony/property-access": "^7.2",
24+
"symfony/var-exporter": "^7.2"
2425
},
2526
"autoload": {
2627
"psr-4": {

0 commit comments

Comments
 (0)