From 57ce6281b5d56711215200ec0a9aaa5d6500b5c3 Mon Sep 17 00:00:00 2001 From: Zayon Date: Mon, 10 Sep 2018 18:37:51 +0200 Subject: [PATCH 1/2] Allow multiple doctrine entity manager instances --- .../Persister/ObjectManagerPersister.php | 62 ++++++++++++------- .../Resources/config/doctrine_mongodb_odm.xml | 2 +- .../Symfony/Resources/config/doctrine_orm.xml | 2 +- .../Resources/config/doctrine_phpcr_odm.xml | 2 +- 4 files changed, 42 insertions(+), 26 deletions(-) diff --git a/src/Bridge/Doctrine/Persister/ObjectManagerPersister.php b/src/Bridge/Doctrine/Persister/ObjectManagerPersister.php index f8946c89..8ebd17d2 100644 --- a/src/Bridge/Doctrine/Persister/ObjectManagerPersister.php +++ b/src/Bridge/Doctrine/Persister/ObjectManagerPersister.php @@ -13,6 +13,7 @@ namespace Fidry\AliceDataFixtures\Bridge\Doctrine\Persister; +use Doctrine\Common\Persistence\ManagerRegistry; use Doctrine\Common\Persistence\Mapping\ClassMetadata; use Doctrine\Common\Persistence\ObjectManager; use Doctrine\ODM\MongoDB\Mapping\ClassMetadataInfo as ODMClassMetadataInfo; @@ -27,7 +28,8 @@ class ObjectManagerPersister implements PersisterInterface { use IsAServiceTrait; - private $objectManager; + /** @var array|ObjectManager[] */ + private $managers; /** * @var array|null Values are FQCN of persistable objects @@ -39,9 +41,9 @@ class ObjectManagerPersister implements PersisterInterface */ private $metadata = []; - public function __construct(ObjectManager $manager) + public function __construct(ManagerRegistry $managerRegistry) { - $this->objectManager = $manager; + $this->managers = $managerRegistry->getManagers(); } /** @@ -50,7 +52,7 @@ public function __construct(ObjectManager $manager) public function persist($object) { if (null === $this->persistableClasses) { - $this->persistableClasses = array_flip($this->getPersistableClasses($this->objectManager)); + $this->persistableClasses = array_flip($this->getPersistableClasses($this->managers)); } $class = get_class($object); @@ -77,14 +79,18 @@ public function persist($object) // Do nothing: not supported. } - try { - $this->objectManager->persist($object); - } catch (ORMException $exception) { - if ($metadata->idGenerator instanceof ORMAssignedGenerator) { - throw ObjectGeneratorPersisterExceptionFactory::createForEntityMissingAssignedIdForField($object); + foreach ($this->managers as $manager) { + if ($manager->contains($object)) { + try { + $manager->persist($object); + } catch (ORMException $exception) { + if ($metadata->idGenerator instanceof ORMAssignedGenerator) { + throw ObjectGeneratorPersisterExceptionFactory::createForEntityMissingAssignedIdForField($object); + } + + throw $exception; + } } - - throw $exception; } if (null !== $generator && false === $generator->isPostInsertGenerator()) { @@ -100,23 +106,30 @@ public function persist($object) */ public function flush() { - $this->objectManager->flush(); + foreach ($this->managers as $manager) { + $manager->flush(); + } } /** + * @param array|ObjectManager[] $managers + * * @return string[] */ - private function getPersistableClasses(ObjectManager $manager): array + private function getPersistableClasses(array $managers): array { $persistableClasses = []; - $allMetadata = $manager->getMetadataFactory()->getAllMetadata(); - - foreach ($allMetadata as $metadata) { - /** @var ORMClassMetadataInfo|ODMClassMetadataInfo $metadata */ - if (false === $metadata->isMappedSuperclass - && false === (isset($metadata->isEmbeddedClass) && $metadata->isEmbeddedClass) - ) { - $persistableClasses[] = $metadata->getName(); + + foreach ($managers as $manager) { + $allMetadata = $manager->getMetadataFactory()->getAllMetadata(); + + foreach ($allMetadata as $metadata) { + /** @var ORMClassMetadataInfo|ODMClassMetadataInfo $metadata */ + if (false === $metadata->isMappedSuperclass + && false === (isset($metadata->isEmbeddedClass) && $metadata->isEmbeddedClass) + ) { + $persistableClasses[] = $metadata->getName(); + } } } @@ -132,8 +145,11 @@ protected function configureIdGenerator(ORMClassMetadataInfo $metadata): void private function getMetadata(string $class): ClassMetadata { if (false === array_key_exists($class, $this->metadata)) { - $classMetadata = $this->objectManager->getClassMetadata($class); - $this->metadata[$class] = $classMetadata; + foreach ($this->managers as $manager) { + if ($manager->getMetadataFactory()->hasMetadataFor($class)) { + $this->metadata[$class] = $manager->getClassMetadata($class); + } + } } return $this->metadata[$class]; diff --git a/src/Bridge/Symfony/Resources/config/doctrine_mongodb_odm.xml b/src/Bridge/Symfony/Resources/config/doctrine_mongodb_odm.xml index 4068f490..4bbc02c0 100644 --- a/src/Bridge/Symfony/Resources/config/doctrine_mongodb_odm.xml +++ b/src/Bridge/Symfony/Resources/config/doctrine_mongodb_odm.xml @@ -71,7 +71,7 @@ - + diff --git a/src/Bridge/Symfony/Resources/config/doctrine_orm.xml b/src/Bridge/Symfony/Resources/config/doctrine_orm.xml index b2906397..7565f763 100644 --- a/src/Bridge/Symfony/Resources/config/doctrine_orm.xml +++ b/src/Bridge/Symfony/Resources/config/doctrine_orm.xml @@ -79,7 +79,7 @@ - + diff --git a/src/Bridge/Symfony/Resources/config/doctrine_phpcr_odm.xml b/src/Bridge/Symfony/Resources/config/doctrine_phpcr_odm.xml index 3b94e524..d51a5280 100644 --- a/src/Bridge/Symfony/Resources/config/doctrine_phpcr_odm.xml +++ b/src/Bridge/Symfony/Resources/config/doctrine_phpcr_odm.xml @@ -73,7 +73,7 @@ - + From 2216d974d0737dc7da270b2124c1f9650094544b Mon Sep 17 00:00:00 2001 From: Zayon Date: Wed, 12 Sep 2018 15:45:15 +0200 Subject: [PATCH 2/2] WIP --- .../Persister/ObjectManagerPersister.php | 74 +++++-------------- .../Resources/config/doctrine_mongodb_odm.xml | 3 +- .../Symfony/Resources/config/doctrine_orm.xml | 1 + .../Resources/config/doctrine_phpcr_odm.xml | 4 +- .../Persister/ObjectManagerPersisterTest.php | 14 +++- 5 files changed, 36 insertions(+), 60 deletions(-) diff --git a/src/Bridge/Doctrine/Persister/ObjectManagerPersister.php b/src/Bridge/Doctrine/Persister/ObjectManagerPersister.php index 8ebd17d2..87247527 100644 --- a/src/Bridge/Doctrine/Persister/ObjectManagerPersister.php +++ b/src/Bridge/Doctrine/Persister/ObjectManagerPersister.php @@ -28,13 +28,8 @@ class ObjectManagerPersister implements PersisterInterface { use IsAServiceTrait; - /** @var array|ObjectManager[] */ - private $managers; - - /** - * @var array|null Values are FQCN of persistable objects - */ - private $persistableClasses; + /** @var ManagerRegistry $managerRegistry */ + private $managerRegistry; /** * @var ClassMetadata[] Entity metadata, FQCN being the key @@ -43,7 +38,7 @@ class ObjectManagerPersister implements PersisterInterface public function __construct(ManagerRegistry $managerRegistry) { - $this->managers = $managerRegistry->getManagers(); + $this->managerRegistry = $managerRegistry; } /** @@ -51,14 +46,12 @@ public function __construct(ManagerRegistry $managerRegistry) */ public function persist($object) { - if (null === $this->persistableClasses) { - $this->persistableClasses = array_flip($this->getPersistableClasses($this->managers)); - } - $class = get_class($object); - if (isset($this->persistableClasses[$class])) { - $metadata = $this->getMetadata($class); + $manager = $this->managerRegistry->getManagerForClass($class); + + if ($manager) { + $metadata = $this->getClassMetadata($manager, $class); $generator = null; $generatorType = null; @@ -79,18 +72,14 @@ public function persist($object) // Do nothing: not supported. } - foreach ($this->managers as $manager) { - if ($manager->contains($object)) { - try { - $manager->persist($object); - } catch (ORMException $exception) { - if ($metadata->idGenerator instanceof ORMAssignedGenerator) { - throw ObjectGeneratorPersisterExceptionFactory::createForEntityMissingAssignedIdForField($object); - } - - throw $exception; - } + try { + $manager->persist($object); + } catch (ORMException $exception) { + if ($metadata->idGenerator instanceof ORMAssignedGenerator) { + throw ObjectGeneratorPersisterExceptionFactory::createForEntityMissingAssignedIdForField($object); } + + throw $exception; } if (null !== $generator && false === $generator->isPostInsertGenerator()) { @@ -106,50 +95,21 @@ public function persist($object) */ public function flush() { - foreach ($this->managers as $manager) { + foreach ($this->managerRegistry->getManagers() as $manager) { $manager->flush(); } } - /** - * @param array|ObjectManager[] $managers - * - * @return string[] - */ - private function getPersistableClasses(array $managers): array - { - $persistableClasses = []; - - foreach ($managers as $manager) { - $allMetadata = $manager->getMetadataFactory()->getAllMetadata(); - - foreach ($allMetadata as $metadata) { - /** @var ORMClassMetadataInfo|ODMClassMetadataInfo $metadata */ - if (false === $metadata->isMappedSuperclass - && false === (isset($metadata->isEmbeddedClass) && $metadata->isEmbeddedClass) - ) { - $persistableClasses[] = $metadata->getName(); - } - } - } - - return $persistableClasses; - } - protected function configureIdGenerator(ORMClassMetadataInfo $metadata): void { $metadata->setIdGeneratorType(ORMClassMetadataInfo::GENERATOR_TYPE_NONE); $metadata->setIdGenerator(new ORMAssignedGenerator()); } - private function getMetadata(string $class): ClassMetadata + private function getClassMetadata(ObjectManager $manager, string $class): ClassMetadata { if (false === array_key_exists($class, $this->metadata)) { - foreach ($this->managers as $manager) { - if ($manager->getMetadataFactory()->hasMetadataFor($class)) { - $this->metadata[$class] = $manager->getClassMetadata($class); - } - } + $this->metadata[$class] = $manager->getClassMetadata($class); } return $this->metadata[$class]; diff --git a/src/Bridge/Symfony/Resources/config/doctrine_mongodb_odm.xml b/src/Bridge/Symfony/Resources/config/doctrine_mongodb_odm.xml index 4bbc02c0..98a52b88 100644 --- a/src/Bridge/Symfony/Resources/config/doctrine_mongodb_odm.xml +++ b/src/Bridge/Symfony/Resources/config/doctrine_mongodb_odm.xml @@ -52,6 +52,7 @@ + @@ -71,7 +72,7 @@ - + diff --git a/src/Bridge/Symfony/Resources/config/doctrine_orm.xml b/src/Bridge/Symfony/Resources/config/doctrine_orm.xml index 7565f763..2289260a 100644 --- a/src/Bridge/Symfony/Resources/config/doctrine_orm.xml +++ b/src/Bridge/Symfony/Resources/config/doctrine_orm.xml @@ -52,6 +52,7 @@ + diff --git a/src/Bridge/Symfony/Resources/config/doctrine_phpcr_odm.xml b/src/Bridge/Symfony/Resources/config/doctrine_phpcr_odm.xml index d51a5280..bdec5296 100644 --- a/src/Bridge/Symfony/Resources/config/doctrine_phpcr_odm.xml +++ b/src/Bridge/Symfony/Resources/config/doctrine_phpcr_odm.xml @@ -52,12 +52,14 @@ + + The service "%service_id%s" is deprecated and will be removed in future versions. Use "fidry_alice_data_fixtures.persistence.doctrine_phpcr.purger.purger_factory" instead. @@ -73,7 +75,7 @@ - + diff --git a/tests/Bridge/Doctrine/Persister/ObjectManagerPersisterTest.php b/tests/Bridge/Doctrine/Persister/ObjectManagerPersisterTest.php index 5c0eef5c..8d0ebf41 100644 --- a/tests/Bridge/Doctrine/Persister/ObjectManagerPersisterTest.php +++ b/tests/Bridge/Doctrine/Persister/ObjectManagerPersisterTest.php @@ -14,6 +14,7 @@ namespace Fidry\AliceDataFixtures\Bridge\Doctrine\Persister; use Doctrine\Common\DataFixtures\Purger\ORMPurger; +use Doctrine\Common\Persistence\ManagerRegistry; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\ORMException; use Doctrine\ORM\ORMInvalidArgumentException; @@ -25,6 +26,7 @@ use Fidry\AliceDataFixtures\Bridge\Doctrine\Entity\MappedSuperclassDummy; use Fidry\AliceDataFixtures\Exception\ObjectGeneratorPersisterException; use Fidry\AliceDataFixtures\Persistence\PersisterInterface; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use ReflectionClass; @@ -48,13 +50,23 @@ class ObjectManagerPersisterTest extends TestCase */ private $purger; + /** + * @var ManagerRegistry|MockObject + */ + private $managerRegistry; + /** * @inheritdoc */ public function setUp() { $this->entityManager = $GLOBALS['entity_manager']; - $this->persister = new ObjectManagerPersister($this->entityManager); + + $this->managerRegistry = $this->createMock(ManagerRegistry::class); + $this->managerRegistry->method('getManagerForClass')->willReturn($this->entityManager); + $this->managerRegistry->method('getManagers')->willReturn([$this->entityManager]); + + $this->persister = new ObjectManagerPersister($this->managerRegistry); $this->purger = new ORMPurger($this->entityManager); }