Skip to content

Commit 1399887

Browse files
authored
Make manager registry resettable (#852)
1 parent 396377f commit 1399887

File tree

3 files changed

+118
-8
lines changed

3 files changed

+118
-8
lines changed

psalm-baseline.xml

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<files psalm-version="5.24.0@462c80e31c34e58cc4f750c656be3927e80e550e">
2+
<files psalm-version="5.25.0@01a8eb06b9e9cc6cfb6a320bf9fb14331919d505">
33
<file src="config/value_resolver.php">
44
<UndefinedClass>
55
<code><![CDATA[ExpressionLanguage]]></code>
@@ -21,15 +21,14 @@
2121
<code><![CDATA[children]]></code>
2222
</UndefinedMethod>
2323
</file>
24-
<file src="tests/DocumentValueResolverFunctionalTest.php">
25-
<InvalidArgument>
26-
<code><![CDATA[[DocumentValueResolverController::class, 'showUserByDefault']]]></code>
27-
<code><![CDATA[[DocumentValueResolverController::class, 'showUserWithMapping']]]></code>
28-
</InvalidArgument>
29-
</file>
3024
<file src="tests/Form/Type/GuesserTestType.php">
3125
<MissingTemplateParam>
3226
<code><![CDATA[GuesserTestType]]></code>
3327
</MissingTemplateParam>
3428
</file>
29+
<file src="tests/ManagerRegistryTest.php">
30+
<RedundantCondition>
31+
<code><![CDATA[assertSame]]></code>
32+
</RedundantCondition>
33+
</file>
3534
</files>

src/ManagerRegistry.php

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,16 @@
66

77
use Doctrine\ODM\MongoDB\DocumentManager;
88
use Doctrine\ODM\MongoDB\MongoDBException;
9+
use ProxyManager\Proxy\LazyLoadingInterface;
910
use Psr\Container\ContainerInterface;
1011
use Symfony\Bridge\Doctrine\ManagerRegistry as BaseManagerRegistry;
12+
use Symfony\Component\VarExporter\LazyObjectInterface;
13+
use Symfony\Contracts\Service\ResetInterface;
1114

1215
use function array_keys;
16+
use function assert;
1317

14-
class ManagerRegistry extends BaseManagerRegistry
18+
class ManagerRegistry extends BaseManagerRegistry implements ResetInterface
1519
{
1620
public function __construct(string $name, array $connections, array $managers, string $defaultConnection, string $defaultManager, string $proxyInterfaceName, ?ContainerInterface $container = null)
1721
{
@@ -42,4 +46,37 @@ public function getAliasNamespace(string $alias): string
4246

4347
throw MongoDBException::unknownDocumentNamespace($alias);
4448
}
49+
50+
/**
51+
* Clears all document managers.
52+
*/
53+
public function reset(): void
54+
{
55+
foreach ($this->getManagerNames() as $managerName => $serviceId) {
56+
$this->resetOrClearManager($managerName, $serviceId);
57+
}
58+
}
59+
60+
private function resetOrClearManager(string $managerName, string $serviceId): void
61+
{
62+
if (! $this->container->initialized($serviceId)) {
63+
return;
64+
}
65+
66+
$manager = $this->container->get($serviceId);
67+
68+
if ($manager instanceof LazyLoadingInterface || $manager instanceof LazyObjectInterface) {
69+
$this->resetManager($managerName);
70+
71+
return;
72+
}
73+
74+
assert($manager instanceof DocumentManager);
75+
76+
if (! $manager->isOpen()) {
77+
return;
78+
}
79+
80+
$manager->clear();
81+
}
4582
}

tests/ManagerRegistryTest.php

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\Bundle\MongoDBBundle\Tests;
6+
7+
use Doctrine\Bundle\MongoDBBundle\ManagerRegistry;
8+
use Doctrine\ODM\MongoDB\DocumentManager;
9+
use Doctrine\Persistence\ObjectManager;
10+
use Symfony\Component\DependencyInjection\Container;
11+
use Symfony\Component\DependencyInjection\ContainerBuilder;
12+
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
13+
14+
class ManagerRegistryTest extends TestCase
15+
{
16+
public function testReset(): void
17+
{
18+
$container = new ContainerBuilder();
19+
$container->register('manager.default', DocumentManagerStub::class)
20+
->setPublic(true);
21+
$container->register('manager.lazy', DocumentManagerStub::class)
22+
->setPublic(true)
23+
->setLazy(true)
24+
->addTag('proxy', ['interface' => ObjectManager::class]);
25+
$container->compile();
26+
27+
/** @var class-string<Container> $containerClass */
28+
$containerClass = 'MongoDBManagerRepositoryTestResetContainer';
29+
$dumper = new PhpDumper($container);
30+
eval('?' . '>' . $dumper->dump(['class' => $containerClass]));
31+
32+
$container = new $containerClass();
33+
$repository = new ManagerRegistry('MongoDB', [], [
34+
'default' => 'manager.default',
35+
'lazy' => 'manager.lazy',
36+
], '', '', '', $container);
37+
38+
DocumentManagerStub::$clearCount = 0;
39+
40+
$repository->reset();
41+
42+
// Service was not initialized, so reset should not be called
43+
$this->assertSame(0, DocumentManagerStub::$clearCount);
44+
45+
// The lazy service is reinitialized instead of being cleared
46+
$container->get('manager.lazy')->flush();
47+
$repository->reset();
48+
$this->assertSame(0, DocumentManagerStub::$clearCount);
49+
50+
// The default service is cleared when initialized
51+
$container->get('manager.default')->flush();
52+
$repository->reset();
53+
$this->assertSame(1, DocumentManagerStub::$clearCount);
54+
}
55+
}
56+
57+
class DocumentManagerStub extends DocumentManager
58+
{
59+
public static int $clearCount;
60+
61+
public function __construct()
62+
{
63+
}
64+
65+
/** {@inheritDoc} */
66+
public function clear($objectName = null): void
67+
{
68+
self::$clearCount++;
69+
}
70+
71+
public function flush(array $options = []): void
72+
{
73+
}
74+
}

0 commit comments

Comments
 (0)