diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 20c96b0..301f5a9 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -138,6 +138,7 @@ class Configuration ->children() ->scalarNode('driver')->end() ->scalarNode('model')->end() + ->scalarNode('repository')->end() ->scalarNode('identifier')->defaultValue('id')->end() ->arrayNode('provider') ->children() diff --git a/DependencyInjection/FOQElasticaExtension.php b/DependencyInjection/FOQElasticaExtension.php index aa165d0..672c53f 100644 --- a/DependencyInjection/FOQElasticaExtension.php +++ b/DependencyInjection/FOQElasticaExtension.php @@ -305,6 +305,15 @@ class FOQElasticaExtension extends Extension $finderDef->replaceArgument(1, new Reference($elasticaToModelId)); $container->setDefinition($finderId, $finderDef); + $managerDef = $container->getDefinition('foq_elastica.manager'); + $arguments = array( $typeConfig['model'], new Reference($finderId)); + if (isset($typeConfig['repository'])) { + $arguments[] = $typeConfig['repository']; + } + + $managerDef->addMethodCall('addEntity', $arguments); + $container->setDefinition('foq_elastica.manager', $managerDef); + return $finderId; } diff --git a/Manager.php b/Manager.php new file mode 100644 index 0000000..904dcb1 --- /dev/null +++ b/Manager.php @@ -0,0 +1,57 @@ + + * + * Allows retrieval of basic or custom repository for mapped Doctrine + * entities/documents. + */ +class Manager +{ + protected $entities; + protected $repositories; + + public function addEntity($entityName, $finder, $repositoryName = null) + { + $this->entities[$entityName]= array(); + $this->entities[$entityName]['finder'] = $finder; + $this->entities[$entityName]['repositoryName'] = $repositoryName; + } + + /** + * Return repository for entity + * + * Returns custom repository if one specified otherwise + * returns a basic respository. + */ + public function getRepository($entityName) + { + if (isset($this->repositories[$entityName])) { + return $this->repositories[$entityName]; + } + + if (!isset($this->entities[$entityName])) { + throw new RuntimeException(sprintf('No search finder configured for %s', $entityName)); + } + + if (isset($this->entities[$entityName]['repositoryName'])) { + + $repositoryName = $this->entities[$entityName]['repositoryName']; + if (!class_exists($repositoryName)) { + throw new RuntimeException(sprintf('%s repository for %s does not exist', $repositoryName, $entityName)); + } + $repository = new $repositoryName($this->entities[$entityName]['finder']); + $this->repositories[$entityName] = $repository; + return $repository; + } + + $repository = new Repository($this->entities[$entityName]['finder']); + $this->repositories[$entityName] = $repository; + return $repository; + } + +} diff --git a/Repository.php b/Repository.php new file mode 100644 index 0000000..44a42c8 --- /dev/null +++ b/Repository.php @@ -0,0 +1,31 @@ + + * + * Basic respoitory to be extended to hold custom queries to be run + * in the finder. + */ +class Repository +{ + protected $finder; + + public function __construct($finder) + { + $this->finder = $finder; + } + + + public function find($query) + { + return $this->finder->find($query); + } + + public function findPaginated($query) + { + return $this->finder->findPaginated($query); + } + +} diff --git a/Resources/config/config.xml b/Resources/config/config.xml index add426b..f771de9 100644 --- a/Resources/config/config.xml +++ b/Resources/config/config.xml @@ -10,6 +10,7 @@ Elastica_Type FOQ\ElasticaBundle\Logger\ElasticaLogger FOQ\ElasticaBundle\DataCollector\ElasticaDataCollector + FOQ\ElasticaBundle\Manager @@ -62,6 +63,8 @@ + + diff --git a/Tests/ManagerTest.php b/Tests/ManagerTest.php new file mode 100644 index 0000000..a1175a0 --- /dev/null +++ b/Tests/ManagerTest.php @@ -0,0 +1,74 @@ + + */ +class ManagerTest extends \PHPUnit_Framework_TestCase +{ + + public function testThatGetRepositoryReturnsDefaultRepository() + { + $finderMock = $this->getMockBuilder('FOQ\ElasticaBundle\Finder\TransformedFinder') + ->disableOriginalConstructor() + ->getMock(); + + $entityName = 'Test Entity'; + + $manager = new Manager($finderMock); + $manager->addEntity($entityName, $finderMock); + $repository = $manager->getRepository($entityName); + $this->assertInstanceOf('FOQ\ElasticaBundle\Repository', $repository); + } + + public function testThatGetRepositoryReturnsCustomRepository() + { + $finderMock = $this->getMockBuilder('FOQ\ElasticaBundle\Finder\TransformedFinder') + ->disableOriginalConstructor() + ->getMock(); + + $entityName = 'Test Entity'; + + $manager = new Manager($finderMock); + $manager->addEntity($entityName, $finderMock, 'FOQ\ElasticaBundle\Tests\CustomRepository'); + $repository = $manager->getRepository($entityName); + $this->assertInstanceOf('FOQ\ElasticaBundle\Tests\CustomRepository', $repository); + } + + /** + * @expectedException RuntimeException + */ + public function testThatGetRepositoryThrowsExceptionIfEntityNotConfigured() + { + $finderMock = $this->getMockBuilder('FOQ\ElasticaBundle\Finder\TransformedFinder') + ->disableOriginalConstructor() + ->getMock(); + + $entityName = 'Test Entity'; + + $manager = new Manager($finderMock); + $manager->addEntity($entityName, $finderMock); + $manager->getRepository('Missing Entity'); + } + + /** + * @expectedException RuntimeException + */ + public function testThatGetRepositoryThrowsExceptionIfCustomRepositoryNotFound() + { + $finderMock = $this->getMockBuilder('FOQ\ElasticaBundle\Finder\TransformedFinder') + ->disableOriginalConstructor() + ->getMock(); + + $entityName = 'Test Entity'; + + $manager = new Manager($finderMock); + $manager->addEntity($entityName, $finderMock, 'FOQ\ElasticaBundle\Tests\MissingRepository'); + $manager->getRepository('Missing Entity'); + } +} diff --git a/Tests/RepositoryTest.php b/Tests/RepositoryTest.php new file mode 100644 index 0000000..1b44543 --- /dev/null +++ b/Tests/RepositoryTest.php @@ -0,0 +1,43 @@ + + */ +class RepositoryTest extends \PHPUnit_Framework_TestCase +{ + + public function testThatFindCallsFindOnFinder() + { + $testQuery = 'Test Query'; + + $finderMock = $this->getMockBuilder('FOQ\ElasticaBundle\Finder\TransformedFinder') + ->disableOriginalConstructor() + ->getMock(); + $finderMock->expects($this->once()) + ->method('find') + ->with($this->equalTo($testQuery)); + + $repository = new Repository($finderMock); + $repository->find($testQuery); + } + + public function testThatFindPaginatedCallsFindPaginatedOnFinder() + { + $testQuery = 'Test Query'; + + $finderMock = $this->getMockBuilder('FOQ\ElasticaBundle\Finder\TransformedFinder') + ->disableOriginalConstructor() + ->getMock(); + $finderMock->expects($this->once()) + ->method('findPaginated') + ->with($this->equalTo($testQuery)); + + $repository = new Repository($finderMock); + $repository->findPaginated($testQuery); + } + +}