Skip to content

Commit e11ebf3

Browse files
authored
Fix proxy interface for ProxyManager or Symfony LazyGhost (#947)
Fix the interface that identifies the lazy objects. Note that Doctrine\Persistence\Mapping\ProxyClassNameResolver should be used by Doctrine\Persistence\AbstractManagerRegistry instead of repeating the same logic. Add a test with various lazy object implementations
1 parent de79766 commit e11ebf3

File tree

4 files changed

+92
-1
lines changed

4 files changed

+92
-1
lines changed

phpstan-baseline.neon

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,18 @@ parameters:
576576
count: 1
577577
path: tests/DependencyInjection/ConfigurationTest.php
578578

579+
-
580+
message: '#^Call to function method_exists\(\) with ''Doctrine\\\\ODM\\\\MongoDB\\\\Configuration'' and ''setUseLazyGhostObje…'' will always evaluate to true\.$#'
581+
identifier: function.alreadyNarrowedType
582+
count: 1
583+
path: tests/DependencyInjection/DoctrineMongoDBExtensionTest.php
584+
585+
-
586+
message: '#^Call to function method_exists\(\) with ''Doctrine\\\\ODM\\\\MongoDB\\\\Configuration'' and ''setUseNativeLazyObj…'' will always evaluate to true\.$#'
587+
identifier: function.alreadyNarrowedType
588+
count: 1
589+
path: tests/DependencyInjection/DoctrineMongoDBExtensionTest.php
590+
579591
-
580592
message: '#^Method Doctrine\\Bundle\\MongoDBBundle\\Tests\\DependencyInjection\\DoctrineMongoDBExtensionTest\:\:assertDICDefinitionMethodCall\(\) has parameter \$params with no value type specified in iterable type array\.$#'
581593
identifier: missingType.iterableValue

src/DependencyInjection/DoctrineMongoDBExtension.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ public function load(array $configs, ContainerBuilder $container): void
487487
}
488488

489489
$container->getDefinition('doctrine_mongodb')
490-
->setArgument(5, $config['enable_lazy_ghost_objects'] ? LazyLoadingInterface::class : Proxy::class);
490+
->setArgument(5, $config['enable_lazy_ghost_objects'] ? Proxy::class : LazyLoadingInterface::class);
491491

492492
// load the connections
493493
$this->loadConnections($config['connections'], $container, $config);

tests/DependencyInjection/DoctrineMongoDBExtensionTest.php

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,31 +10,48 @@
1010
use Doctrine\Bundle\MongoDBBundle\Attribute\MapDocument;
1111
use Doctrine\Bundle\MongoDBBundle\Command\Encryption\DiagnosticCommand;
1212
use Doctrine\Bundle\MongoDBBundle\Command\Encryption\DumpFieldsMapCommand;
13+
use Doctrine\Bundle\MongoDBBundle\DependencyInjection\Compiler\CreateProxyDirectoryPass;
1314
use Doctrine\Bundle\MongoDBBundle\DependencyInjection\Compiler\ServiceRepositoryCompilerPass;
1415
use Doctrine\Bundle\MongoDBBundle\DependencyInjection\DoctrineMongoDBExtension;
16+
use Doctrine\Bundle\MongoDBBundle\ManagerRegistry;
17+
use Doctrine\Bundle\MongoDBBundle\Tests\DependencyInjection\Fixtures\Bundles\AttributesBundle\Document\TestDocument;
1518
use Doctrine\Bundle\MongoDBBundle\Tests\DependencyInjection\Fixtures\Bundles\DocumentListenerBundle\EventListener\TestAttributeListener;
1619
use Doctrine\ODM\MongoDB\Configuration;
20+
use Doctrine\ODM\MongoDB\DocumentManager;
1721
use Doctrine\ODM\MongoDB\Mapping\Annotations;
1822
use InvalidArgumentException;
1923
use MongoDB\Client;
2024
use PHPUnit\Framework\Attributes\DataProvider;
2125
use PHPUnit\Framework\TestCase;
26+
use ProxyManager\Proxy\GhostObjectInterface;
2227
use stdClass;
2328
use Symfony\Component\DependencyInjection\Alias;
2429
use Symfony\Component\DependencyInjection\ChildDefinition;
30+
use Symfony\Component\DependencyInjection\Compiler\ResolveParameterPlaceHoldersPass;
2531
use Symfony\Component\DependencyInjection\Container;
2632
use Symfony\Component\DependencyInjection\ContainerBuilder;
2733
use Symfony\Component\DependencyInjection\Definition;
2834
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
2935
use Symfony\Component\DependencyInjection\Reference;
36+
use Symfony\Component\VarExporter\LazyGhostTrait;
3037

3138
use function array_diff_key;
3239
use function array_merge;
40+
use function interface_exists;
3341
use function is_dir;
3442
use function method_exists;
3543
use function sprintf;
3644
use function sys_get_temp_dir;
45+
use function trait_exists;
3746

47+
use const PHP_VERSION_ID;
48+
49+
/**
50+
* @phpstan-type ConfigurationArray array{
51+
* enable_lazy_ghost_objects?: bool,
52+
* enable_native_lazy_objects?: bool,
53+
* }
54+
*/
3855
class DoctrineMongoDBExtensionTest extends TestCase
3956
{
4057
public static function buildConfiguration(array $settings = []): array
@@ -716,6 +733,63 @@ public function testAutoEncryptionMinimumODMVersion(): void
716733
$loader->load([$config], $container);
717734
}
718735

736+
/** @phpstan-param ConfigurationArray $config */
737+
#[DataProvider('provideLazyObjectConfigurations')]
738+
public function testRegistryGetManagerForClass(array $config): void
739+
{
740+
$container = $this->getContainer('AttributesBundle');
741+
$loader = new DoctrineMongoDBExtension();
742+
$loader->load(self::buildConfiguration($config + [
743+
'connections' => [
744+
'default' => [],
745+
],
746+
'document_managers' => [
747+
'default' => [
748+
'mappings' => [
749+
'AttributesBundle' => ['type' => 'attribute'],
750+
],
751+
],
752+
],
753+
]), $container);
754+
(new ResolveParameterPlaceHoldersPass())->process($container);
755+
(new ServiceRepositoryCompilerPass())->process($container);
756+
(new CreateProxyDirectoryPass())->process($container);
757+
758+
$container->compile();
759+
$registry = $container->get('doctrine_mongodb');
760+
$dm = $container->get('doctrine_mongodb.odm.document_manager');
761+
762+
self::assertInstanceOf(ManagerRegistry::class, $registry);
763+
self::assertInstanceOf(DocumentManager::class, $dm);
764+
765+
// Create a lazy object
766+
$ref = $dm->getReference(TestDocument::class, 'some');
767+
self::assertInstanceOf(TestDocument::class, $ref);
768+
self::assertSame($dm, $registry->getManagerForClass($ref::class), 'The manager is found for the proxy document class');
769+
}
770+
771+
/** @phpstan-return iterable<ConfigurationArray> */
772+
public static function provideLazyObjectConfigurations(): iterable
773+
{
774+
if (interface_exists(GhostObjectInterface::class)) {
775+
yield 'Proxy Manager' => [
776+
['enable_lazy_ghost_objects' => false, 'enable_native_lazy_objects' => false],
777+
];
778+
}
779+
780+
if (trait_exists(LazyGhostTrait::class) && method_exists(Configuration::class, 'setUseLazyGhostObject')) {
781+
yield 'Symfony Lazy Objects' => [
782+
['enable_lazy_ghost_objects' => true, 'enable_native_lazy_objects' => false],
783+
];
784+
}
785+
786+
if (PHP_VERSION_ID >= 80400 && method_exists(Configuration::class, 'setUseNativeLazyObject')) {
787+
yield 'Native Lazy Objects' => [
788+
['enable_lazy_ghost_objects' => false, 'enable_native_lazy_objects' => true],
789+
];
790+
}
791+
}
792+
719793
private static function requireAutoEncryptionSupportInODM(): void
720794
{
721795
if (! InstalledVersions::satisfies(new VersionParser(), 'doctrine/mongodb-odm', '>=2.12@dev')) {

tests/DependencyInjection/Fixtures/Bundles/AttributesBundle/Document/TestDocument.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,9 @@
99
#[MongoDB\Document]
1010
class TestDocument
1111
{
12+
#[MongoDB\Id]
13+
public ?string $id = null;
14+
15+
#[MongoDB\Field(type: 'string')]
16+
public ?string $name = null;
1217
}

0 commit comments

Comments
 (0)