diff --git a/src/Model/ModelManager.php b/src/Model/ModelManager.php index e82436d6..a3dfaa14 100755 --- a/src/Model/ModelManager.php +++ b/src/Model/ModelManager.php @@ -18,8 +18,10 @@ use Doctrine\ODM\MongoDB\Mapping\ClassMetadata as MongoDBClassMetadata; use Doctrine\ODM\MongoDB\Query\Builder; use Doctrine\ODM\MongoDB\Repository\DocumentRepository; +use Doctrine\Persistence\Mapping\MappingException; use Sonata\AdminBundle\Datagrid\ProxyQueryInterface as BaseProxyQueryInterface; use Sonata\AdminBundle\Model\ModelManagerInterface; +use Sonata\AdminBundle\Model\ProxyResolverInterface; use Sonata\DoctrineMongoDBAdminBundle\Datagrid\ProxyQuery; use Sonata\DoctrineMongoDBAdminBundle\Datagrid\ProxyQueryInterface; use Symfony\Bridge\Doctrine\ManagerRegistry; @@ -30,7 +32,7 @@ * * @template-implements ModelManagerInterface */ -final class ModelManager implements ModelManagerInterface +final class ModelManager implements ModelManagerInterface, ProxyResolverInterface { public const ID_SEPARATOR = '-'; @@ -240,6 +242,22 @@ public function reverseTransform(object $object, array $array = []): void } } + public function getRealClass(object $object): string + { + $class = \get_class($object); + + $dm = $this->registry->getManagerForClass($class); + if (null === $dm) { + return $class; + } + + try { + return $dm->getClassMetadata($class)->getName(); + } catch (MappingException $e) { + return $class; + } + } + /** * @param MongoDBClassMetadata $metadata */ diff --git a/tests/Model/ModelManagerTest.php b/tests/Model/ModelManagerTest.php index 09fc6df8..5d76cd1e 100644 --- a/tests/Model/ModelManagerTest.php +++ b/tests/Model/ModelManagerTest.php @@ -14,6 +14,7 @@ namespace Sonata\DoctrineMongoDBAdminBundle\Tests\Model; use Doctrine\ODM\MongoDB\DocumentManager; +use Doctrine\ODM\MongoDB\Mapping\ClassMetadata; use Doctrine\ODM\MongoDB\Query\Builder; use Doctrine\ODM\MongoDB\Repository\DocumentRepository; use PHPUnit\Framework\MockObject\Stub; @@ -148,6 +149,47 @@ public function testSupportsQuery(bool $expected, object $object): void static::assertSame($expected, $modelManager->supportsQuery($object)); } + public function testGetRealClassWithProxyObject(): void + { + $proxyClass = TestDocument::class; + /** @var class-string $baseClass */ + $baseClass = 'BaseTestDocument'; + + $classMetadata = $this->createMock(ClassMetadata::class); + $classMetadata->expects(static::once()) + ->method('getName') + ->willReturn($baseClass); + + $documentManager = $this->createMock(DocumentManager::class); + $documentManager->expects(static::once()) + ->method('getClassMetadata') + ->with($proxyClass) + ->willReturn($classMetadata); + + $registry = $this->createMock(ManagerRegistry::class); + $registry->expects(static::once()) + ->method('getManagerForClass') + ->with($proxyClass) + ->willReturn($documentManager); + + $modelManager = new ModelManager($registry, $this->propertyAccessor); + + static::assertSame($baseClass, $modelManager->getRealClass(new TestDocument())); + } + + public function testGetRealClassWithNonProxyObject(): void + { + $registry = $this->createMock(ManagerRegistry::class); + $registry->expects(static::once()) + ->method('getManagerForClass') + ->with(\DateTime::class) + ->willReturn(null); + + $modelManager = new ModelManager($registry, $this->propertyAccessor); + + static::assertSame(\DateTime::class, $modelManager->getRealClass(new \DateTime())); + } + /** * @phpstan-return iterable */