Skip to content

Commit

Permalink
Added RepositoryFactory [doctrine#891]
Browse files Browse the repository at this point in the history
  • Loading branch information
hilobok committed May 30, 2014
1 parent dc47303 commit f8065eb
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 18 deletions.
55 changes: 55 additions & 0 deletions lib/Doctrine/ODM/MongoDB/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use Doctrine\Common\Cache\Cache;
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver;
use Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver;
use Doctrine\ODM\MongoDB\Repository\DefaultRepositoryFactory;

/**
* Configuration class for the DocumentManager. When setting up your DocumentManager
Expand Down Expand Up @@ -374,4 +375,58 @@ public function getFilterClassName($name)
? $this->attributes['filters'][$name]
: null;
}

/**
* Sets default repository class.
*
* @param string $className
*
* @return void
*
* @throws MongoDBException If not is a ObjectRepository
*/
public function setDefaultRepositoryClassName($className)
{
$reflectionClass = new \ReflectionClass($className);

if ( ! $reflectionClass->implementsInterface('Doctrine\Common\Persistence\ObjectRepository')) {
throw MongoDBException::invalidDocumentRepository($className);
}

$this->attributes['defaultRepositoryClassName'] = $className;
}

/**
* Get default repository class.
*
* @return string
*/
public function getDefaultRepositoryClassName()
{
return isset($this->attributes['defaultRepositoryClassName'])
? $this->attributes['defaultRepositoryClassName']
: 'Doctrine\ODM\MongoDB\DocumentRepository';
}

/**
* Set the document repository factory.
*
* @param RepositoryFactory $repositoryFactory
*/
public function setRepositoryFactory(RepositoryFactory $repositoryFactory)
{
$this->attributes['repositoryFactory'] = $repositoryFactory;
}

/**
* Get the document repository factory.
*
* @return RepositoryFactory
*/
public function getRepositoryFactory()
{
return isset($this->attributes['repositoryFactory'])
? $this->attributes['repositoryFactory']
: new DefaultRepositoryFactory();
}
}
28 changes: 10 additions & 18 deletions lib/Doctrine/ODM/MongoDB/DocumentManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
use Doctrine\ODM\MongoDB\Mapping\ClassMetadataFactory;
use Doctrine\ODM\MongoDB\Proxy\ProxyFactory;
use Doctrine\ODM\MongoDB\Query\FilterCollection;
use Doctrine\ODM\MongoDB\Repository\RepositoryFactory;

/**
* The DocumentManager class is the central access point for managing the
Expand Down Expand Up @@ -99,6 +100,13 @@ class DocumentManager implements ObjectManager
*/
private $proxyFactory;

/**
* The repository factory used to create dynamic repositories.
*
* @var RepositoryFactory
*/
private $repositoryFactory;

/**
* SchemaManager instance
*
Expand Down Expand Up @@ -174,6 +182,7 @@ protected function __construct(Connection $conn = null, Configuration $config =
$this->config->getProxyNamespace(),
$this->config->getAutoGenerateProxyClasses()
);
$this->repositoryFactory = $this->config->getRepositoryFactory();
}

/**
Expand Down Expand Up @@ -505,24 +514,7 @@ public function unlock($document)
*/
public function getRepository($documentName)
{
$documentName = ltrim($documentName, '\\');

if (isset($this->repositories[$documentName])) {
return $this->repositories[$documentName];
}

$metadata = $this->getClassMetadata($documentName);
$customRepositoryClassName = $metadata->customRepositoryClassName;

if ($customRepositoryClassName !== null) {
$repository = new $customRepositoryClassName($this, $this->unitOfWork, $metadata);
} else {
$repository = new DocumentRepository($this, $this->unitOfWork, $metadata);
}

$this->repositories[$documentName] = $repository;

return $repository;
return $this->repositoryFactory->getRepository($this, $documentName);
}

/**
Expand Down
5 changes: 5 additions & 0 deletions lib/Doctrine/ODM/MongoDB/MongoDBException.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,9 @@ public static function queryNotIndexed($className, $unindexedFields)
implode(', ', $unindexedFields)
));
}

public static function invalidDocumentRepository($className)
{
return new self("Invalid repository class '".$className."'. It must be a Doctrine\Common\Persistence\ObjectRepository.");
}
}
57 changes: 57 additions & 0 deletions lib/Doctrine/ODM/MongoDB/Repository/DefaultRepositoryFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

namespace Doctrine\ODM\MongoDB\Repository;

use Doctrine\ODM\MongoDB\DocumentManager;

/**
* This factory is used to create default repository objects for entities at runtime.
*/
class DefaultRepositoryFactory implements RepositoryFactory
{
/**
* The list of DocumentRepository instances.
*
* @var array<\Doctrine\Common\Persistence\ObjectRepository>
*/
private $repositoryList = array();

/**
* {@inheritdoc}
*/
public function getRepository(DocumentManager $documentManager, $documentName)
{
$documentName = ltrim($documentName, '\\');

if (isset($this->repositoryList[$documentName])) {
return $this->repositoryList[$documentName];
}

$repository = $this->createRepository($documentManager, $documentName);

$this->repositoryList[$documentName] = $repository;

return $repository;
}

/**
* Create a new repository instance for a document class.
*
* @param DocumentManager $documentManager The DocumentManager instance.
* @param string $documentName The name of the document.
*
* @return \Doctrine\Common\Persistence\ObjectRepository
*/
protected function createRepository(DocumentManager $documentManager, $documentName)
{
$metadata = $documentManager->getClassMetadata($documentName);
$repositoryClassName = $metadata->customRepositoryClassName;

if ($repositoryClassName === null) {
$configuration = $documentManager->getConfiguration();
$repositoryClassName = $configuration->getDefaultRepositoryClassName();
}

return new $repositoryClassName($documentManager, $documentManager->getUnitOfWork(), $metadata);
}
}
21 changes: 21 additions & 0 deletions lib/Doctrine/ODM/MongoDB/Repository/RepositoryFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace Doctrine\ODM\MongoDB\Repository;

use Doctrine\ODM\MongoDB\DocumentManager;

/**
* Interface for document repository factory.
*/
interface RepositoryFactory
{
/**
* Gets the repository for a document class.
*
* @param DocumentManager $documentManager The DocumentManager instance.
* @param string $documentName The name of the document.
*
* @return \Doctrine\Common\Persistence\ObjectRepository
*/
public function getRepository(DocumentManager $documentManager, $documentName);
}

0 comments on commit f8065eb

Please sign in to comment.