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

Skip to content

Commit c6c7cbd

Browse files
committed
[DoctrineBridge] Fix resetting the manager when using native lazy objects
1 parent 77bcded commit c6c7cbd

File tree

3 files changed

+77
-10
lines changed

3 files changed

+77
-10
lines changed

src/Symfony/Bridge/Doctrine/ManagerRegistry.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,15 @@ function (&$wrappedInstance, LazyLoadingInterface $manager) use ($name) {
8181
}
8282

8383
try {
84-
$r->resetAsLazyProxy($manager, \Closure::bind(
85-
function () use ($name) {
84+
$r->resetAsLazyGhost($manager, \Closure::bind(
85+
function ($manager) use ($name) {
8686
$name = $this->aliases[$name] ?? $name;
8787

88-
return match (true) {
89-
isset($this->fileMap[$name]) => $this->load($this->fileMap[$name], false),
88+
match (true) {
89+
isset($this->fileMap[$name]) => $this->load($this->fileMap[$name], $manager),
9090
!$method = $this->methodMap[$name] ?? null => throw new \LogicException(\sprintf('The "%s" service is synthetic and cannot be reset.', $name)),
91-
(new \ReflectionMethod($this, $method))->isStatic() => $this->{$method}($this, false),
92-
default => $this->{$method}(false),
91+
(new \ReflectionMethod($this, $method))->isStatic() => $this->{$method}($this, $manager),
92+
default => $this->{$method}($manager),
9393
};
9494
},
9595
$this->container,

src/Symfony/Bridge/Doctrine/Tests/Fixtures/DummyManager.php

Lines changed: 13 additions & 0 deletions
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 <[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+
312
namespace Symfony\Bridge\Doctrine\Tests\Fixtures;
413

514
use Doctrine\Persistence\Mapping\ClassMetadata;
@@ -11,6 +20,10 @@ class DummyManager implements ObjectManager
1120
{
1221
public $bar;
1322

23+
public function __construct()
24+
{
25+
}
26+
1427
public function find($className, $id): ?object
1528
{
1629
}

src/Symfony/Bridge/Doctrine/Tests/ManagerRegistryTest.php

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
class ManagerRegistryTest extends TestCase
2424
{
25-
public static function setUpBeforeClass(): void
25+
public function testResetService()
2626
{
2727
$container = new ContainerBuilder();
2828

@@ -32,10 +32,7 @@ public static function setUpBeforeClass(): void
3232

3333
$dumper = new PhpDumper($container);
3434
eval('?>'.$dumper->dump(['class' => 'LazyServiceDoctrineBridgeContainer']));
35-
}
3635

37-
public function testResetService()
38-
{
3936
$container = new \LazyServiceDoctrineBridgeContainer();
4037

4138
$registry = new TestManagerRegistry('name', [], ['defaultManager' => 'foo'], 'defaultConnection', 'defaultManager', 'proxyInterfaceName');
@@ -52,6 +49,63 @@ public function testResetService()
5249
$this->assertFalse(isset($foo->bar));
5350
}
5451

52+
/**
53+
* @requires PHP 8.4
54+
*
55+
* @dataProvider provideResetServiceWithNativeLazyObjectsCases
56+
*/
57+
public function testResetServiceWithNativeLazyObjects(string $class)
58+
{
59+
$container = new $class();
60+
61+
$registry = new TestManagerRegistry(
62+
'irrelevant',
63+
[],
64+
['defaultManager' => 'foo'],
65+
'irrelevant',
66+
'defaultManager',
67+
'irrelevant',
68+
);
69+
$registry->setTestContainer($container);
70+
71+
$foo = $container->get('foo');
72+
self::assertSame(DummyManager::class, $foo::class);
73+
74+
$foo->bar = 123;
75+
self::assertTrue(isset($foo->bar));
76+
77+
$registry->resetManager();
78+
79+
self::assertSame($foo, $container->get('foo'));
80+
self::assertSame(DummyManager::class, $foo::class);
81+
self::assertFalse(isset($foo->bar));
82+
}
83+
84+
public static function provideResetServiceWithNativeLazyObjectsCases(): iterable
85+
{
86+
$container = new ContainerBuilder();
87+
88+
$container->register('foo', DummyManager::class)->setPublic(true);
89+
$container->getDefinition('foo')->setLazy(true);
90+
$container->compile();
91+
92+
$dumper = new PhpDumper($container);
93+
94+
eval('?>'.$dumper->dump(['class' => 'NativeLazyServiceDoctrineBridgeContainer']));
95+
96+
yield ['NativeLazyServiceDoctrineBridgeContainer'];
97+
98+
$dumps = $dumper->dump(['class' => 'NativeLazyServiceDoctrineBridgeContainerAsFiles', 'as_files' => true]);
99+
100+
$lastDump = array_pop($dumps);
101+
foreach (array_reverse($dumps) as $dump) {
102+
eval('?>'.$dump);
103+
}
104+
eval('?>'.$lastDump);
105+
106+
yield ['NativeLazyServiceDoctrineBridgeContainerAsFiles'];
107+
}
108+
55109
/**
56110
* When performing an entity manager lazy service reset, the reset operations may re-use the container
57111
* to create a "fresh" service: when doing so, it can happen that the "fresh" service is itself a proxy.

0 commit comments

Comments
 (0)