Merge branch '2.1.x'
Conflicts: Tests/ResetterTest.php
This commit is contained in:
commit
3c26f157aa
10 changed files with 263 additions and 9 deletions
|
|
@ -179,6 +179,7 @@ class Configuration implements ConfigurationInterface
|
|||
->children()
|
||||
->scalarNode('hydrate')->defaultTrue()->end()
|
||||
->scalarNode('ignore_missing')->defaultFalse()->end()
|
||||
->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
|
||||
->scalarNode('service')->end()
|
||||
->end()
|
||||
->end()
|
||||
|
|
@ -270,6 +271,7 @@ class Configuration implements ConfigurationInterface
|
|||
->children()
|
||||
->scalarNode('hydrate')->defaultTrue()->end()
|
||||
->scalarNode('ignore_missing')->defaultFalse()->end()
|
||||
->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
|
||||
->scalarNode('service')->end()
|
||||
->end()
|
||||
->end()
|
||||
|
|
@ -284,6 +286,7 @@ class Configuration implements ConfigurationInterface
|
|||
->end()
|
||||
->append($this->getIdNode())
|
||||
->append($this->getMappingsNode())
|
||||
->append($this->getDynamicTemplateNode())
|
||||
->append($this->getSourceNode())
|
||||
->append($this->getBoostNode())
|
||||
->append($this->getRoutingNode())
|
||||
|
|
@ -316,6 +319,37 @@ class Configuration implements ConfigurationInterface
|
|||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array node used for "dynamic_templates".
|
||||
*/
|
||||
public function getDynamicTemplateNode()
|
||||
{
|
||||
$builder = new TreeBuilder();
|
||||
$node = $builder->root('dynamic_templates');
|
||||
|
||||
$node
|
||||
->useAttributeAsKey('name')
|
||||
->prototype('array')
|
||||
->children()
|
||||
->scalarNode('match')->isRequired()->end()
|
||||
->scalarNode('match_mapping_type')->end()
|
||||
->arrayNode('mapping')
|
||||
->isRequired()
|
||||
->children()
|
||||
->scalarNode('type')->end()
|
||||
->scalarNode('index')->end()
|
||||
->arrayNode('fields')
|
||||
->children()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
;
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Symfony\Component\Config\Definition\Builder\NodeBuilder $node The node to which to attach the field config to
|
||||
* @param array $nestings the nested mappings for the current field level
|
||||
|
|
|
|||
|
|
@ -232,6 +232,12 @@ class FOSElasticaExtension extends Extension
|
|||
if (isset($type['index'])) {
|
||||
$this->indexConfigs[$indexName]['config']['mappings'][$name]['index'] = $type['index'];
|
||||
}
|
||||
if (!empty($type['dynamic_templates'])) {
|
||||
$this->indexConfigs[$indexName]['config']['mappings'][$name]['dynamic_templates'] = array();
|
||||
foreach ($type['dynamic_templates'] as $templateName => $templateData) {
|
||||
$this->indexConfigs[$indexName]['config']['mappings'][$name]['dynamic_templates'][] = array($templateName => $templateData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -304,7 +310,8 @@ class FOSElasticaExtension extends Extension
|
|||
$serviceDef->replaceArgument($argPos + 1, array(
|
||||
'hydrate' => $typeConfig['elastica_to_model_transformer']['hydrate'],
|
||||
'identifier' => $typeConfig['identifier'],
|
||||
'ignore_missing' => $typeConfig['elastica_to_model_transformer']['ignore_missing']
|
||||
'ignore_missing' => $typeConfig['elastica_to_model_transformer']['ignore_missing'],
|
||||
'query_builder_method' => $typeConfig['elastica_to_model_transformer']['query_builder_method']
|
||||
));
|
||||
$container->setDefinition($serviceId, $serviceDef);
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ abstract class AbstractElasticaToModelTransformer implements ElasticaToModelTran
|
|||
'hydrate' => true,
|
||||
'identifier' => 'id',
|
||||
'ignore_missing' => false,
|
||||
'query_builder_method' => 'createQueryBuilder',
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class ElasticaToModelTransformer extends AbstractElasticaToModelTransformer
|
|||
{
|
||||
return $this->registry
|
||||
->getManagerForClass($this->objectClass)
|
||||
->createQueryBuilder($this->objectClass)
|
||||
->{$this->options['query_builder_method']}($this->objectClass)
|
||||
->field($this->options['identifier'])->in($identifierValues)
|
||||
->hydrate($hydrate)
|
||||
->getQuery()
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ use Doctrine\ORM\Query;
|
|||
*/
|
||||
class ElasticaToModelTransformer extends AbstractElasticaToModelTransformer
|
||||
{
|
||||
const ENTITY_ALIAS = 'o';
|
||||
|
||||
/**
|
||||
* Fetch objects for theses identifier values
|
||||
*
|
||||
|
|
@ -25,14 +27,25 @@ class ElasticaToModelTransformer extends AbstractElasticaToModelTransformer
|
|||
return array();
|
||||
}
|
||||
$hydrationMode = $hydrate ? Query::HYDRATE_OBJECT : Query::HYDRATE_ARRAY;
|
||||
$qb = $this->registry
|
||||
->getManagerForClass($this->objectClass)
|
||||
->getRepository($this->objectClass)
|
||||
->createQueryBuilder('o');
|
||||
/* @var $qb \Doctrine\ORM\QueryBuilder */
|
||||
$qb->where($qb->expr()->in('o.'.$this->options['identifier'], ':values'))
|
||||
|
||||
$qb = $this->getEntityQueryBuilder();
|
||||
$qb->where($qb->expr()->in(static::ENTITY_ALIAS.'.'.$this->options['identifier'], ':values'))
|
||||
->setParameter('values', $identifierValues);
|
||||
|
||||
return $qb->getQuery()->setHydrationMode($hydrationMode)->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a query builder to be used for querying by identifiers
|
||||
*
|
||||
* @return \Doctrine\ORM\QueryBuilder
|
||||
*/
|
||||
protected function getEntityQueryBuilder()
|
||||
{
|
||||
$repository = $this->registry
|
||||
->getManagerForClass($this->objectClass)
|
||||
->getRepository($this->objectClass);
|
||||
|
||||
return $repository->{$this->options['query_builder_method']}(static::ENTITY_ALIAS);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
30
README.md
30
README.md
|
|
@ -822,3 +822,33 @@ fos_elastica:
|
|||
lastlogin: { type: date, format: basic_date_time }
|
||||
birthday: { type: date, format: "yyyy-MM-dd" }
|
||||
```
|
||||
|
||||
#### Dynamic templates
|
||||
|
||||
Dynamic templates allow to define mapping templates that will be
|
||||
applied when dynamic introduction of fields / objects happens.
|
||||
|
||||
[Documentation](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-root-object-type.html#_dynamic_templates)
|
||||
|
||||
```yaml
|
||||
fos_elastica:
|
||||
clients:
|
||||
default: { host: localhost, port: 9200 }
|
||||
indexes:
|
||||
site:
|
||||
types:
|
||||
user:
|
||||
dynamic_templates:
|
||||
my_template_1:
|
||||
match: apples_*
|
||||
mapping:
|
||||
type: float
|
||||
my_template_2:
|
||||
match: *
|
||||
match_mapping_type: string
|
||||
mapping:
|
||||
type: string
|
||||
index: not_analyzed
|
||||
mappings:
|
||||
username: { type: string }
|
||||
```
|
||||
|
|
|
|||
|
|
@ -78,6 +78,10 @@ class Resetter
|
|||
$mapping->setParam('_parent', array('type' => $indexConfig['_parent']['type']));
|
||||
}
|
||||
|
||||
if (isset($indexConfig['dynamic_templates'])) {
|
||||
$mapping->setParam('dynamic_templates', $indexConfig['dynamic_templates']);
|
||||
}
|
||||
|
||||
return $mapping;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,4 +31,45 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertInstanceOf('Symfony\Component\Config\Definition\ScalarNode', $mappings['format']);
|
||||
$this->assertNull($mappings['format']->getDefaultValue());
|
||||
}
|
||||
|
||||
public function testDynamicTemplateNodes()
|
||||
{
|
||||
$tree = $this->configuration->getConfigTree();
|
||||
$children = $tree->getChildren();
|
||||
$children = $children['indexes']->getPrototype()->getChildren();
|
||||
$typeNodes = $children['types']->getPrototype()->getChildren();
|
||||
$dynamicTemplates = $typeNodes['dynamic_templates']->getPrototype()->getChildren();
|
||||
|
||||
$this->assertArrayHasKey('match', $dynamicTemplates);
|
||||
$this->assertInstanceOf('Symfony\Component\Config\Definition\ScalarNode', $dynamicTemplates['match']);
|
||||
$this->assertNull($dynamicTemplates['match']->getDefaultValue());
|
||||
|
||||
$this->assertArrayHasKey('match_mapping_type', $dynamicTemplates);
|
||||
$this->assertInstanceOf('Symfony\Component\Config\Definition\ScalarNode', $dynamicTemplates['match_mapping_type']);
|
||||
$this->assertNull($dynamicTemplates['match_mapping_type']->getDefaultValue());
|
||||
|
||||
$this->assertArrayHasKey('mapping', $dynamicTemplates);
|
||||
$this->assertInstanceOf('Symfony\Component\Config\Definition\ArrayNode', $dynamicTemplates['mapping']);
|
||||
}
|
||||
|
||||
public function testDynamicTemplateMappingNodes()
|
||||
{
|
||||
$tree = $this->configuration->getConfigTree();
|
||||
$children = $tree->getChildren();
|
||||
$children = $children['indexes']->getPrototype()->getChildren();
|
||||
$typeNodes = $children['types']->getPrototype()->getChildren();
|
||||
$dynamicTemplates = $typeNodes['dynamic_templates']->getPrototype()->getChildren();
|
||||
$mapping = $dynamicTemplates['mapping']->getChildren();
|
||||
|
||||
$this->assertArrayHasKey('type', $mapping);
|
||||
$this->assertInstanceOf('Symfony\Component\Config\Definition\ScalarNode', $mapping['type']);
|
||||
$this->assertNull($mapping['type']->getDefaultValue());
|
||||
|
||||
$this->assertArrayHasKey('index', $mapping);
|
||||
$this->assertInstanceOf('Symfony\Component\Config\Definition\ScalarNode', $mapping['index']);
|
||||
$this->assertNull($mapping['index']->getDefaultValue());
|
||||
|
||||
$this->assertArrayHasKey('fields', $mapping);
|
||||
$this->assertInstanceOf('Symfony\Component\Config\Definition\ArrayNode', $mapping['fields']);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
120
Tests/Doctrine/ORM/ElasticaToModelTransformerTest.php
Normal file
120
Tests/Doctrine/ORM/ElasticaToModelTransformerTest.php
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
<?php
|
||||
|
||||
namespace FOS\ElasticaBundle\Tests\Doctrine\ORM;
|
||||
|
||||
use FOS\ElasticaBundle\Doctrine\ORM\ElasticaToModelTransformer;
|
||||
|
||||
class ElasticaToModelTransformerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var \Doctrine\Common\Persistence\ManagerRegistry|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $registry;
|
||||
|
||||
/**
|
||||
* @var \Doctrine\ORM\EntityManager|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $manager;
|
||||
|
||||
/**
|
||||
* @var \Doctrine\Common\Persistence\ObjectRepository|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $repository;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $objectClass = 'stdClass';
|
||||
|
||||
/**
|
||||
* Tests that the Transformer uses the query_builder_method configuration option
|
||||
* allowing configuration of createQueryBuilder call.
|
||||
*/
|
||||
public function testTransformUsesQueryBuilderMethodConfiguration()
|
||||
{
|
||||
$qb = $this->getMockBuilder('Doctrine\ORM\QueryBuilder')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->repository->expects($this->once())
|
||||
->method('customQueryBuilderCreator')
|
||||
->with($this->equalTo(ElasticaToModelTransformer::ENTITY_ALIAS))
|
||||
->will($this->returnValue($qb));
|
||||
$this->repository->expects($this->never())
|
||||
->method('createQueryBuilder');
|
||||
|
||||
$transformer = new ElasticaToModelTransformer($this->registry, $this->objectClass, array(
|
||||
'query_builder_method' => 'customQueryBuilderCreator',
|
||||
));
|
||||
|
||||
$class = new \ReflectionClass('FOS\ElasticaBundle\Doctrine\ORM\ElasticaToModelTransformer');
|
||||
$method = $class->getMethod('getEntityQueryBuilder');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$method->invokeArgs($transformer, array());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the Transformer uses the query_builder_method configuration option
|
||||
* allowing configuration of createQueryBuilder call.
|
||||
*/
|
||||
public function testTransformUsesDefaultQueryBuilderMethodConfiguration()
|
||||
{
|
||||
$qb = $this->getMockBuilder('Doctrine\ORM\QueryBuilder')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->repository->expects($this->never())
|
||||
->method('customQueryBuilderCreator');
|
||||
$this->repository->expects($this->once())
|
||||
->method('createQueryBuilder')
|
||||
->with($this->equalTo(ElasticaToModelTransformer::ENTITY_ALIAS))
|
||||
->will($this->returnValue($qb));
|
||||
|
||||
$transformer = new ElasticaToModelTransformer($this->registry, $this->objectClass);
|
||||
|
||||
$class = new \ReflectionClass('FOS\ElasticaBundle\Doctrine\ORM\ElasticaToModelTransformer');
|
||||
$method = $class->getMethod('getEntityQueryBuilder');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$method->invokeArgs($transformer, array());
|
||||
}
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
if (!interface_exists('Doctrine\Common\Persistence\ManagerRegistry')) {
|
||||
$this->markTestSkipped('Doctrine Common is not present');
|
||||
}
|
||||
if (!class_exists('Doctrine\ORM\EntityManager')) {
|
||||
$this->markTestSkipped('Doctrine Common is not present');
|
||||
}
|
||||
|
||||
$this->registry = $this->getMockBuilder('Doctrine\Common\Persistence\ManagerRegistry')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->manager = $this->getMockBuilder('Doctrine\ORM\EntityManager')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->registry->expects($this->any())
|
||||
->method('getManagerForClass')
|
||||
->with($this->objectClass)
|
||||
->will($this->returnValue($this->manager));
|
||||
|
||||
$this->repository = $this->getMock('Doctrine\Common\Persistence\ObjectRepository', array(
|
||||
'customQueryBuilderCreator',
|
||||
'createQueryBuilder',
|
||||
'find',
|
||||
'findAll',
|
||||
'findBy',
|
||||
'findOneBy',
|
||||
'getClassName'
|
||||
));
|
||||
|
||||
$this->manager->expects($this->any())
|
||||
->method('getRepository')
|
||||
->with($this->objectClass)
|
||||
->will($this->returnValue($this->repository));
|
||||
}
|
||||
}
|
||||
|
|
@ -16,7 +16,10 @@ class ResetterTest extends \PHPUnit_Framework_TestCase
|
|||
'index' => $this->getMockElasticaIndex(),
|
||||
'config' => array(
|
||||
'mappings' => array(
|
||||
'a' => array('properties' => array()),
|
||||
'a' => array(
|
||||
'dynamic_templates' => array(),
|
||||
'properties' => array(),
|
||||
),
|
||||
'b' => array('properties' => array()),
|
||||
),
|
||||
),
|
||||
|
|
@ -100,6 +103,7 @@ class ResetterTest extends \PHPUnit_Framework_TestCase
|
|||
->method('delete');
|
||||
|
||||
$mapping = Mapping::create($this->indexConfigsByName['foo']['config']['mappings']['a']['properties']);
|
||||
$mapping->setParam('dynamic_templates', $this->indexConfigsByName['foo']['config']['mappings']['a']['dynamic_templates']);
|
||||
$type->expects($this->once())
|
||||
->method('setMapping')
|
||||
->with($mapping);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue