From 7eb744126ba5081ea51441a893dd950046777383 Mon Sep 17 00:00:00 2001 From: Guilherme Blanco Date: Thu, 13 Jun 2013 21:47:40 -0400 Subject: [PATCH 1/5] Implemented support for RepositoryFactory. --- lib/Doctrine/ORM/Configuration.php | 50 ++++++++--- lib/Doctrine/ORM/EntityManager.php | 46 ++++------ .../Repository/DefaultRepositoryFactory.php | 89 +++++++++++++++++++ .../ORM/Repository/RepositoryFactory.php | 47 ++++++++++ .../ORM/Functional/Ticket/DDC2359Test.php | 5 +- 5 files changed, 195 insertions(+), 42 deletions(-) create mode 100644 lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php create mode 100644 lib/Doctrine/ORM/Repository/RepositoryFactory.php diff --git a/lib/Doctrine/ORM/Configuration.php b/lib/Doctrine/ORM/Configuration.php index 959a206dd..a1535de85 100644 --- a/lib/Doctrine/ORM/Configuration.php +++ b/lib/Doctrine/ORM/Configuration.php @@ -19,20 +19,22 @@ namespace Doctrine\ORM; -use Doctrine\Common\Cache\Cache; -use Doctrine\Common\Cache\ArrayCache; -use Doctrine\Common\Annotations\AnnotationRegistry; use Doctrine\Common\Annotations\AnnotationReader; -use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver; -use Doctrine\ORM\Mapping\Driver\AnnotationDriver; -use Doctrine\ORM\Mapping\QuoteStrategy; -use Doctrine\ORM\Mapping\DefaultQuoteStrategy; -use Doctrine\ORM\Mapping\NamingStrategy; -use Doctrine\ORM\Mapping\DefaultNamingStrategy; -use Doctrine\ORM\Mapping\EntityListenerResolver; -use Doctrine\ORM\Mapping\DefaultEntityListenerResolver; -use Doctrine\Common\Annotations\SimpleAnnotationReader; +use Doctrine\Common\Annotations\AnnotationRegistry; use Doctrine\Common\Annotations\CachedReader; +use Doctrine\Common\Annotations\SimpleAnnotationReader; +use Doctrine\Common\Cache\ArrayCache; +use Doctrine\Common\Cache\Cache; +use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver; +use Doctrine\ORM\Mapping\DefaultEntityListenerResolver; +use Doctrine\ORM\Mapping\DefaultNamingStrategy; +use Doctrine\ORM\Mapping\DefaultQuoteStrategy; +use Doctrine\ORM\Mapping\Driver\AnnotationDriver; +use Doctrine\ORM\Mapping\EntityListenerResolver; +use Doctrine\ORM\Mapping\NamingStrategy; +use Doctrine\ORM\Mapping\QuoteStrategy; +use Doctrine\ORM\Repository\DefaultRepositoryFactory; +use Doctrine\ORM\Repository\RepositoryFactoryInterface; /** * Configuration container for all configuration options of Doctrine. @@ -779,4 +781,28 @@ class Configuration extends \Doctrine\DBAL\Configuration return $this->_attributes['entityListenerResolver']; } + + /** + * Set the entity repository factory. + * + * @since 2.5 + * @param \Doctrine\ORM\Repository\RepositoryFactoryInterface $repositoryFactory + */ + public function setRepositoryFactory(RepositoryFactoryInterface $repositoryFactory) + { + $this->_attributes['repositoryFactory'] = $repositoryFactory; + } + + /** + * Get the entity repository factory. + * + * @since 2.5 + * @return \Doctrine\ORM\Repository\RepositoryFactoryInterface + */ + public function getRepositoryFactory() + { + return isset($this->_attributes['repositoryFactory']) + ? $this->_attributes['repositoryFactory'] + : new DefaultRepositoryFactory(); + } } diff --git a/lib/Doctrine/ORM/EntityManager.php b/lib/Doctrine/ORM/EntityManager.php index bc0d4ef18..8ee39cf06 100644 --- a/lib/Doctrine/ORM/EntityManager.php +++ b/lib/Doctrine/ORM/EntityManager.php @@ -85,13 +85,6 @@ use Doctrine\Common\Util\ClassUtils; */ private $metadataFactory; - /** - * The EntityRepository instances. - * - * @var array - */ - private $repositories = array(); - /** * The UnitOfWork used to coordinate object-level transactions. * @@ -120,6 +113,13 @@ use Doctrine\Common\Util\ClassUtils; */ private $proxyFactory; + /** + * The repository factory used to create dynamic repositories. + * + * @var \Doctrine\ORM\Repository\RepositoryFactory + */ + private $repositoryFactory; + /** * The expression builder instance used to generate query expressions. * @@ -151,9 +151,9 @@ use Doctrine\Common\Util\ClassUtils; */ protected function __construct(Connection $conn, Configuration $config, EventManager $eventManager) { - $this->conn = $conn; - $this->config = $config; - $this->eventManager = $eventManager; + $this->conn = $conn; + $this->config = $config; + $this->eventManager = $eventManager; $metadataFactoryClassName = $config->getClassMetadataFactoryName(); @@ -161,6 +161,11 @@ use Doctrine\Common\Util\ClassUtils; $this->metadataFactory->setEntityManager($this); $this->metadataFactory->setCacheDriver($this->config->getMetadataCacheImpl()); + $repositoryFactory = $config->getRepositoryFactory(); + + $this->repositoryFactory = $repositoryFactory; + $this->repositoryFactory->setEntityManager($this); + $this->unitOfWork = new UnitOfWork($this); $this->proxyFactory = new ProxyFactory( $this, @@ -758,28 +763,11 @@ use Doctrine\Common\Util\ClassUtils; * * @param string $entityName The name of the entity. * - * @return EntityRepository The repository class. + * @return \Doctrine\ORM\EntityRepository The repository class. */ public function getRepository($entityName) { - $entityName = ltrim($entityName, '\\'); - - if (isset($this->repositories[$entityName])) { - return $this->repositories[$entityName]; - } - - $metadata = $this->getClassMetadata($entityName); - $repositoryClassName = $metadata->customRepositoryClassName; - - if ($repositoryClassName === null) { - $repositoryClassName = $this->config->getDefaultRepositoryClassName(); - } - - $repository = new $repositoryClassName($this, $metadata); - - $this->repositories[$entityName] = $repository; - - return $repository; + return $this->repositoryFactory->getRepository($entityName); } /** diff --git a/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php b/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php new file mode 100644 index 000000000..b97424810 --- /dev/null +++ b/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php @@ -0,0 +1,89 @@ +. + */ + +namespace Doctrine\ORM\Repository; + +use Doctrine\ORM\EntityManagerInterface; + +/** + * This factory is used to create default repository objects for entities at runtime. + * + * @author Guilherme Blanco + * @since 2.5 + */ +class DefaultRepositoryFactory implements RepositoryFactory +{ + /** + * The list of EntityRepository instances. + * + * @var array<\Doctrine\ORM\EntityRepository> + */ + private $repositoryList = array(); + + /** + * @var \Doctrine\ORM\EntityManagerInterface + */ + protected $entityManager; + + /** + * {@inheritdoc} + */ + public function setEntityManager(EntityManagerInterface $entityManager) + { + $this->entityManager = $entityManager; + } + + /** + * {@inheritdoc} + */ + public function getRepository($entityName) + { + $entityName = ltrim($entityName, '\\'); + + if (isset($this->repositoryList[$entityName])) { + return $this->repositoryList[$entityName]; + } + + $repository = $this->createRepository($entityName); + + $this->repositoryList[$entityName] = $repository; + + return $repository; + } + + /** + * Create a new repository instance for an entity class. + * + * @param string $entityName The name of the entity. + * + * @return \Doctrine\ORM\EntityRepository + */ + protected function createRepository($entityName) + { + $metadata = $this->entityManager->getClassMetadata($entityName); + $repositoryClassName = $metadata->customRepositoryClassName; + + if ($repositoryClassName === null) { + $configuration = $this->entityManager->getConfiguration(); + $repositoryClassName = $configuration->getDefaultRepositoryClassName(); + } + + return new $repositoryClassName($this->entityManager, $metadata); + } +} \ No newline at end of file diff --git a/lib/Doctrine/ORM/Repository/RepositoryFactory.php b/lib/Doctrine/ORM/Repository/RepositoryFactory.php new file mode 100644 index 000000000..cd3e20a26 --- /dev/null +++ b/lib/Doctrine/ORM/Repository/RepositoryFactory.php @@ -0,0 +1,47 @@ +. + */ + +namespace Doctrine\ORM\Repository; + +use Doctrine\ORM\EntityManagerInterface; + +/** + * Interface for entity repository factory. + * + * @author Guilherme Blanco + * @since 2.5 + */ +interface RepositoryFactory +{ + /** + * Set the entity manager. + * + * @param \Doctrine\ORM\EntityManagerInterface $entityManager + */ + public function setEntityManager(EntityManagerInterface $entityManager); + + /** + * Gets the repository for an entity class. + * + * @param string $entityName The name of the entity. + * + * @return \Doctrine\ORM\EntityRepository + */ + public function getRepository($entityName); +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2359Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2359Test.php index b9670d27a..c1189d797 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2359Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2359Test.php @@ -19,18 +19,21 @@ class DDC2359Test extends \PHPUnit_Framework_TestCase $mockDriver = $this->getMock('Doctrine\\Common\\Persistence\\Mapping\\Driver\\MappingDriver'); $mockMetadata = $this->getMock('Doctrine\\ORM\\Mapping\\ClassMetadata', array(), array(), '', false); $entityManager = $this->getMock('Doctrine\\ORM\\EntityManager', array(), array(), '', false); + /* @var $metadataFactory \Doctrine\ORM\Mapping\ClassMetadataFactory|\PHPUnit_Framework_MockObject_MockObject */ $metadataFactory = $this->getMock( 'Doctrine\\ORM\\Mapping\\ClassMetadataFactory', array('newClassMetadataInstance', 'wakeupReflection') ); - $configuration = $this->getMock('Doctrine\\ORM\\Configuration'); + + $configuration = $this->getMock('Doctrine\\ORM\\Configuration', array('getMetadataDriverImpl')); $connection = $this->getMock('Doctrine\\DBAL\\Connection', array(), array(), '', false); $configuration ->expects($this->any()) ->method('getMetadataDriverImpl') ->will($this->returnValue($mockDriver)); + $entityManager->expects($this->any())->method('getConfiguration')->will($this->returnValue($configuration)); $entityManager->expects($this->any())->method('getConnection')->will($this->returnValue($connection)); $entityManager From 37e7e841c350ac6920ef5dc80b242659963b0868 Mon Sep 17 00:00:00 2001 From: Guilherme Blanco Date: Thu, 13 Jun 2013 23:31:18 -0400 Subject: [PATCH 2/5] Fixed wrong interface. --- lib/Doctrine/ORM/Configuration.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Doctrine/ORM/Configuration.php b/lib/Doctrine/ORM/Configuration.php index a1535de85..073543ed9 100644 --- a/lib/Doctrine/ORM/Configuration.php +++ b/lib/Doctrine/ORM/Configuration.php @@ -34,7 +34,7 @@ use Doctrine\ORM\Mapping\EntityListenerResolver; use Doctrine\ORM\Mapping\NamingStrategy; use Doctrine\ORM\Mapping\QuoteStrategy; use Doctrine\ORM\Repository\DefaultRepositoryFactory; -use Doctrine\ORM\Repository\RepositoryFactoryInterface; +use Doctrine\ORM\Repository\RepositoryFactory; /** * Configuration container for all configuration options of Doctrine. @@ -786,9 +786,9 @@ class Configuration extends \Doctrine\DBAL\Configuration * Set the entity repository factory. * * @since 2.5 - * @param \Doctrine\ORM\Repository\RepositoryFactoryInterface $repositoryFactory + * @param \Doctrine\ORM\Repository\RepositoryFactory $repositoryFactory */ - public function setRepositoryFactory(RepositoryFactoryInterface $repositoryFactory) + public function setRepositoryFactory(RepositoryFactory $repositoryFactory) { $this->_attributes['repositoryFactory'] = $repositoryFactory; } @@ -797,7 +797,7 @@ class Configuration extends \Doctrine\DBAL\Configuration * Get the entity repository factory. * * @since 2.5 - * @return \Doctrine\ORM\Repository\RepositoryFactoryInterface + * @return \Doctrine\ORM\Repository\RepositoryFactory */ public function getRepositoryFactory() { From a66fc03441cff3f9ad2047852d1dcbfed9f48683 Mon Sep 17 00:00:00 2001 From: Guilherme Blanco Date: Thu, 13 Jun 2013 23:53:53 -0400 Subject: [PATCH 3/5] Reducing dependency on RepositoryFactory by providing EntityManager as a getRepository argument. --- lib/Doctrine/ORM/EntityManager.php | 12 +++----- .../Repository/DefaultRepositoryFactory.php | 28 ++++++------------- .../ORM/Repository/RepositoryFactory.php | 12 ++------ 3 files changed, 15 insertions(+), 37 deletions(-) diff --git a/lib/Doctrine/ORM/EntityManager.php b/lib/Doctrine/ORM/EntityManager.php index 8ee39cf06..acaec984d 100644 --- a/lib/Doctrine/ORM/EntityManager.php +++ b/lib/Doctrine/ORM/EntityManager.php @@ -161,13 +161,9 @@ use Doctrine\Common\Util\ClassUtils; $this->metadataFactory->setEntityManager($this); $this->metadataFactory->setCacheDriver($this->config->getMetadataCacheImpl()); - $repositoryFactory = $config->getRepositoryFactory(); - - $this->repositoryFactory = $repositoryFactory; - $this->repositoryFactory->setEntityManager($this); - - $this->unitOfWork = new UnitOfWork($this); - $this->proxyFactory = new ProxyFactory( + $this->repositoryFactory = $config->getRepositoryFactory(); + $this->unitOfWork = new UnitOfWork($this); + $this->proxyFactory = new ProxyFactory( $this, $config->getProxyDir(), $config->getProxyNamespace(), @@ -767,7 +763,7 @@ use Doctrine\Common\Util\ClassUtils; */ public function getRepository($entityName) { - return $this->repositoryFactory->getRepository($entityName); + return $this->repositoryFactory->getRepository($this, $entityName); } /** diff --git a/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php b/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php index b97424810..0caab1b63 100644 --- a/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php +++ b/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php @@ -36,23 +36,10 @@ class DefaultRepositoryFactory implements RepositoryFactory */ private $repositoryList = array(); - /** - * @var \Doctrine\ORM\EntityManagerInterface - */ - protected $entityManager; - /** * {@inheritdoc} */ - public function setEntityManager(EntityManagerInterface $entityManager) - { - $this->entityManager = $entityManager; - } - - /** - * {@inheritdoc} - */ - public function getRepository($entityName) + public function getRepository(EntityManagerInterface $entityManager, $entityName) { $entityName = ltrim($entityName, '\\'); @@ -60,7 +47,7 @@ class DefaultRepositoryFactory implements RepositoryFactory return $this->repositoryList[$entityName]; } - $repository = $this->createRepository($entityName); + $repository = $this->createRepository($entityManager, $entityName); $this->repositoryList[$entityName] = $repository; @@ -70,20 +57,21 @@ class DefaultRepositoryFactory implements RepositoryFactory /** * Create a new repository instance for an entity class. * - * @param string $entityName The name of the entity. + * @param \Doctrine\ORM\EntityManagerInterface $entityManager The EntityManager instance. + * @param string $entityName The name of the entity. * * @return \Doctrine\ORM\EntityRepository */ - protected function createRepository($entityName) + protected function createRepository(EntityManagerInterface $entityManager, $entityName) { - $metadata = $this->entityManager->getClassMetadata($entityName); + $metadata = $entityManager->getClassMetadata($entityName); $repositoryClassName = $metadata->customRepositoryClassName; if ($repositoryClassName === null) { - $configuration = $this->entityManager->getConfiguration(); + $configuration = $entityManager->getConfiguration(); $repositoryClassName = $configuration->getDefaultRepositoryClassName(); } - return new $repositoryClassName($this->entityManager, $metadata); + return new $repositoryClassName($entityManager, $metadata); } } \ No newline at end of file diff --git a/lib/Doctrine/ORM/Repository/RepositoryFactory.php b/lib/Doctrine/ORM/Repository/RepositoryFactory.php index cd3e20a26..faf7d6c81 100644 --- a/lib/Doctrine/ORM/Repository/RepositoryFactory.php +++ b/lib/Doctrine/ORM/Repository/RepositoryFactory.php @@ -29,19 +29,13 @@ use Doctrine\ORM\EntityManagerInterface; */ interface RepositoryFactory { - /** - * Set the entity manager. - * - * @param \Doctrine\ORM\EntityManagerInterface $entityManager - */ - public function setEntityManager(EntityManagerInterface $entityManager); - /** * Gets the repository for an entity class. * - * @param string $entityName The name of the entity. + * @param \Doctrine\ORM\EntityManagerInterface $entityManager The EntityManager instance. + * @param string $entityName The name of the entity. * * @return \Doctrine\ORM\EntityRepository */ - public function getRepository($entityName); + public function getRepository(EntityManagerInterface $entityManager, $entityName); } \ No newline at end of file From 3488049c18849a0cb942f4fea00501fa11727a83 Mon Sep 17 00:00:00 2001 From: Guilherme Blanco Date: Thu, 13 Jun 2013 23:59:08 -0400 Subject: [PATCH 4/5] Reduced granularity of DefaultRepositoryFactory reference to ObjectRepository instances, in cases where consumers are completely rewrote EntityRepository. --- lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php | 4 ++-- lib/Doctrine/ORM/Repository/RepositoryFactory.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php b/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php index 0caab1b63..932a1108c 100644 --- a/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php +++ b/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php @@ -32,7 +32,7 @@ class DefaultRepositoryFactory implements RepositoryFactory /** * The list of EntityRepository instances. * - * @var array<\Doctrine\ORM\EntityRepository> + * @var array<\Doctrine\Common\Persistence\ObjectRepository> */ private $repositoryList = array(); @@ -60,7 +60,7 @@ class DefaultRepositoryFactory implements RepositoryFactory * @param \Doctrine\ORM\EntityManagerInterface $entityManager The EntityManager instance. * @param string $entityName The name of the entity. * - * @return \Doctrine\ORM\EntityRepository + * @return \Doctrine\Common\Persistence\ObjectRepository */ protected function createRepository(EntityManagerInterface $entityManager, $entityName) { diff --git a/lib/Doctrine/ORM/Repository/RepositoryFactory.php b/lib/Doctrine/ORM/Repository/RepositoryFactory.php index faf7d6c81..00efca2c7 100644 --- a/lib/Doctrine/ORM/Repository/RepositoryFactory.php +++ b/lib/Doctrine/ORM/Repository/RepositoryFactory.php @@ -35,7 +35,7 @@ interface RepositoryFactory * @param \Doctrine\ORM\EntityManagerInterface $entityManager The EntityManager instance. * @param string $entityName The name of the entity. * - * @return \Doctrine\ORM\EntityRepository + * @return \Doctrine\Common\Persistence\ObjectRepository */ public function getRepository(EntityManagerInterface $entityManager, $entityName); } \ No newline at end of file From 52b3fc1fc3b1adfe17290126712916196f5b5345 Mon Sep 17 00:00:00 2001 From: Guilherme Blanco Date: Fri, 14 Jun 2013 12:07:28 -0400 Subject: [PATCH 5/5] Updated since php doc tag. --- lib/Doctrine/ORM/Configuration.php | 4 ++-- lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php | 2 +- lib/Doctrine/ORM/Repository/RepositoryFactory.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Doctrine/ORM/Configuration.php b/lib/Doctrine/ORM/Configuration.php index 073543ed9..3a096ba21 100644 --- a/lib/Doctrine/ORM/Configuration.php +++ b/lib/Doctrine/ORM/Configuration.php @@ -785,7 +785,7 @@ class Configuration extends \Doctrine\DBAL\Configuration /** * Set the entity repository factory. * - * @since 2.5 + * @since 2.4 * @param \Doctrine\ORM\Repository\RepositoryFactory $repositoryFactory */ public function setRepositoryFactory(RepositoryFactory $repositoryFactory) @@ -796,7 +796,7 @@ class Configuration extends \Doctrine\DBAL\Configuration /** * Get the entity repository factory. * - * @since 2.5 + * @since 2.4 * @return \Doctrine\ORM\Repository\RepositoryFactory */ public function getRepositoryFactory() diff --git a/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php b/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php index 932a1108c..2774dea68 100644 --- a/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php +++ b/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php @@ -25,7 +25,7 @@ use Doctrine\ORM\EntityManagerInterface; * This factory is used to create default repository objects for entities at runtime. * * @author Guilherme Blanco - * @since 2.5 + * @since 2.4 */ class DefaultRepositoryFactory implements RepositoryFactory { diff --git a/lib/Doctrine/ORM/Repository/RepositoryFactory.php b/lib/Doctrine/ORM/Repository/RepositoryFactory.php index 00efca2c7..f3af43ebe 100644 --- a/lib/Doctrine/ORM/Repository/RepositoryFactory.php +++ b/lib/Doctrine/ORM/Repository/RepositoryFactory.php @@ -25,7 +25,7 @@ use Doctrine\ORM\EntityManagerInterface; * Interface for entity repository factory. * * @author Guilherme Blanco - * @since 2.5 + * @since 2.4 */ interface RepositoryFactory {