diff --git a/.travis.yml b/.travis.yml
index ad1f366..8f6a9d8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,4 +6,4 @@ php:
before_script:
- echo "extension = mongo.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
- - composer install --dev
+ - composer install --dev --prefer-source
diff --git a/Client.php b/Client.php
index 8430b36..ea0c572 100644
--- a/Client.php
+++ b/Client.php
@@ -4,6 +4,7 @@ namespace FOS\ElasticaBundle;
use Elastica\Client as ElasticaClient;
use Elastica\Request;
+use FOS\ElasticaBundle\Logger\ElasticaLogger;
/**
* @author Gordon Franke
@@ -15,9 +16,18 @@ class Client extends ElasticaClient
$start = microtime(true);
$response = parent::request($path, $method, $data, $query);
- if (null !== $this->_logger) {
+ if (null !== $this->_logger and $this->_logger instanceof ElasticaLogger) {
$time = microtime(true) - $start;
- $this->_logger->logQuery($path, $method, $data, $time);
+
+ $connection = $this->getLastRequest()->getConnection();
+
+ $connection_array = array(
+ 'host' => $connection->getHost(),
+ 'port' => $connection->getPort(),
+ 'transport' => $connection->getTransport(),
+ );
+
+ $this->_logger->logQuery($path, $method, $data, $time, $connection_array);
}
return $response;
diff --git a/Command/PopulateCommand.php b/Command/PopulateCommand.php
index 58e5e9f..7297523 100755
--- a/Command/PopulateCommand.php
+++ b/Command/PopulateCommand.php
@@ -4,11 +4,9 @@ namespace FOS\ElasticaBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Helper\DialogHelper;
-use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
-use Symfony\Component\Console\Output\Output;
use FOS\ElasticaBundle\IndexManager;
use FOS\ElasticaBundle\Provider\ProviderRegistry;
use FOS\ElasticaBundle\Resetter;
diff --git a/Command/ResetCommand.php b/Command/ResetCommand.php
index b318827..06cfe48 100755
--- a/Command/ResetCommand.php
+++ b/Command/ResetCommand.php
@@ -3,11 +3,9 @@
namespace FOS\ElasticaBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
-use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
-use Symfony\Component\Console\Output\Output;
use FOS\ElasticaBundle\IndexManager;
use FOS\ElasticaBundle\Resetter;
@@ -62,7 +60,7 @@ class ResetCommand extends ContainerAwareCommand
if (null !== $type) {
$output->writeln(sprintf('Resetting %s/%s', $index, $type));
- $this->resetter->resetIndex($index, $type);
+ $this->resetter->resetIndexType($index, $type);
} else {
$indexes = null === $index
? array_keys($this->indexManager->getAllIndexes())
diff --git a/Command/SearchCommand.php b/Command/SearchCommand.php
index 62e3340..ec7cfb7 100644
--- a/Command/SearchCommand.php
+++ b/Command/SearchCommand.php
@@ -7,7 +7,6 @@ use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
-use Symfony\Component\Console\Output\Output;
use Elastica\Query;
use Elastica\Result;
diff --git a/Configuration/Search.php b/Configuration/Search.php
index ded65a5..cee10ab 100644
--- a/Configuration/Search.php
+++ b/Configuration/Search.php
@@ -11,8 +11,6 @@ namespace FOS\ElasticaBundle\Configuration;
*/
class Search
{
-
/** @var string */
public $repositoryClass;
-
}
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 50d4b89..fbcd486 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -76,8 +76,9 @@ class Configuration implements ConfigurationInterface
return array(
'servers' => array(
array(
- 'host' => $v['host'],
- 'port' => $v['port'],
+ 'host' => $v['host'],
+ 'port' => $v['port'],
+ 'logger' => isset($v['logger']) ? $v['logger'] : null
)
)
);
@@ -89,7 +90,8 @@ class Configuration implements ConfigurationInterface
return array(
'servers' => array(
array(
- 'url' => $v['url'],
+ 'url' => $v['url'],
+ 'logger' => isset($v['logger']) ? $v['logger'] : null
)
)
);
@@ -102,6 +104,11 @@ class Configuration implements ConfigurationInterface
->scalarNode('url')->end()
->scalarNode('host')->end()
->scalarNode('port')->end()
+ ->scalarNode('logger')
+ ->defaultValue('fos_elastica.logger')
+ ->treatNullLike('fos_elastica.logger')
+ ->treatTrueLike('fos_elastica.logger')
+ ->end()
->end()
->end()
->end()
@@ -293,6 +300,7 @@ class Configuration implements ConfigurationInterface
->append($this->getBoostNode())
->append($this->getRoutingNode())
->append($this->getParentNode())
+ ->append($this->getAllNode())
->end()
;
@@ -333,18 +341,13 @@ class Configuration implements ConfigurationInterface
->useAttributeAsKey('name')
->prototype('array')
->children()
- ->scalarNode('match')->isRequired()->end()
+ ->scalarNode('match')->end()
+ ->scalarNode('unmatch')->end()
->scalarNode('match_mapping_type')->end()
- ->arrayNode('mapping')
- ->isRequired()
- ->children()
- ->scalarNode('type')->end()
- ->scalarNode('index')->end()
- ->arrayNode('fields')
- ->children()
- ->end()
- ->end()
- ->end()
+ ->scalarNode('path_match')->end()
+ ->scalarNode('path_unmatch')->end()
+ ->scalarNode('match_pattern')->end()
+ ->append($this->getDynamicTemplateMapping())
->end()
->end()
;
@@ -352,6 +355,21 @@ class Configuration implements ConfigurationInterface
return $node;
}
+ /**
+ * @return the array node used for mapping in dynamic templates
+ */
+ protected function getDynamicTemplateMapping()
+ {
+ $builder = new TreeBuilder();
+ $node = $builder->root('mapping');
+
+ $nestings = $this->getNestingsForDynamicTemplates();
+
+ $this->addFieldConfig($node->children(), $nestings);
+
+ 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
@@ -369,6 +387,7 @@ class Configuration implements ConfigurationInterface
->scalarNode('term_vector')->end()
->scalarNode('null_value')->end()
->booleanNode('include_in_all')->defaultValue(true)->end()
+ ->booleanNode('enabled')->defaultValue(true)->end()
->scalarNode('lat_lon')->end()
->scalarNode('index_name')->end()
->booleanNode('omit_norms')->end()
@@ -434,12 +453,51 @@ class Configuration implements ConfigurationInterface
}
foreach ($index['types'] as $type) {
+ if (empty($type['mappings'])) {
+ continue;
+ }
+
$nestings = array_merge_recursive($nestings, $this->getNestingsForType($type['mappings'], $nestings));
}
}
return $nestings;
}
+ /**
+ * @return array The unique nested mappings for all dynamic templates
+ */
+ protected function getNestingsForDynamicTemplates()
+ {
+ if (!isset($this->configArray[0]['indexes'])) {
+ return array();
+ }
+
+ $nestings = array();
+ foreach ($this->configArray[0]['indexes'] as $index) {
+ if (empty($index['types'])) {
+ continue;
+ }
+
+ foreach ($index['types'] as $type) {
+ if (empty($type['dynamic_templates'])) {
+ continue;
+ }
+
+ foreach ($type['dynamic_templates'] as $definition) {
+ $field = $definition['mapping'];
+
+ if (isset($field['fields'])) {
+ $this->addPropertyNesting($field, $nestings, 'fields');
+ } else if (isset($field['properties'])) {
+ $this->addPropertyNesting($field, $nestings, 'properties');
+ }
+ }
+
+ }
+ }
+ return $nestings;
+ }
+
/**
* @param array $mappings The mappings for the current type
* @return array The nested mappings defined for this type
@@ -574,4 +632,21 @@ class Configuration implements ConfigurationInterface
return $node;
}
+
+ /**
+ * Returns the array node used for "_all"
+ */
+ protected function getAllNode()
+ {
+ $builder = new TreeBuilder();
+ $node = $builder->root('_all');
+
+ $node
+ ->children()
+ ->scalarNode('enabled')->defaultValue(true)->end()
+ ->end()
+ ;
+
+ return $node;
+ }
}
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 733a039..53c91f1 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -16,6 +16,7 @@ class FOSElasticaExtension extends Extension
protected $indexConfigs = array();
protected $typeFields = array();
protected $loadedDrivers = array();
+ protected $serializerConfig = array();
public function load(array $configs, ContainerBuilder $container)
{
@@ -40,8 +41,8 @@ class FOSElasticaExtension extends Extension
}
$clientIdsByName = $this->loadClients($config['clients'], $container);
- $serializerConfig = isset($config['serializer']) ? $config['serializer'] : null;
- $indexIdsByName = $this->loadIndexes($config['indexes'], $container, $clientIdsByName, $config['default_client'], $serializerConfig);
+ $this->serializerConfig = isset($config['serializer']) ? $config['serializer'] : null;
+ $indexIdsByName = $this->loadIndexes($config['indexes'], $container, $clientIdsByName, $config['default_client']);
$indexRefsByName = array_map(function($id) {
return new Reference($id);
}, $indexIdsByName);
@@ -73,7 +74,10 @@ class FOSElasticaExtension extends Extension
foreach ($clients as $name => $clientConfig) {
$clientId = sprintf('fos_elastica.client.%s', $name);
$clientDef = new Definition('%fos_elastica.client.class%', array($clientConfig));
- $clientDef->addMethodCall('setLogger', array(new Reference('fos_elastica.logger')));
+ $logger = $clientConfig['servers'][0]['logger'];
+ if (false !== $logger) {
+ $clientDef->addMethodCall('setLogger', array(new Reference($logger)));
+ }
$clientDef->addTag('fos_elastica.client');
$container->setDefinition($clientId, $clientDef);
@@ -91,10 +95,11 @@ class FOSElasticaExtension extends Extension
* @param ContainerBuilder $container A ContainerBuilder instance
* @param array $clientIdsByName
* @param $defaultClientName
+ * @param $serializerConfig
* @throws \InvalidArgumentException
* @return array
*/
- protected function loadIndexes(array $indexes, ContainerBuilder $container, array $clientIdsByName, $defaultClientName, $serializerConfig)
+ protected function loadIndexes(array $indexes, ContainerBuilder $container, array $clientIdsByName, $defaultClientName)
{
$indexIds = array();
foreach ($indexes as $name => $index) {
@@ -129,7 +134,7 @@ class FOSElasticaExtension extends Extension
if (!empty($index['settings'])) {
$this->indexConfigs[$name]['config']['settings'] = $index['settings'];
}
- $this->loadTypes(isset($index['types']) ? $index['types'] : array(), $container, $name, $indexId, $typePrototypeConfig, $serializerConfig);
+ $this->loadTypes(isset($index['types']) ? $index['types'] : array(), $container, $name, $indexId, $typePrototypeConfig);
}
return $indexIds;
@@ -170,8 +175,9 @@ class FOSElasticaExtension extends Extension
* @param $indexName
* @param $indexId
* @param array $typePrototypeConfig
+ * @param $serializerConfig
*/
- protected function loadTypes(array $types, ContainerBuilder $container, $indexName, $indexId, array $typePrototypeConfig, $serializerConfig)
+ protected function loadTypes(array $types, ContainerBuilder $container, $indexName, $indexId, array $typePrototypeConfig)
{
foreach ($types as $name => $type) {
$type = self::deepArrayUnion($typePrototypeConfig, $type);
@@ -180,12 +186,12 @@ class FOSElasticaExtension extends Extension
$typeDef = new Definition('%fos_elastica.type.class%', $typeDefArgs);
$typeDef->setFactoryService($indexId);
$typeDef->setFactoryMethod('getType');
- if ($serializerConfig) {
- $callbackDef = new Definition($serializerConfig['callback_class']);
+ if ($this->serializerConfig) {
+ $callbackDef = new Definition($this->serializerConfig['callback_class']);
$callbackId = sprintf('%s.%s.serializer.callback', $indexId, $name);
$typeDef->addMethodCall('setSerializer', array(array(new Reference($callbackId), 'serialize')));
- $callbackDef->addMethodCall('setSerializer', array(new Reference($serializerConfig['serializer'])));
+ $callbackDef->addMethodCall('setSerializer', array(new Reference($this->serializerConfig['serializer'])));
if (isset($type['serializer']['groups'])) {
$callbackDef->addMethodCall('setGroups', array($type['serializer']['groups']));
}
@@ -198,6 +204,11 @@ class FOSElasticaExtension extends Extension
$typeDef->addMethodCall('setSerializer', array(array(new Reference($callbackId), 'serialize')));
}
$container->setDefinition($typeId, $typeDef);
+
+ $this->indexConfigs[$indexName]['config']['mappings'][$name] = array(
+ "_source" => array("enabled" => true), // Add a default setting for empty mapping settings
+ );
+
if (isset($type['_id'])) {
$this->indexConfigs[$indexName]['config']['mappings'][$name]['_id'] = $type['_id'];
}
@@ -210,7 +221,7 @@ class FOSElasticaExtension extends Extension
if (isset($type['_routing'])) {
$this->indexConfigs[$indexName]['config']['mappings'][$name]['_routing'] = $type['_routing'];
}
- if (isset($type['mappings'])) {
+ if (isset($type['mappings']) && !empty($type['mappings'])) {
$this->indexConfigs[$indexName]['config']['mappings'][$name]['properties'] = $type['mappings'];
$typeName = sprintf('%s/%s', $indexName, $name);
$this->typeFields[$typeName] = $type['mappings'];
@@ -232,6 +243,9 @@ class FOSElasticaExtension extends Extension
if (isset($type['index'])) {
$this->indexConfigs[$indexName]['config']['mappings'][$name]['index'] = $type['index'];
}
+ if (isset($type['_all'])) {
+ $this->indexConfigs[$indexName]['config']['mappings'][$name]['_all'] = $type['_all'];
+ }
if (!empty($type['dynamic_templates'])) {
$this->indexConfigs[$indexName]['config']['mappings'][$name]['dynamic_templates'] = array();
foreach ($type['dynamic_templates'] as $templateName => $templateData) {
@@ -324,8 +338,14 @@ class FOSElasticaExtension extends Extension
return $typeConfig['model_to_elastica_transformer']['service'];
}
+ if ($this->serializerConfig) {
+ $abstractId = sprintf('fos_elastica.model_to_elastica_identifier_transformer');
+ } else {
+ $abstractId = sprintf('fos_elastica.model_to_elastica_transformer');
+ }
+
$serviceId = sprintf('fos_elastica.model_to_elastica_transformer.%s.%s', $indexName, $typeName);
- $serviceDef = new DefinitionDecorator('fos_elastica.model_to_elastica_transformer');
+ $serviceDef = new DefinitionDecorator($abstractId);
$serviceDef->replaceArgument(0, array(
'identifier' => $typeConfig['identifier']
));
@@ -336,12 +356,26 @@ class FOSElasticaExtension extends Extension
protected function loadObjectPersister(array $typeConfig, Definition $typeDef, ContainerBuilder $container, $indexName, $typeName, $transformerId)
{
+ $arguments = array(
+ $typeDef,
+ new Reference($transformerId),
+ $typeConfig['model'],
+ );
+
+ if ($this->serializerConfig) {
+ $abstractId = 'fos_elastica.object_serializer_persister';
+ $callbackId = sprintf('%s.%s.serializer.callback', $this->indexConfigs[$indexName]['index'], $typeName);
+ $arguments[] = array(new Reference($callbackId), 'serialize');
+ } else {
+ $abstractId = 'fos_elastica.object_persister';
+ $arguments[] = $this->typeFields[sprintf('%s/%s', $indexName, $typeName)];
+ }
$serviceId = sprintf('fos_elastica.object_persister.%s.%s', $indexName, $typeName);
- $serviceDef = new DefinitionDecorator('fos_elastica.object_persister');
- $serviceDef->replaceArgument(0, $typeDef);
- $serviceDef->replaceArgument(1, new Reference($transformerId));
- $serviceDef->replaceArgument(2, $typeConfig['model']);
- $serviceDef->replaceArgument(3, $this->typeFields[sprintf('%s/%s', $indexName, $typeName)]);
+ $serviceDef = new DefinitionDecorator($abstractId);
+ foreach ($arguments as $i => $argument) {
+ $serviceDef->replaceArgument($i, $argument);
+ }
+
$container->setDefinition($serviceId, $serviceDef);
return $serviceId;
diff --git a/Doctrine/RepositoryManager.php b/Doctrine/RepositoryManager.php
index 6ba6bf5..f8867eb 100644
--- a/Doctrine/RepositoryManager.php
+++ b/Doctrine/RepositoryManager.php
@@ -40,5 +40,4 @@ class RepositoryManager extends BaseManager
return parent::getRepository($realEntityName);
}
-
}
diff --git a/Finder/TransformedFinder.php b/Finder/TransformedFinder.php
index 24f680f..4c8aa98 100644
--- a/Finder/TransformedFinder.php
+++ b/Finder/TransformedFinder.php
@@ -97,6 +97,7 @@ class TransformedFinder implements PaginatedFinderInterface
public function createPaginatorAdapter($query)
{
$query = Query::create($query);
+
return new TransformedPaginatorAdapter($this->searchable, $query, $this->transformer);
}
}
diff --git a/Logger/ElasticaLogger.php b/Logger/ElasticaLogger.php
index 1705d06..7aacac5 100644
--- a/Logger/ElasticaLogger.php
+++ b/Logger/ElasticaLogger.php
@@ -38,15 +38,17 @@ class ElasticaLogger implements LoggerInterface
* @param string $method Rest method to use (GET, POST, DELETE, PUT)
* @param array $data arguments
* @param float $time execution time
+ * @param array $connection host, port and transport of the query
*/
- public function logQuery($path, $method, $data, $time)
+ public function logQuery($path, $method, $data, $time, $connection = array())
{
if ($this->debug) {
$this->queries[] = array(
'path' => $path,
'method' => $method,
'data' => $data,
- 'executionMS' => $time
+ 'executionMS' => $time,
+ 'connection' => $connection
);
}
@@ -145,6 +147,6 @@ class ElasticaLogger implements LoggerInterface
*/
public function log($level, $message, array $context = array())
{
- return $this->logger->log($message, $context);
+ return $this->logger->log($level, $message, $context);
}
}
diff --git a/Manager/RepositoryManager.php b/Manager/RepositoryManager.php
index 6459c19..3cf8e96 100644
--- a/Manager/RepositoryManager.php
+++ b/Manager/RepositoryManager.php
@@ -5,6 +5,7 @@ namespace FOS\ElasticaBundle\Manager;
use Doctrine\Common\Annotations\Reader;
use FOS\ElasticaBundle\Finder\FinderInterface;
use RuntimeException;
+
/**
* @author Richard Miller
*
@@ -70,11 +71,10 @@ class RepositoryManager implements RepositoryManagerInterface
private function createRepository($entityName)
{
- $repositoryName = $this->getRepositoryName($entityName);
- if (!class_exists($repositoryName)) {
+ if (!class_exists($repositoryName = $this->getRepositoryName($entityName))) {
throw new RuntimeException(sprintf('%s repository for %s does not exist', $repositoryName, $entityName));
}
+
return new $repositoryName($this->entities[$entityName]['finder']);
}
-
}
diff --git a/Manager/RepositoryManagerInterface.php b/Manager/RepositoryManagerInterface.php
index c831d35..1008371 100644
--- a/Manager/RepositoryManagerInterface.php
+++ b/Manager/RepositoryManagerInterface.php
@@ -32,5 +32,4 @@ interface RepositoryManagerInterface
* @param string $entityName
*/
public function getRepository($entityName);
-
}
diff --git a/Paginator/FantaPaginatorAdapter.php b/Paginator/FantaPaginatorAdapter.php
index a2f8c0e..2ad6983 100644
--- a/Paginator/FantaPaginatorAdapter.php
+++ b/Paginator/FantaPaginatorAdapter.php
@@ -3,14 +3,13 @@
namespace FOS\ElasticaBundle\Paginator;
use Pagerfanta\Adapter\AdapterInterface;
-use FOS\ElasticaBundle\Paginator\PaginatorAdapterInterface;
class FantaPaginatorAdapter implements AdapterInterface
{
private $adapter;
/**
- * @param PaginatorAdapterInterface $adapter
+ * @param \FOS\ElasticaBundle\Paginator\PaginatorAdapterInterface $adapter
*/
public function __construct(PaginatorAdapterInterface $adapter)
{
@@ -42,7 +41,7 @@ class FantaPaginatorAdapter implements AdapterInterface
}
/**
- * Returns an slice of the results.
+ * Returns a slice of the results.
*
* @param integer $offset The offset.
* @param integer $length The length.
diff --git a/Paginator/PaginatorAdapterInterface.php b/Paginator/PaginatorAdapterInterface.php
index 9182973..25786a0 100644
--- a/Paginator/PaginatorAdapterInterface.php
+++ b/Paginator/PaginatorAdapterInterface.php
@@ -2,8 +2,6 @@
namespace FOS\ElasticaBundle\Paginator;
-use FOS\ElasticaBundle\Paginator\PartialResultsInterface;
-
interface PaginatorAdapterInterface
{
/**
diff --git a/Paginator/RawPaginatorAdapter.php b/Paginator/RawPaginatorAdapter.php
index 125cd35..d4b5357 100644
--- a/Paginator/RawPaginatorAdapter.php
+++ b/Paginator/RawPaginatorAdapter.php
@@ -5,9 +5,6 @@ namespace FOS\ElasticaBundle\Paginator;
use Elastica\SearchableInterface;
use Elastica\Query;
use Elastica\ResultSet;
-use FOS\ElasticaBundle\Paginator\PaginatorAdapterInterface;
-use FOS\ElasticaBundle\Paginator\RawPartialResults;
-use FOS\ElasticaBundle\Paginator\PartialResultsInterface;
use InvalidArgumentException;
/**
@@ -52,6 +49,7 @@ class RawPaginatorAdapter implements PaginatorAdapterInterface
*
* @param $offset
* @param $itemCountPerPage
+ * @throws \InvalidArgumentException
* @return ResultSet
*/
protected function getElasticaResults($offset, $itemCountPerPage)
diff --git a/Paginator/RawPartialResults.php b/Paginator/RawPartialResults.php
index 270e4cd..a4afb00 100644
--- a/Paginator/RawPartialResults.php
+++ b/Paginator/RawPartialResults.php
@@ -2,7 +2,6 @@
namespace FOS\ElasticaBundle\Paginator;
-use FOS\ElasticaBundle\Paginator\PartialResultsInterface;
use Elastica\ResultSet;
use Elastica\Result;
diff --git a/Paginator/TransformedPaginatorAdapter.php b/Paginator/TransformedPaginatorAdapter.php
index a668636..7bc038a 100644
--- a/Paginator/TransformedPaginatorAdapter.php
+++ b/Paginator/TransformedPaginatorAdapter.php
@@ -3,7 +3,6 @@
namespace FOS\ElasticaBundle\Paginator;
use FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerInterface;
-use FOS\ElasticaBundle\Paginator\TransformedPartialResults;
use Elastica\SearchableInterface;
use Elastica\Query;
diff --git a/Paginator/TransformedPartialResults.php b/Paginator/TransformedPartialResults.php
index f7f125a..13d716c 100644
--- a/Paginator/TransformedPartialResults.php
+++ b/Paginator/TransformedPartialResults.php
@@ -3,7 +3,6 @@
namespace FOS\ElasticaBundle\Paginator;
use FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerInterface;
-use FOS\ElasticaBundle\Paginator\RawPartialResults;
use Elastica\ResultSet;
/**
diff --git a/Persister/ObjectSerializerPersister.php b/Persister/ObjectSerializerPersister.php
new file mode 100644
index 0000000..1a15656
--- /dev/null
+++ b/Persister/ObjectSerializerPersister.php
@@ -0,0 +1,42 @@
+
+ */
+class ObjectSerializerPersister extends ObjectPersister
+{
+ protected $serializer;
+
+ public function __construct(Type $type, ModelToElasticaTransformerInterface $transformer, $objectClass, $serializer)
+ {
+ parent::__construct($type, $transformer, $objectClass, array());
+ $this->serializer = $serializer;
+ }
+
+ /**
+ * Transforms an object to an elastica document
+ * with just the identifier set
+ *
+ * @param object $object
+ * @return Document the elastica document
+ */
+ public function transformToElasticaDocument($object)
+ {
+ $document = $this->transformer->transform($object, array());
+
+ $data = call_user_func($this->serializer, $object);
+ $document->setData($data);
+
+ return $document;
+ }
+}
diff --git a/Provider/AbstractProvider.php b/Provider/AbstractProvider.php
index daa57ae..06883a3 100644
--- a/Provider/AbstractProvider.php
+++ b/Provider/AbstractProvider.php
@@ -3,7 +3,6 @@
namespace FOS\ElasticaBundle\Provider;
use FOS\ElasticaBundle\Persister\ObjectPersisterInterface;
-use FOS\ElasticaBundle\Provider\ProviderInterface;
abstract class AbstractProvider implements ProviderInterface
{
diff --git a/Provider/ProviderRegistry.php b/Provider/ProviderRegistry.php
index ed5b499..2142223 100644
--- a/Provider/ProviderRegistry.php
+++ b/Provider/ProviderRegistry.php
@@ -2,8 +2,6 @@
namespace FOS\ElasticaBundle\Provider;
-use Symfony\Component\DependencyInjection\ContainerBuilder;
-
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
diff --git a/README.md b/README.md
index 9f77a1b..b3a4c5d 100644
--- a/README.md
+++ b/README.md
@@ -182,17 +182,19 @@ per type.
content: ~
_parent: { type: "post", property: "post", identifier: "id" }
-The parent filed declaration has the following values:
+The parent field declaration has the following values:
* `type`: The parent type.
* `property`: The property in the child entity where to look for the parent entity. It may be ignored if is equal to the parent type.
- * `identifier`: The property in the parent entity which have the parent identifier. Defaults to `id`.
+ * `identifier`: The property in the parent entity which has the parent identifier. Defaults to `id`.
Note that to create a document with a parent, you need to call `setParent` on the document rather than setting a _parent field.
If you do this wrong, you will see a `RoutingMissingException` as elasticsearch does not know where to store a document that should have a parent but does not specify it.
### Declaring `nested` or `object`
+Note that object can autodetect properties
+
fos_elastica:
clients:
default: { host: localhost, port: 9200 }
@@ -213,6 +215,12 @@ If you do this wrong, you will see a `RoutingMissingException` as elasticsearch
properties:
date: { boost: 5 }
content: ~
+ user:
+ type: "object"
+ approver:
+ type: "object"
+ properties:
+ date: { boost: 5 }
#### Doctrine ORM and `object` mappings
@@ -230,7 +238,7 @@ It applies the configured mappings to the types.
This command needs providers to insert new documents in the elasticsearch types.
There are 2 ways to create providers.
If your elasticsearch type matches a Doctrine repository or a Propel query, go for the persistence automatic provider.
-Or, for complete flexibility, go for manual provider.
+Or, for complete flexibility, go for a manual provider.
#### Persistence automatic provider
@@ -495,7 +503,7 @@ If you use multiple drivers then you can choose which one is aliased to `fos_ela
using the `default_manager` parameter:
fos_elastica:
- default_manager: mongodb #defauults to orm
+ default_manager: mongodb #defaults to orm
clients:
default: { host: localhost, port: 9200 }
#--
diff --git a/Resources/config/config.xml b/Resources/config/config.xml
index ad6b13b..1fb2c1d 100644
--- a/Resources/config/config.xml
+++ b/Resources/config/config.xml
@@ -49,6 +49,13 @@
+
+
+
+
+
+
+
@@ -56,6 +63,13 @@
+
+
+
+
+
+
+
diff --git a/Resources/views/Collector/elastica.html.twig b/Resources/views/Collector/elastica.html.twig
index a665e2d..0eb50a6 100644
--- a/Resources/views/Collector/elastica.html.twig
+++ b/Resources/views/Collector/elastica.html.twig
@@ -19,13 +19,13 @@
{% endblock %}
{% block menu %}
-
-
- Elastica
-
- {{ collector.querycount }}
+
+
+ Elastica
+
+ {{ collector.querycount }}
+
-
{% endblock %}
{% block panel %}
@@ -41,18 +41,52 @@
{% else %}
- {% for query in collector.queries %}
+ {% for key, query in collector.queries %}
-
Path: {{ query.path }}
- Method: {{ query.method }}
+ Method: {{ query.method }} ({{ query.connection.transport }} on {{ query.connection.host }}:{{ query.connection.port }})
{{ query.data|json_encode }}
Time: {{ '%0.2f'|format(query.executionMS * 1000) }} ms
+
+ {% if query.connection.transport in ['Http', 'Https'] %}{# cURL support only HTTP #}
+
+
+
+ Display cURL query
+
+
+
+ curl -X{{ query.method }} '{{ query.connection.transport|lower }}://{{ query.connection.host }}:{{ query.connection.port }}/{{ query.path }}' -d '{{ query.data|json_encode }}'
+
+ {% endif %}
{% endfor %}
+
+
{% endif %}
{% endblock %}
diff --git a/Serializer/Callback.php b/Serializer/Callback.php
index 50307e0..9fe7064 100644
--- a/Serializer/Callback.php
+++ b/Serializer/Callback.php
@@ -8,9 +8,7 @@ use JMS\Serializer\SerializerInterface;
class Callback
{
protected $serializer;
-
protected $groups;
-
protected $version;
public function setSerializer($serializer)
diff --git a/Tests/ClientTest.php b/Tests/ClientTest.php
new file mode 100644
index 0000000..c8509cf
--- /dev/null
+++ b/Tests/ClientTest.php
@@ -0,0 +1,42 @@
+getMock('Elastica\Connection');
+ $connection->expects($this->any())->method('getTransportObject')->will($this->returnValue($transport));
+ $connection->expects($this->any())->method('toArray')->will($this->returnValue(array()));
+
+ $logger = $this->getMock('FOS\ElasticaBundle\Logger\ElasticaLogger');
+ $logger
+ ->expects($this->once())
+ ->method('logQuery')
+ ->with(
+ 'foo',
+ Request::GET,
+ $this->isType('array'),
+ $this->isType('float'),
+ $this->isType('array')
+ );
+
+ $client = $this->getMockBuilder('FOS\ElasticaBundle\Client')
+ ->setMethods(array('getConnection'))
+ ->getMock();
+
+ $client->expects($this->any())->method('getConnection')->will($this->returnValue($connection));
+
+ $client->setLogger($logger);
+
+ $response = $client->request('foo');
+
+ $this->assertInstanceOf('Elastica\Response', $response);
+ }
+}
diff --git a/Tests/Command/ResetCommandTest.php b/Tests/Command/ResetCommandTest.php
new file mode 100644
index 0000000..b6548aa
--- /dev/null
+++ b/Tests/Command/ResetCommandTest.php
@@ -0,0 +1,91 @@
+resetter = $this->getMockBuilder('\FOS\ElasticaBundle\Resetter')
+ ->disableOriginalConstructor()
+ ->setMethods(array('resetIndex', 'resetIndexType'))
+ ->getMock();
+
+ $container->set('fos_elastica.resetter', $this->resetter);
+
+ $this->indexManager = $this->getMockBuilder('\FOS\ElasticaBundle\IndexManager')
+ ->disableOriginalConstructor()
+ ->setMethods(array('getAllIndexes'))
+ ->getMock();
+
+ $container->set('fos_elastica.index_manager', $this->indexManager);
+
+ $this->command = new ResetCommand();
+ $this->command->setContainer($container);
+ }
+
+ public function testResetAllIndexes()
+ {
+ $this->indexManager->expects($this->any())
+ ->method('getAllIndexes')
+ ->will($this->returnValue(array('index1' => true, 'index2' => true)));
+
+ $this->resetter->expects($this->at(0))
+ ->method('resetIndex')
+ ->with($this->equalTo('index1'));
+
+ $this->resetter->expects($this->at(1))
+ ->method('resetIndex')
+ ->with($this->equalTo('index2'));
+
+ $this->command->run(
+ new ArrayInput(array()),
+ new NullOutput()
+ );
+ }
+
+ public function testResetIndex()
+ {
+ $this->indexManager->expects($this->never())
+ ->method('getAllIndexes');
+
+ $this->resetter->expects($this->at(0))
+ ->method('resetIndex')
+ ->with($this->equalTo('index1'));
+
+ $this->command->run(
+ new ArrayInput(array('--index' => 'index1')),
+ new NullOutput()
+ );
+ }
+
+ public function testResetIndexType()
+ {
+ $this->indexManager->expects($this->never())
+ ->method('getAllIndexes');
+
+ $this->resetter->expects($this->never())
+ ->method('resetIndex');
+
+ $this->resetter->expects($this->at(0))
+ ->method('resetIndexType')
+ ->with($this->equalTo('index1'), $this->equalTo('type1'));
+
+ $this->command->run(
+ new ArrayInput(array('--index' => 'index1', '--type' => 'type1')),
+ new NullOutput()
+ );
+ }
+}
\ No newline at end of file
diff --git a/Tests/DataCollector/ElasticaDataCollectorTest.php b/Tests/DataCollector/ElasticaDataCollectorTest.php
index 758e1c2..aac1fb4 100644
--- a/Tests/DataCollector/ElasticaDataCollectorTest.php
+++ b/Tests/DataCollector/ElasticaDataCollectorTest.php
@@ -9,7 +9,6 @@ use FOS\ElasticaBundle\DataCollector\ElasticaDataCollector;
*/
class ElasticaDataCollectorTest extends \PHPUnit_Framework_TestCase
{
-
public function testCorrectAmountOfQueries()
{
/** @var $requestMock \PHPUnit_Framework_MockObject_MockObject|\Symfony\Component\HttpFoundation\Request */
@@ -93,5 +92,4 @@ class ElasticaDataCollectorTest extends \PHPUnit_Framework_TestCase
$elasticaDataCollector->collect($requestMock, $responseMock);
$this->assertEquals(30, $elasticaDataCollector->getTime());
}
-
}
diff --git a/Tests/DependencyInjection/ConfigurationTest.php b/Tests/DependencyInjection/ConfigurationTest.php
index ead9977..35b2af3 100644
--- a/Tests/DependencyInjection/ConfigurationTest.php
+++ b/Tests/DependencyInjection/ConfigurationTest.php
@@ -48,6 +48,22 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
$this->assertInstanceOf('Symfony\Component\Config\Definition\ScalarNode', $dynamicTemplates['match_mapping_type']);
$this->assertNull($dynamicTemplates['match_mapping_type']->getDefaultValue());
+ $this->assertArrayHasKey('unmatch', $dynamicTemplates);
+ $this->assertInstanceOf('Symfony\Component\Config\Definition\ScalarNode', $dynamicTemplates['unmatch']);
+ $this->assertNull($dynamicTemplates['unmatch']->getDefaultValue());
+
+ $this->assertArrayHasKey('path_match', $dynamicTemplates);
+ $this->assertInstanceOf('Symfony\Component\Config\Definition\ScalarNode', $dynamicTemplates['path_match']);
+ $this->assertNull($dynamicTemplates['path_match']->getDefaultValue());
+
+ $this->assertArrayHasKey('path_unmatch', $dynamicTemplates);
+ $this->assertInstanceOf('Symfony\Component\Config\Definition\ScalarNode', $dynamicTemplates['path_unmatch']);
+ $this->assertNull($dynamicTemplates['path_unmatch']->getDefaultValue());
+
+ $this->assertArrayHasKey('match_pattern', $dynamicTemplates);
+ $this->assertInstanceOf('Symfony\Component\Config\Definition\ScalarNode', $dynamicTemplates['match_pattern']);
+ $this->assertNull($dynamicTemplates['match_pattern']->getDefaultValue());
+
$this->assertArrayHasKey('mapping', $dynamicTemplates);
$this->assertInstanceOf('Symfony\Component\Config\Definition\ArrayNode', $dynamicTemplates['mapping']);
}
@@ -63,13 +79,10 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
$this->assertArrayHasKey('type', $mapping);
$this->assertInstanceOf('Symfony\Component\Config\Definition\ScalarNode', $mapping['type']);
- $this->assertNull($mapping['type']->getDefaultValue());
+ $this->assertSame('string', $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']);
}
}
diff --git a/Tests/Doctrine/RepositoryManagerTest.php b/Tests/Doctrine/RepositoryManagerTest.php
index 2863127..ce7b14b 100644
--- a/Tests/Doctrine/RepositoryManagerTest.php
+++ b/Tests/Doctrine/RepositoryManagerTest.php
@@ -156,5 +156,4 @@ class RepositoryManagerTest extends \PHPUnit_Framework_TestCase
$repository = $manager->getRepository($shortEntityName);
$this->assertInstanceOf('FOS\ElasticaBundle\Repository', $repository);
}
-
}
diff --git a/Tests/FOSElasticaBundleTest.php b/Tests/FOSElasticaBundleTest.php
new file mode 100644
index 0000000..2bfc7f9
--- /dev/null
+++ b/Tests/FOSElasticaBundleTest.php
@@ -0,0 +1,39 @@
+getMock('Symfony\Component\DependencyInjection\ContainerBuilder');
+
+ $container
+ ->expects($this->at(0))
+ ->method('addCompilerPass')
+ ->with($this->isInstanceOf($passes[0][0]), $passes[0][1]);
+
+ $container
+ ->expects($this->at(1))
+ ->method('addCompilerPass')
+ ->with($this->isInstanceOf($passes[1][0]));
+
+ $bundle = new FOSElasticaBundle();
+
+ $bundle->build($container);
+ }
+}
diff --git a/Tests/HybridResultTest.php b/Tests/HybridResultTest.php
new file mode 100644
index 0000000..cb382d1
--- /dev/null
+++ b/Tests/HybridResultTest.php
@@ -0,0 +1,19 @@
+assertSame($result, $hybridResult->getResult());
+ $this->assertNull($hybridResult->getTransformed());
+ }
+}
diff --git a/Tests/Logger/ElasticaLoggerTest.php b/Tests/Logger/ElasticaLoggerTest.php
index 3cf6d2d..30ce30c 100644
--- a/Tests/Logger/ElasticaLoggerTest.php
+++ b/Tests/Logger/ElasticaLoggerTest.php
@@ -9,6 +9,39 @@ use FOS\ElasticaBundle\Logger\ElasticaLogger;
*/
class ElasticaLoggerTest extends \PHPUnit_Framework_TestCase
{
+ /**
+ * @return \PHPUnit_Framework_MockObject_MockObject|\Symfony\Component\HttpKernel\Log\LoggerInterface
+ */
+ private function getMockLogger()
+ {
+ return $this->getMockBuilder('Symfony\Component\HttpKernel\Log\LoggerInterface')
+ ->disableOriginalConstructor()
+ ->getMock();
+ }
+
+ /**
+ * @param string $level
+ * @param string $message
+ * @param array $context
+ * @return ElasticaLogger
+ */
+ private function getMockLoggerForLevelMessageAndContext($level, $message, $context)
+ {
+ $loggerMock = $this->getMockBuilder('Symfony\Component\HttpKernel\Log\LoggerInterface')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $loggerMock->expects($this->once())
+ ->method($level)
+ ->with(
+ $this->equalTo($message),
+ $this->equalTo($context)
+ );
+
+ $elasticaLogger = new ElasticaLogger($loggerMock);
+
+ return $elasticaLogger;
+ }
public function testGetZeroIfNoQueriesAdded()
{
@@ -36,15 +69,17 @@ class ElasticaLoggerTest extends \PHPUnit_Framework_TestCase
$method = 'testMethod';
$data = array('data');
$time = 12;
+ $connection = array('host' => 'localhost', 'port' => '8999', 'transport' => 'https');
$expected = array(
'path' => $path,
'method' => $method,
'data' => $data,
- 'executionMS' => $time
+ 'executionMS' => $time,
+ 'connection' => $connection,
);
- $elasticaLogger->logQuery($path, $method, $data, $time);
+ $elasticaLogger->logQuery($path, $method, $data, $time, $connection);
$returnedQueries = $elasticaLogger->getQueries();
$this->assertEquals($expected, $returnedQueries[0]);
}
@@ -63,10 +98,7 @@ class ElasticaLoggerTest extends \PHPUnit_Framework_TestCase
public function testQueryIsLogged()
{
- /** @var $loggerMock \PHPUnit_Framework_MockObject_MockObject|\Symfony\Component\HttpKernel\Log\LoggerInterface */
- $loggerMock = $this->getMockBuilder('Symfony\Component\HttpKernel\Log\LoggerInterface')
- ->disableOriginalConstructor()
- ->getMock();
+ $loggerMock = $this->getMockLogger();
$elasticaLogger = new ElasticaLogger($loggerMock);
@@ -87,4 +119,54 @@ class ElasticaLoggerTest extends \PHPUnit_Framework_TestCase
$elasticaLogger->logQuery($path, $method, $data, $time);
}
+ /**
+ * @return array
+ */
+ public function logLevels()
+ {
+ return array(
+ array('emergency'),
+ array('alert'),
+ array('critical'),
+ array('error'),
+ array('warning'),
+ array('notice'),
+ array('info'),
+ array('debug'),
+ );
+ }
+
+ /**
+ * @dataProvider logLevels
+ */
+ public function testMessagesCanBeLoggedAtSpecificLogLevels($level)
+ {
+ $message = 'foo';
+ $context = array('data');
+
+ $loggerMock = $this->getMockLoggerForLevelMessageAndContext($level, $message, $context);
+
+ call_user_func(array($loggerMock, $level), $message, $context);
+ }
+
+ public function testMessagesCanBeLoggedToArbitraryLevels()
+ {
+ $loggerMock = $this->getMockLogger();
+
+ $level = 'info';
+ $message = 'foo';
+ $context = array('data');
+
+ $loggerMock->expects($this->once())
+ ->method('log')
+ ->with(
+ $level,
+ $message,
+ $context
+ );
+
+ $elasticaLogger = new ElasticaLogger($loggerMock);
+
+ $elasticaLogger->log($level, $message, $context);
+ }
}
diff --git a/Tests/Manager/RepositoryManagerTest.php b/Tests/Manager/RepositoryManagerTest.php
index 8cdf1b4..8849035 100644
--- a/Tests/Manager/RepositoryManagerTest.php
+++ b/Tests/Manager/RepositoryManagerTest.php
@@ -97,5 +97,4 @@ class RepositoryManagerTest extends \PHPUnit_Framework_TestCase
$manager->addEntity($entityName, $finderMock, 'FOS\ElasticaBundle\Tests\MissingRepository');
$manager->getRepository('Missing Entity');
}
-
}
diff --git a/Tests/Persister/ObjectSerializerPersisterTest.php b/Tests/Persister/ObjectSerializerPersisterTest.php
new file mode 100644
index 0000000..aae3a64
--- /dev/null
+++ b/Tests/Persister/ObjectSerializerPersisterTest.php
@@ -0,0 +1,131 @@
+id;
+ }
+
+ public function getName()
+ {
+ return $this->name;
+ }
+}
+
+class ObjectSerializerPersisterTest extends \PHPUnit_Framework_TestCase
+{
+ public function setUp()
+ {
+ if (!class_exists('Elastica\Type')) {
+ $this->markTestSkipped('The Elastica library classes are not available');
+ }
+ }
+
+ public function testThatCanReplaceObject()
+ {
+ $transformer = $this->getTransformer();
+
+ /** @var $typeMock \PHPUnit_Framework_MockObject_MockObject|\Elastica\Type */
+ $typeMock = $this->getMockBuilder('Elastica\Type')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $typeMock->expects($this->once())
+ ->method('deleteById')
+ ->with($this->equalTo(123));
+ $typeMock->expects($this->once())
+ ->method('addDocument');
+
+ $serializerMock = $this->getMockBuilder('FOS\ElasticaBundle\Serializer\Callback')->getMock();
+ $serializerMock->expects($this->once())->method('serialize');
+
+ $objectPersister = new ObjectSerializerPersister($typeMock, $transformer, 'SomeClass', array($serializerMock, 'serialize'));
+ $objectPersister->replaceOne(new POPO());
+ }
+
+ public function testThatCanInsertObject()
+ {
+ $transformer = $this->getTransformer();
+
+ /** @var $typeMock \PHPUnit_Framework_MockObject_MockObject|\Elastica\Type */
+ $typeMock = $this->getMockBuilder('Elastica\Type')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $typeMock->expects($this->never())
+ ->method('deleteById');
+ $typeMock->expects($this->once())
+ ->method('addDocument');
+
+ $serializerMock = $this->getMockBuilder('FOS\ElasticaBundle\Serializer\Callback')->getMock();
+ $serializerMock->expects($this->once())->method('serialize');
+
+ $objectPersister = new ObjectSerializerPersister($typeMock, $transformer, 'SomeClass', array($serializerMock, 'serialize'));
+ $objectPersister->insertOne(new POPO());
+ }
+
+ public function testThatCanDeleteObject()
+ {
+ $transformer = $this->getTransformer();
+
+ /** @var $typeMock \PHPUnit_Framework_MockObject_MockObject|\Elastica\Type */
+ $typeMock = $this->getMockBuilder('Elastica\Type')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $typeMock->expects($this->once())
+ ->method('deleteById');
+ $typeMock->expects($this->never())
+ ->method('addDocument');
+
+ $serializerMock = $this->getMockBuilder('FOS\ElasticaBundle\Serializer\Callback')->getMock();
+ $serializerMock->expects($this->once())->method('serialize');
+
+ $objectPersister = new ObjectSerializerPersister($typeMock, $transformer, 'SomeClass', array($serializerMock, 'serialize'));
+ $objectPersister->deleteOne(new POPO());
+ }
+
+ public function testThatCanInsertManyObjects()
+ {
+ $transformer = $this->getTransformer();
+
+ /** @var $typeMock \PHPUnit_Framework_MockObject_MockObject|\Elastica\Type */
+ $typeMock = $this->getMockBuilder('Elastica\Type')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $typeMock->expects($this->never())
+ ->method('deleteById');
+ $typeMock->expects($this->never())
+ ->method('addObject');
+ $typeMock->expects($this->never())
+ ->method('addObjects');
+ $typeMock->expects($this->once())
+ ->method('addDocuments');
+
+ $serializerMock = $this->getMockBuilder('FOS\ElasticaBundle\Serializer\Callback')->getMock();
+ $serializerMock->expects($this->exactly(2))->method('serialize');
+
+ $objectPersister = new ObjectSerializerPersister($typeMock, $transformer, 'SomeClass', array($serializerMock, 'serialize'));
+ $objectPersister->insertMany(array(new POPO(), new POPO()));
+ }
+
+ /**
+ * @return ModelToElasticaIdentifierTransformer
+ */
+ private function getTransformer()
+ {
+ $transformer = new ModelToElasticaIdentifierTransformer();
+ $transformer->setPropertyAccessor(PropertyAccess::getPropertyAccessor());
+
+ return $transformer;
+ }
+}
diff --git a/Tests/RepositoryTest.php b/Tests/RepositoryTest.php
index ded8009..c4d4efc 100644
--- a/Tests/RepositoryTest.php
+++ b/Tests/RepositoryTest.php
@@ -9,7 +9,6 @@ use FOS\ElasticaBundle\Repository;
*/
class RepositoryTest extends \PHPUnit_Framework_TestCase
{
-
public function testThatFindCallsFindOnFinder()
{
$testQuery = 'Test Query';
@@ -59,6 +58,22 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
$repository->findPaginated($testQuery);
}
+ public function testThatCreatePaginatorCreatesAPaginatorViaFinder()
+ {
+ $testQuery = 'Test Query';
+
+ /** @var $typeMock \PHPUnit_Framework_MockObject_MockObject|\FOS\ElasticaBundle\Finder\TransformedFinder */
+ $finderMock = $this->getMockBuilder('FOS\ElasticaBundle\Finder\TransformedFinder')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $finderMock->expects($this->once())
+ ->method('createPaginatorAdapter')
+ ->with($this->equalTo($testQuery));
+
+ $repository = new Repository($finderMock);
+ $repository->createPaginatorAdapter($testQuery);
+ }
+
public function testThatFindHybridCallsFindHybridOnFinder()
{
$testQuery = 'Test Query';
@@ -75,5 +90,4 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
$repository = new Repository($finderMock);
$repository->findHybrid($testQuery, $testLimit);
}
-
}
diff --git a/Tests/Transformer/ElasticaToModelTransformerCollectionTest.php b/Tests/Transformer/ElasticaToModelTransformerCollectionTest.php
index 9b1d782..eb4d8e4 100644
--- a/Tests/Transformer/ElasticaToModelTransformerCollectionTest.php
+++ b/Tests/Transformer/ElasticaToModelTransformerCollectionTest.php
@@ -3,6 +3,7 @@
namespace FOS\ElasticaBundle\Tests\Transformer;
use Elastica\Document;
+use Elastica\Result;
use FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerCollection;
class ElasticaToModelTransformerCollectionTest extends \PHPUnit_Framework_TestCase
@@ -98,6 +99,57 @@ class ElasticaToModelTransformerCollectionTest extends \PHPUnit_Framework_TestCa
$result2,
), $results);
}
+
+ public function testGetIdentifierFieldReturnsAMapOfIdentifiers()
+ {
+ $collection = new ElasticaToModelTransformerCollection(array());
+ $identifiers = $collection->getIdentifierField();
+ $this->assertInternalType('array', $identifiers);
+ $this->assertEmpty($identifiers);
+
+ $this->collectionSetup();
+ $identifiers = $this->collection->getIdentifierField();
+ $this->assertInternalType('array', $identifiers);
+ $this->assertEquals(array('type1' => 'id', 'type2' => 'id'), $identifiers);
+ }
+
+ public function elasticaResults()
+ {
+ $result = new Result(array('_id' => 123, '_type' => 'type1'));
+ $transformedObject = new POPO(123, array());
+
+ return array(
+ array(
+ $result, $transformedObject
+ )
+ );
+ }
+
+ /**
+ * @dataProvider elasticaResults
+ */
+ public function testHybridTransformDecoratesResultsWithHybridResultObjects($result, $transformedObject)
+ {
+ $transformer = $this->getMock('FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerInterface');
+ $transformer->expects($this->any())->method('getIdentifierField')->will($this->returnValue('id'));
+
+ $transformer
+ ->expects($this->any())
+ ->method('transform')
+ ->will($this->returnValue(array($transformedObject)));
+
+ $collection = new ElasticaToModelTransformerCollection(array('type1' => $transformer));
+
+ $hybridResults = $collection->hybridTransform(array($result));
+
+ $this->assertInternalType('array', $hybridResults);
+ $this->assertNotEmpty($hybridResults);
+ $this->assertContainsOnlyInstancesOf('FOS\ElasticaBundle\HybridResult', $hybridResults);
+
+ $hybridResult = array_pop($hybridResults);
+ $this->assertEquals($result, $hybridResult->getResult());
+ $this->assertEquals($transformedObject, $hybridResult->getTransformed());
+ }
}
class POPO
@@ -119,5 +171,4 @@ class POPO
class POPO2 extends POPO
{
-
}
diff --git a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
index 9990fa2..646d1a4 100644
--- a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
+++ b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
@@ -102,6 +102,11 @@ class POPO
);
}
+ public function getObj()
+ {
+ return array('foo' => 'foo', 'bar' => 'foo', 'id' => 1);
+ }
+
public function getUpper()
{
return (object) array('id' => 'parent', 'name' => 'a random name');
@@ -118,7 +123,6 @@ class ModelToElasticaAutoTransformerTest extends \PHPUnit_Framework_TestCase
public function setUp()
{
if (!class_exists('Elastica\Document')) {
- ;
$this->markTestSkipped('The Elastica library classes are not available');
}
}
@@ -273,6 +277,25 @@ class ModelToElasticaAutoTransformerTest extends \PHPUnit_Framework_TestCase
), $data['sub']);
}
+ public function testObjectDoesNotRequireProperties()
+ {
+ $transformer = $this->getTransformer();
+ $document = $transformer->transform(new POPO(), array(
+ 'obj' => array(
+ 'type' => 'object'
+ )
+ ));
+ $data = $document->getData();
+
+ $this->assertTrue(array_key_exists('obj', $data));
+ $this->assertInternalType('array', $data['obj']);
+ $this->assertEquals(array(
+ 'foo' => 'foo',
+ 'bar' => 'foo',
+ 'id' => 1
+ ), $data['obj']);
+ }
+
public function testParentMapping()
{
$transformer = $this->getTransformer();
diff --git a/Tests/Transformer/ModelToElasticaIdentifierTransformerTest.php b/Tests/Transformer/ModelToElasticaIdentifierTransformerTest.php
new file mode 100644
index 0000000..f1a77d4
--- /dev/null
+++ b/Tests/Transformer/ModelToElasticaIdentifierTransformerTest.php
@@ -0,0 +1,65 @@
+id;
+ }
+
+ public function getName()
+ {
+ return $this->name;
+ }
+}
+
+class ModelToElasticaIdentifierTransformerTest extends \PHPUnit_Framework_TestCase
+{
+ public function setUp()
+ {
+ if (!class_exists('Elastica\Document')) {
+ $this->markTestSkipped('The Elastica library classes are not available');
+ }
+ }
+
+ public function testGetDocumentWithIdentifierOnly()
+ {
+ $transformer = $this->getTransformer();
+ $document = $transformer->transform(new POPO(), array());
+ $data = $document->getData();
+
+ $this->assertInstanceOf('Elastica\Document', $document);
+ $this->assertEquals(123, $document->getId());
+ $this->assertCount(0, $data);
+ }
+
+ public function testGetDocumentWithIdentifierOnlyWithFields()
+ {
+ $transformer = $this->getTransformer();
+ $document = $transformer->transform(new POPO(), array('name' => array()));
+ $data = $document->getData();
+
+ $this->assertInstanceOf('Elastica\Document', $document);
+ $this->assertEquals(123, $document->getId());
+ $this->assertCount(0, $data);
+ }
+
+ /**
+ * @return ModelToElasticaIdentifierTransformer
+ */
+ private function getTransformer()
+ {
+ $transformer = new ModelToElasticaIdentifierTransformer();
+ $transformer->setPropertyAccessor(PropertyAccess::getPropertyAccessor());
+
+ return $transformer;
+ }
+}
diff --git a/Transformer/ElasticaToModelTransformerCollection.php b/Transformer/ElasticaToModelTransformerCollection.php
index 6264959..a261e81 100644
--- a/Transformer/ElasticaToModelTransformerCollection.php
+++ b/Transformer/ElasticaToModelTransformerCollection.php
@@ -84,11 +84,4 @@ class ElasticaToModelTransformerCollection implements ElasticaToModelTransformer
return $result;
}
-
- protected function getTypeToClassMap()
- {
- return array_map(function (ElasticaToModelTransformerInterface $transformer) {
- return $transformer->getObjectClass();
- }, $this->transformers);
- }
}
diff --git a/Transformer/ModelToElasticaAutoTransformer.php b/Transformer/ModelToElasticaAutoTransformer.php
index 6e01907..3107d0a 100644
--- a/Transformer/ModelToElasticaAutoTransformer.php
+++ b/Transformer/ModelToElasticaAutoTransformer.php
@@ -71,11 +71,11 @@ class ModelToElasticaAutoTransformer implements ModelToElasticaTransformerInterf
$value = $this->propertyAccessor->getValue($object, $key);
- if (isset($mapping['type']) && in_array($mapping['type'], array('nested', 'object'))) {
+ if (isset($mapping['type']) && in_array($mapping['type'], array('nested', 'object')) && isset($mapping['properties'])) {
/* $value is a nested document or object. Transform $value into
* an array of documents, respective the mapped properties.
*/
- $document->add($key, $this->transformNested($value, $mapping['properties']));
+ $document->set($key, $this->transformNested($value, $mapping['properties']));
continue;
}
@@ -89,7 +89,7 @@ class ModelToElasticaAutoTransformer implements ModelToElasticaTransformerInterf
continue;
}
- $document->add($key, $this->normalizeValue($value));
+ $document->set($key, $this->normalizeValue($value));
}
return $document;
@@ -149,5 +149,4 @@ class ModelToElasticaAutoTransformer implements ModelToElasticaTransformerInterf
return $value;
}
-
}
diff --git a/Transformer/ModelToElasticaIdentifierTransformer.php b/Transformer/ModelToElasticaIdentifierTransformer.php
new file mode 100644
index 0000000..654850f
--- /dev/null
+++ b/Transformer/ModelToElasticaIdentifierTransformer.php
@@ -0,0 +1,26 @@
+propertyAccessor->getValue($object, $this->options['identifier']);
+ return new Document($identifier);
+ }
+}
diff --git a/UPGRADE-3.0.md b/UPGRADE-3.0.md
new file mode 100644
index 0000000..a9a99a4
--- /dev/null
+++ b/UPGRADE-3.0.md
@@ -0,0 +1,32 @@
+UPGRADE FROM 2.1 to 3.0
+=======================
+
+### Serialization
+
+ * you can now define a Serializer service and callback for indexing. All providers and listeners will use it.
+
+ ```yml
+ serializer:
+ callback_class: FOS\ElasticaBundle\Serializer\Callback
+ serializer: serializer
+ ```
+
+### Mapping
+
+ * you do not have to setup any mapping anymore if you use a Serializer, properties are no more indexed only if
+ they are mapped. So this kind of configuration became valid:
+
+ ```yml
+ serializer:
+ callback_class: FOS\ElasticaBundle\Serializer\Callback
+ serializer: serializer
+ indexes:
+ acme:
+ client: default
+ types:
+ Article:
+ persistence:
+ driver: orm
+ model: Acme\Bundle\CoreBundle\Entity\Article
+ provider: ~
+ ```