From 57ce6281b5d56711215200ec0a9aaa5d6500b5c3 Mon Sep 17 00:00:00 2001 From: Zayon Date: Mon, 10 Sep 2018 18:37:51 +0200 Subject: [PATCH 1/3] 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/3] 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); } From 6c3c04d2a6f5075266d01f0a985e71b2df890228 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20FIDRY?= Date: Wed, 24 Oct 2018 21:12:30 +0200 Subject: [PATCH 3/3] Add a persister and purger for Doctrine which operates on all known managers --- .../Persister/ManagerRegistryPersister.php | 85 +++++++++++ .../Persister/ObjectManagerPersister.php | 54 +++++-- .../Doctrine/Purger/ManagerRegistryPurger.php | 74 +++++++++ .../Doctrine/Purger/ObjectManagerPurger.php | 144 ++++++++++++++++++ src/Bridge/Doctrine/Purger/Purger.php | 127 ++------------- src/Persistence/PurgerInterface.php | 2 + 6 files changed, 358 insertions(+), 128 deletions(-) create mode 100644 src/Bridge/Doctrine/Persister/ManagerRegistryPersister.php create mode 100644 src/Bridge/Doctrine/Purger/ManagerRegistryPurger.php create mode 100644 src/Bridge/Doctrine/Purger/ObjectManagerPurger.php diff --git a/src/Bridge/Doctrine/Persister/ManagerRegistryPersister.php b/src/Bridge/Doctrine/Persister/ManagerRegistryPersister.php new file mode 100644 index 00000000..2f6a9a11 --- /dev/null +++ b/src/Bridge/Doctrine/Persister/ManagerRegistryPersister.php @@ -0,0 +1,85 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Fidry\AliceDataFixtures\Bridge\Doctrine\Persister; + +use Doctrine\Common\Persistence\ManagerRegistry; +use Fidry\AliceDataFixtures\Persistence\PersisterInterface; +use function get_class; +use function implode; +use InvalidArgumentException; +use Nelmio\Alice\IsAServiceTrait; +use function sprintf; + +/** + * @final + */ +class ManagerRegistryPersister implements PersisterInterface +{ + use IsAServiceTrait; + + private $registry; + + /** + * @var PersisterInterface[] + */ + private $persisters = []; + + public function __construct(ManagerRegistry $registry) + { + $this->registry = $registry; + + $managers = $registry->getManagers(); + + foreach ($managers as $manager) { + $this->persisters[get_class($manager)] = new ObjectManagerPersister($manager); + } + } + + /** + * @inheritdoc + */ + public function persist($object) + { + $persister = $this->getPersisterForClass(get_class($object)); + + $persister->persist($object); + } + + /** + * @inheritdoc + */ + public function flush() + { + foreach ($this->persisters as $persister) { + $persister->flush(); + } + } + + private function getPersisterForClass(string $class): PersisterInterface + { + $manager = $this->registry->getManagerForClass($class); + + if (null === $manager) { + throw new InvalidArgumentException( + sprintf( + 'Could not find a manager for the class "%s". Known managers: "%s"', + $class, + implode('", "', $this->registry->getManagerNames()) + ) + ); + } + + return $this->persisters[get_class($manager)]; + } +} diff --git a/src/Bridge/Doctrine/Persister/ObjectManagerPersister.php b/src/Bridge/Doctrine/Persister/ObjectManagerPersister.php index 87247527..7efa9627 100644 --- a/src/Bridge/Doctrine/Persister/ObjectManagerPersister.php +++ b/src/Bridge/Doctrine/Persister/ObjectManagerPersister.php @@ -13,7 +13,6 @@ 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; @@ -24,21 +23,25 @@ use Fidry\AliceDataFixtures\Persistence\PersisterInterface; use Nelmio\Alice\IsAServiceTrait; -class ObjectManagerPersister implements PersisterInterface +/* final */ class ObjectManagerPersister implements PersisterInterface { use IsAServiceTrait; - /** @var ManagerRegistry $managerRegistry */ - private $managerRegistry; + private $objectManager; + + /** + * @var array|null Values are FQCN of persistable objects + */ + private $persistableClasses; /** * @var ClassMetadata[] Entity metadata, FQCN being the key */ private $metadata = []; - public function __construct(ManagerRegistry $managerRegistry) + public function __construct(ObjectManager $manager) { - $this->managerRegistry = $managerRegistry; + $this->objectManager = $manager; } /** @@ -46,12 +49,14 @@ public function __construct(ManagerRegistry $managerRegistry) */ public function persist($object) { - $class = get_class($object); + if (null === $this->persistableClasses) { + $this->persistableClasses = array_flip($this->getPersistableClasses($this->objectManager)); + } - $manager = $this->managerRegistry->getManagerForClass($class); + $class = get_class($object); - if ($manager) { - $metadata = $this->getClassMetadata($manager, $class); + if (isset($this->persistableClasses[$class])) { + $metadata = $this->getMetadata($class); $generator = null; $generatorType = null; @@ -73,7 +78,7 @@ public function persist($object) } try { - $manager->persist($object); + $this->objectManager->persist($object); } catch (ORMException $exception) { if ($metadata->idGenerator instanceof ORMAssignedGenerator) { throw ObjectGeneratorPersisterExceptionFactory::createForEntityMissingAssignedIdForField($object); @@ -95,9 +100,27 @@ public function persist($object) */ public function flush() { - foreach ($this->managerRegistry->getManagers() as $manager) { - $manager->flush(); + $this->objectManager->flush(); + } + + /** + * @return string[] + */ + private function getPersistableClasses(ObjectManager $manager): 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(); + } } + + return $persistableClasses; } protected function configureIdGenerator(ORMClassMetadataInfo $metadata): void @@ -106,10 +129,11 @@ protected function configureIdGenerator(ORMClassMetadataInfo $metadata): void $metadata->setIdGenerator(new ORMAssignedGenerator()); } - private function getClassMetadata(ObjectManager $manager, string $class): ClassMetadata + private function getMetadata(string $class): ClassMetadata { if (false === array_key_exists($class, $this->metadata)) { - $this->metadata[$class] = $manager->getClassMetadata($class); + $classMetadata = $this->objectManager->getClassMetadata($class); + $this->metadata[$class] = $classMetadata; } return $this->metadata[$class]; diff --git a/src/Bridge/Doctrine/Purger/ManagerRegistryPurger.php b/src/Bridge/Doctrine/Purger/ManagerRegistryPurger.php new file mode 100644 index 00000000..6c840f68 --- /dev/null +++ b/src/Bridge/Doctrine/Purger/ManagerRegistryPurger.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Fidry\AliceDataFixtures\Bridge\Doctrine\Persister; + +use function array_map; +use Doctrine\Common\Persistence\ManagerRegistry; +use Doctrine\Common\Persistence\ObjectManager; +use Fidry\AliceDataFixtures\Bridge\Doctrine\Purger\ObjectManagerPurger; +use Fidry\AliceDataFixtures\Persistence\PurgeMode; +use Fidry\AliceDataFixtures\Persistence\PurgerFactoryInterface; +use Fidry\AliceDataFixtures\Persistence\PurgerInterface; +use InvalidArgumentException; +use Nelmio\Alice\IsAServiceTrait; + +/** + * @final + */ +/* final */ class ManagerRegistryPurger implements PurgerInterface, PurgerFactoryInterface +{ + use IsAServiceTrait; + + private $registry; + private $purgeMode; + + /** + * @var PurgerInterface[] + */ + private $purgers = []; + + public function __construct(ManagerRegistry $registry, PurgeMode $purgeMode = null) + { + $this->registry = $registry; + + $this->purgers = array_map( + function (ObjectManager $manager) use ($purgeMode): PurgerInterface { + return new ObjectManagerPurger($manager, $purgeMode); + }, + $registry->getManagers() + ); + } + + /** + * @inheritdoc + */ + public function create(PurgeMode $mode, PurgerInterface $purger = null): PurgerInterface + { + if (null !== $purger) { + throw new InvalidArgumentException('Cannot create a new purger from an existing one.'); + } + + return new self($this->registry, $mode); + } + + /** + * @inheritdoc + */ + public function purge(): void + { + foreach ($this->purgers as $purger) { + $purger->purge(); + } + } +} diff --git a/src/Bridge/Doctrine/Purger/ObjectManagerPurger.php b/src/Bridge/Doctrine/Purger/ObjectManagerPurger.php new file mode 100644 index 00000000..13075bc5 --- /dev/null +++ b/src/Bridge/Doctrine/Purger/ObjectManagerPurger.php @@ -0,0 +1,144 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Fidry\AliceDataFixtures\Bridge\Doctrine\Purger; + +use Doctrine\Common\DataFixtures\Purger\MongoDBPurger as DoctrineMongoDBPurger; +use Doctrine\Common\DataFixtures\Purger\ORMPurger as DoctrineOrmPurger; +use Doctrine\Common\DataFixtures\Purger\PHPCRPurger as DoctrinePhpCrPurger; +use Doctrine\Common\DataFixtures\Purger\PurgerInterface as DoctrinePurgerInterface; +use Doctrine\Common\Persistence\ObjectManager; +use Doctrine\DBAL\Driver\AbstractMySQLDriver; +use Doctrine\ODM\MongoDB\DocumentManager as DoctrineMongoDocumentManager; +use Doctrine\ODM\PHPCR\DocumentManager as DoctrinePhpCrDocumentManager; +use Doctrine\ORM\EntityManagerInterface; +use Fidry\AliceDataFixtures\Persistence\PurgeMode; +use Fidry\AliceDataFixtures\Persistence\PurgerFactoryInterface; +use Fidry\AliceDataFixtures\Persistence\PurgerInterface; +use InvalidArgumentException; +use Nelmio\Alice\IsAServiceTrait; + +/** + * Bridge for Doctrine purger. + * + * @author Vincent CHALAMON + * @final + */ +/* final */ class ObjectManagerPurger implements PurgerInterface, PurgerFactoryInterface +{ + use IsAServiceTrait; + + private $manager; + private $purgeMode; + private $purger; + + public function __construct(ObjectManager $manager, PurgeMode $purgeMode = null) + { + $this->manager = $manager; + $this->purgeMode = $purgeMode; + + $this->purger = static::createPurger($manager, $purgeMode); + } + + /** + * @inheritdoc + */ + public function create(PurgeMode $mode, PurgerInterface $purger = null): PurgerInterface + { + if (null === $purger) { + return new self($this->manager, $mode); + } + + if ($purger instanceof DoctrinePurgerInterface) { + $manager = $purger->getObjectManager(); + } elseif ($purger instanceof self) { + $manager = $purger->manager; + } else { + throw new InvalidArgumentException( + sprintf( + 'Expected purger to be either and instance of "%s" or "%s". Got "%s".', + DoctrinePurgerInterface::class, + __CLASS__, + get_class($purger) + ) + ); + } + + if (null === $manager) { + throw new InvalidArgumentException( + sprintf( + 'Expected purger "%s" to have an object manager, got "null" instead.', + get_class($purger) + ) + ); + } + + return new self($manager, $mode); + } + + /** + * @inheritdoc + */ + public function purge(): void + { + // Because MySQL rocks, you got to disable foreign key checks when doing a TRUNCATE unlike in for example + // PostgreSQL. This ideally should be done in the Purger of doctrine/data-fixtures but meanwhile we are doing + // it here. + // See the progress in https://github.com/doctrine/data-fixtures/pull/272 + $truncateOrm = ( + $this->purger instanceof DoctrineOrmPurger + && PurgeMode::createTruncateMode()->getValue() === $this->purgeMode->getValue() + && $this->purger->getObjectManager()->getConnection()->getDriver() instanceof AbstractMySQLDriver + ); + + if ($truncateOrm) { + $connection = $this->purger->getObjectManager()->getConnection(); + + $connection->exec('SET FOREIGN_KEY_CHECKS = 0;'); + } + + $this->purger->purge(); + + if ($truncateOrm && isset($connection)) { + $connection->exec('SET FOREIGN_KEY_CHECKS = 1;'); + } + } + + private static function createPurger(ObjectManager $manager, ?PurgeMode $purgeMode): DoctrinePurgerInterface + { + if ($manager instanceof EntityManagerInterface) { + $purger = new DoctrineOrmPurger($manager); + + if (null !== $purgeMode) { + $purger->setPurgeMode($purgeMode->getValue()); + } + + return $purger; + } + + if ($manager instanceof DoctrinePhpCrDocumentManager) { + return new DoctrinePhpCrPurger($manager); + } + + if ($manager instanceof DoctrineMongoDocumentManager) { + return new DoctrineMongoDBPurger($manager); + } + + throw new InvalidArgumentException( + sprintf( + 'Cannot create a purger for ObjectManager of class %s', + get_class($manager) + ) + ); + } +} diff --git a/src/Bridge/Doctrine/Purger/Purger.php b/src/Bridge/Doctrine/Purger/Purger.php index da53aed7..dd5ef975 100644 --- a/src/Bridge/Doctrine/Purger/Purger.php +++ b/src/Bridge/Doctrine/Purger/Purger.php @@ -13,132 +13,33 @@ namespace Fidry\AliceDataFixtures\Bridge\Doctrine\Purger; -use Doctrine\Common\DataFixtures\Purger\MongoDBPurger as DoctrineMongoDBPurger; -use Doctrine\Common\DataFixtures\Purger\ORMPurger as DoctrineOrmPurger; -use Doctrine\Common\DataFixtures\Purger\PHPCRPurger as DoctrinePhpCrPurger; -use Doctrine\Common\DataFixtures\Purger\PurgerInterface as DoctrinePurgerInterface; use Doctrine\Common\Persistence\ObjectManager; -use Doctrine\DBAL\Driver\AbstractMySQLDriver; -use Doctrine\ODM\MongoDB\DocumentManager as DoctrineMongoDocumentManager; -use Doctrine\ODM\PHPCR\DocumentManager as DoctrinePhpCrDocumentManager; -use Doctrine\ORM\EntityManagerInterface; +use const E_USER_DEPRECATED; use Fidry\AliceDataFixtures\Persistence\PurgeMode; -use Fidry\AliceDataFixtures\Persistence\PurgerFactoryInterface; -use Fidry\AliceDataFixtures\Persistence\PurgerInterface; -use InvalidArgumentException; -use Nelmio\Alice\IsAServiceTrait; +use function trigger_error; /** - * Bridge for Doctrine purger. + * @deprecated Use ObjectManagerPurger instead * - * @author Vincent CHALAMON - * @final + * @see ObjectManagerPurger */ -/* final */ class Purger implements PurgerInterface, PurgerFactoryInterface +/* final */ class Purger extends ObjectManagerPurger { - use IsAServiceTrait; - - private $manager; - private $purgeMode; - private $purger; - - public function __construct(ObjectManager $manager, PurgeMode $purgeMode = null) - { - $this->manager = $manager; - $this->purgeMode = $purgeMode; - - $this->purger = static::createPurger($manager, $purgeMode); - } - - /** - * @inheritdoc - */ - public function create(PurgeMode $mode, PurgerInterface $purger = null): PurgerInterface - { - if (null === $purger) { - return new self($this->manager, $mode); - } - - if ($purger instanceof DoctrinePurgerInterface) { - $manager = $purger->getObjectManager(); - } elseif ($purger instanceof self) { - $manager = $purger->manager; - } else { - throw new InvalidArgumentException( - sprintf( - 'Expected purger to be either and instance of "%s" or "%s". Got "%s".', - DoctrinePurgerInterface::class, - __CLASS__, - get_class($purger) - ) - ); - } - - if (null === $manager) { - throw new InvalidArgumentException( - sprintf( - 'Expected purger "%s" to have an object manager, got "null" instead.', - get_class($purger) - ) - ); - } - - return new self($manager, $mode); - } - /** * @inheritdoc */ - public function purge() + public function __construct(ObjectManager $manager, PurgeMode $purgeMode = null) { - // Because MySQL rocks, you got to disable foreign key checks when doing a TRUNCATE unlike in for example - // PostgreSQL. This ideally should be done in the Purger of doctrine/data-fixtures but meanwhile we are doing - // it here. - // See the progress in https://github.com/doctrine/data-fixtures/pull/272 - $truncateOrm = ( - $this->purger instanceof DoctrineOrmPurger - && PurgeMode::createTruncateMode()->getValue() === $this->purgeMode->getValue() - && $this->purger->getObjectManager()->getConnection()->getDriver() instanceof AbstractMySQLDriver + @trigger_error( + sprintf( + '"%s" has been deprecated since v1.2.0. Use "%s" instead.', + self::class, + ObjectManagerPurger::class + ), + E_USER_DEPRECATED ); - if ($truncateOrm) { - $connection = $this->purger->getObjectManager()->getConnection(); - - $connection->exec('SET FOREIGN_KEY_CHECKS = 0;'); - } - - $this->purger->purge(); - - if ($truncateOrm && isset($connection)) { - $connection->exec('SET FOREIGN_KEY_CHECKS = 1;'); - } + parent::__construct($manager, $purgeMode); } - private static function createPurger(ObjectManager $manager, ?PurgeMode $purgeMode): DoctrinePurgerInterface - { - if ($manager instanceof EntityManagerInterface) { - $purger = new DoctrineOrmPurger($manager); - - if (null !== $purgeMode) { - $purger->setPurgeMode($purgeMode->getValue()); - } - - return $purger; - } - - if ($manager instanceof DoctrinePhpCrDocumentManager) { - return new DoctrinePhpCrPurger($manager); - } - - if ($manager instanceof DoctrineMongoDocumentManager) { - return new DoctrineMongoDBPurger($manager); - } - - throw new InvalidArgumentException( - sprintf( - 'Cannot create a purger for ObjectManager of class %s', - get_class($manager) - ) - ); - } } diff --git a/src/Persistence/PurgerInterface.php b/src/Persistence/PurgerInterface.php index bfe67204..c286633b 100644 --- a/src/Persistence/PurgerInterface.php +++ b/src/Persistence/PurgerInterface.php @@ -34,6 +34,8 @@ interface PurgerInterface /** * Purges the database before loading. Depending of the implementation, the purge may truncate the database or * remove only a part of the database data. + * + * @return void The typehint is gonna be enforced from 2.0.0 onwards */ public function purge(); }