From 83e27ede93ab9f48a4c5d455cfa32392f4729d34 Mon Sep 17 00:00:00 2001
From: Karel Souffriau
Date: Thu, 4 Apr 2013 15:44:42 +0200
Subject: [PATCH 001/447] Require PropertyAccess component
---
.../AbstractElasticaToModelTransformer.php | 29 ++++++++++++----
Propel/ElasticaToModelTransformer.php | 31 +++++++++++++----
Resources/config/config.xml | 6 +++-
Resources/config/mongodb.xml | 3 ++
Resources/config/orm.xml | 3 ++
Resources/config/propel.xml | 3 ++
Tests/Persister/ObjectPersisterTest.php | 5 +--
.../ModelToElasticaAutoTransformerTest.php | 12 ++-----
.../ModelToElasticaAutoTransformer.php | 33 ++++---------------
composer.json | 2 +-
10 files changed, 71 insertions(+), 56 deletions(-)
diff --git a/Doctrine/AbstractElasticaToModelTransformer.php b/Doctrine/AbstractElasticaToModelTransformer.php
index 0b339fb..f796eec 100755
--- a/Doctrine/AbstractElasticaToModelTransformer.php
+++ b/Doctrine/AbstractElasticaToModelTransformer.php
@@ -5,7 +5,7 @@ namespace FOS\ElasticaBundle\Doctrine;
use FOS\ElasticaBundle\HybridResult;
use FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerInterface;
use FOS\ElasticaBundle\Transformer\HighlightableModelInterface;
-use Symfony\Component\Form\Util\PropertyPath;
+use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
/**
* Maps Elastica documents with Doctrine objects
@@ -33,9 +33,16 @@ abstract class AbstractElasticaToModelTransformer implements ElasticaToModelTran
*/
protected $options = array(
'hydrate' => true,
- 'identifier' => 'id'
+ 'identifier' => 'id'
);
+ /**
+ * PropertyAccessor instance
+ *
+ * @var PropertyAccessorInterface
+ */
+ protected $propertyAccessor;
+
/**
* Instantiates a new Mapper
*
@@ -60,6 +67,16 @@ abstract class AbstractElasticaToModelTransformer implements ElasticaToModelTran
return $this->objectClass;
}
+ /**
+ * Set the PropertyAccessor
+ *
+ * @param PropertyAccessorInterface $propertyAccessor
+ */
+ public function setPropertyAccessor(PropertyAccessorInterface $propertyAccessor)
+ {
+ $this->propertyAccessor = $propertyAccessor;
+ }
+
/**
* Transforms an array of elastica objects into an array of
* model objects fetched from the doctrine repository
@@ -87,13 +104,13 @@ abstract class AbstractElasticaToModelTransformer implements ElasticaToModelTran
}
}
- $identifierProperty = new PropertyPath($this->options['identifier']);
-
// sort objects in the order of ids
$idPos = array_flip($ids);
- usort($objects, function($a, $b) use ($idPos, $identifierProperty)
+ $identifier = $this->options['identifier'];
+ $propertyAccessor = $this->propertyAccessor;
+ usort($objects, function($a, $b) use ($idPos, $identifier, $propertyAccessor)
{
- return $idPos[$identifierProperty->getValue($a)] > $idPos[$identifierProperty->getValue($b)];
+ return $idPos[$propertyAccessor->getValue($a, $identifier)] > $idPos[$propertyAccessor->getValue($b, $identifier)];
});
return $objects;
diff --git a/Propel/ElasticaToModelTransformer.php b/Propel/ElasticaToModelTransformer.php
index 76e4233..2678cd6 100644
--- a/Propel/ElasticaToModelTransformer.php
+++ b/Propel/ElasticaToModelTransformer.php
@@ -4,7 +4,7 @@ namespace FOS\ElasticaBundle\Propel;
use FOS\ElasticaBundle\HybridResult;
use FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerInterface;
-use Symfony\Component\Form\Util\PropertyPath;
+use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
/**
* Maps Elastica documents with Propel objects
@@ -32,6 +32,13 @@ class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface
'identifier' => 'id'
);
+ /**
+ * PropertyAccessor instance
+ *
+ * @var PropertyAccessorInterface
+ */
+ protected $propertyAccessor;
+
/**
* Instantiates a new Mapper
*
@@ -44,6 +51,16 @@ class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface
$this->options = array_merge($this->options, $options);
}
+ /**
+ * Set the PropertyAccessor
+ *
+ * @param PropertyAccessorInterface $propertyAccessor
+ */
+ public function setPropertyAccessor(PropertyAccessorInterface $propertyAccessor)
+ {
+ $this->propertyAccessor = $propertyAccessor;
+ }
+
/**
* Transforms an array of elastica objects into an array of
* model objects fetched from the propel repository
@@ -59,17 +76,17 @@ class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface
$objects = $this->findByIdentifiers($ids, $this->options['hydrate']);
- $identifierProperty = new PropertyPath($this->options['identifier']);
-
// sort objects in the order of ids
$idPos = array_flip($ids);
+ $identifier = $this->options['identifier'];
+ $propertyAccessor = $this->propertyAccessor;
if (is_object($objects)) {
- $objects->uasort(function($a, $b) use ($idPos, $identifierProperty) {
- return $idPos[$identifierProperty->getValue($a)] > $idPos[$identifierProperty->getValue($b)];
+ $objects->uasort(function($a, $b) use ($idPos, $identifier, $propertyAccessor) {
+ return $idPos[$propertyAccessor->getValue($a, $identifier)] > $idPos[$propertyAccessor->getValue($b, $identifier)];
});
} else {
- usort($objects, function($a, $b) use ($idPos, $identifierProperty) {
- return $idPos[$identifierProperty->getValue($a)] > $idPos[$identifierProperty->getValue($b)];
+ usort($objects, function($a, $b) use ($idPos, $identifier, $propertyAccessor) {
+ return $idPos[$propertyAccessor->getValue($a, $identifier)] > $idPos[$propertyAccessor->getValue($b, $identifier)];
});
}
diff --git a/Resources/config/config.xml b/Resources/config/config.xml
index a0819fb..bf9d40d 100644
--- a/Resources/config/config.xml
+++ b/Resources/config/config.xml
@@ -13,6 +13,7 @@
FOS\ElasticaBundle\Manager\RepositoryManager
FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerCollection
FOS\ElasticaBundle\Provider\ProviderRegistry
+ Symfony\Component\PropertyAccess\PropertyAccessor
@@ -58,7 +59,7 @@
-
+
@@ -75,6 +76,9 @@
+
+
+
diff --git a/Resources/config/mongodb.xml b/Resources/config/mongodb.xml
index 53c82f9..e60e3dc 100644
--- a/Resources/config/mongodb.xml
+++ b/Resources/config/mongodb.xml
@@ -24,6 +24,9 @@
+
+
+
diff --git a/Resources/config/orm.xml b/Resources/config/orm.xml
index b47cfc1..4fd6ae7 100644
--- a/Resources/config/orm.xml
+++ b/Resources/config/orm.xml
@@ -25,6 +25,9 @@
+
+
+
diff --git a/Resources/config/propel.xml b/Resources/config/propel.xml
index a6fc32f..7a7d93e 100644
--- a/Resources/config/propel.xml
+++ b/Resources/config/propel.xml
@@ -14,6 +14,9 @@
+
+
+
diff --git a/Tests/Persister/ObjectPersisterTest.php b/Tests/Persister/ObjectPersisterTest.php
index 0a46553..e672e12 100644
--- a/Tests/Persister/ObjectPersisterTest.php
+++ b/Tests/Persister/ObjectPersisterTest.php
@@ -213,10 +213,7 @@ class ObjectPersisterTest extends \PHPUnit_Framework_TestCase
private function getTransformer()
{
$transformer = new ModelToElasticaAutoTransformer();
-
- if (class_exists('Symfony\Component\PropertyAccess\PropertyAccess')) {
- $transformer->setPropertyAccessor(PropertyAccess::getPropertyAccessor());
- }
+ $transformer->setPropertyAccessor(PropertyAccess::getPropertyAccessor());
return $transformer;
}
diff --git a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
index 798ea38..5ac13e6 100644
--- a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
+++ b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
@@ -203,12 +203,7 @@ class ModelToElasticaAutoTransformerTest extends \PHPUnit_Framework_TestCase
public function testThatCannotTransformObjectWhenGetterDoesNotExistForPrivateMethod()
{
- // Support both Symfony 2.1 (Form component) and 2.2 (PropertyAccess component)
- $expectedException = class_exists('Symfony\Component\PropertyAccess\PropertyAccess')
- ? 'Symfony\Component\PropertyAccess\Exception\PropertyAccessDeniedException'
- : 'Symfony\Component\Form\Exception\PropertyAccessDeniedException';
-
- $this->setExpectedException($expectedException);
+ $this->setExpectedException('Symfony\Component\PropertyAccess\Exception\PropertyAccessDeniedException');
$transformer = $this->getTransformer();
$transformer->transform(new POPO(), array('desc' => array()));
@@ -302,10 +297,7 @@ class ModelToElasticaAutoTransformerTest extends \PHPUnit_Framework_TestCase
private function getTransformer()
{
$transformer = new ModelToElasticaAutoTransformer();
-
- if (class_exists('Symfony\Component\PropertyAccess\PropertyAccess')) {
- $transformer->setPropertyAccessor(PropertyAccess::getPropertyAccessor());
- }
+ $transformer->setPropertyAccessor(PropertyAccess::getPropertyAccessor());
return $transformer;
}
diff --git a/Transformer/ModelToElasticaAutoTransformer.php b/Transformer/ModelToElasticaAutoTransformer.php
index 4565199..ad20529 100644
--- a/Transformer/ModelToElasticaAutoTransformer.php
+++ b/Transformer/ModelToElasticaAutoTransformer.php
@@ -2,7 +2,6 @@
namespace FOS\ElasticaBundle\Transformer;
-use Symfony\Component\Form\Util\PropertyPath;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
/**
@@ -22,11 +21,11 @@ class ModelToElasticaAutoTransformer implements ModelToElasticaTransformerInterf
);
/**
- * PropertyAccessor instance (will be used if available)
+ * PropertyAccessor instance
*
* @var PropertyAccessorInterface
*/
- private $propertyAccessor;
+ protected $propertyAccessor;
/**
* Instanciates a new Mapper
@@ -43,7 +42,7 @@ class ModelToElasticaAutoTransformer implements ModelToElasticaTransformerInterf
*
* @param PropertyAccessorInterface $propertyAccessor
*/
- public function setPropertyAccessor(PropertyAccessorInterface $propertyAccessor = null)
+ public function setPropertyAccessor(PropertyAccessorInterface $propertyAccessor)
{
$this->propertyAccessor = $propertyAccessor;
}
@@ -58,17 +57,17 @@ class ModelToElasticaAutoTransformer implements ModelToElasticaTransformerInterf
**/
public function transform($object, array $fields)
{
- $identifier = $this->getPropertyValue($object, $this->options['identifier']);
+ $identifier = $this->propertyAccessor->getValue($object, $this->options['identifier']);
$document = new \Elastica_Document($identifier);
foreach ($fields as $key => $mapping) {
- $value = $this->getPropertyValue($object, $key);
+ $value = $this->propertyAccessor->getValue($object, $key);
if (isset($mapping['_parent']['identifier'])) {
/* $value is the parent. Read its identifier and set that as the
* document's parent.
*/
- $document->setParent($this->getPropertyValue($value, $mapping['_parent']['identifier']));
+ $document->setParent($this->propertyAccessor->getValue($value, $mapping['_parent']['identifier']));
continue;
}
@@ -96,26 +95,6 @@ class ModelToElasticaAutoTransformer implements ModelToElasticaTransformerInterf
return $document;
}
- /**
- * Get the value of an object property.
- *
- * This method will use Symfony 2.2's PropertyAccessor if it is available.
- *
- * @param object $object
- * @param string $property
- * @return mixed
- */
- protected function getPropertyValue($object, $property)
- {
- if (isset($this->propertyAccessor)) {
- return $this->propertyAccessor->getValue($object, $property);
- }
-
- $propertyPath = new PropertyPath($property);
-
- return $propertyPath->getValue($object);
- }
-
/**
* transform a nested document or an object property into an array of ElasticaDocument
*
diff --git a/composer.json b/composer.json
index a4969a0..3629fda 100644
--- a/composer.json
+++ b/composer.json
@@ -15,6 +15,7 @@
"symfony/framework-bundle": ">=2.1.0,<2.3.0-dev",
"symfony/console": ">=2.1.0,<2.3.0-dev",
"symfony/form": ">=2.1.0,<2.3.0-dev",
+ "symfony/property-access": "2.2.*",
"ruflin/elastica": "0.19.8"
},
"require-dev":{
@@ -25,7 +26,6 @@
"knplabs/knp-components": "1.2.*"
},
"suggest": {
- "symfony/property-access": "2.2.*",
"doctrine/orm": ">=2.2,<2.5-dev",
"doctrine/mongodb-odm": "1.0.*@dev",
"propel/propel1": "1.6.*",
From 4f5be038ef8892c7efde9fb7a68c30d929a5081f Mon Sep 17 00:00:00 2001
From: Karel Souffriau
Date: Fri, 5 Apr 2013 13:17:00 +0200
Subject: [PATCH 002/447] Collector: print query data as json instead of yaml
---
Resources/views/Collector/elastica.html.twig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Resources/views/Collector/elastica.html.twig b/Resources/views/Collector/elastica.html.twig
index 137dcdb..a665e2d 100644
--- a/Resources/views/Collector/elastica.html.twig
+++ b/Resources/views/Collector/elastica.html.twig
@@ -46,7 +46,7 @@
Path: {{ query.path }}
Method: {{ query.method }}
- {{ query.data|yaml_encode }}
+ {{ query.data|json_encode }}
Time: {{ '%0.2f'|format(query.executionMS * 1000) }} ms
From ae4f676c2504de6583a0458fb105889e88e2a53d Mon Sep 17 00:00:00 2001
From: Jeremy Mikola
Date: Fri, 5 Apr 2013 13:31:19 -0400
Subject: [PATCH 003/447] Create 2.1.x-dev branch alias for master
---
composer.json | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/composer.json b/composer.json
index 3629fda..b1be5fa 100644
--- a/composer.json
+++ b/composer.json
@@ -35,5 +35,10 @@
"autoload": {
"psr-0": { "FOS\\ElasticaBundle": "" }
},
- "target-dir": "FOS/ElasticaBundle"
+ "target-dir": "FOS/ElasticaBundle",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.1.x-dev"
+ }
+ }
}
From 58e983fb068df8b28c171fb87fcc68ad175fedef Mon Sep 17 00:00:00 2001
From: Jeremy Mikola
Date: Tue, 16 Apr 2013 13:16:53 -0400
Subject: [PATCH 004/447] Document installation via composer in README (closes
#271)
---
README.md | 107 +++++++++++++++---------------------------------------
1 file changed, 29 insertions(+), 78 deletions(-)
diff --git a/README.md b/README.md
index eefb1b7..a375ca1 100644
--- a/README.md
+++ b/README.md
@@ -1,95 +1,46 @@
-[Elastica](https://github.com/ruflin/Elastica) integration in Symfony2
+[Elastica](https://github.com/ruflin/Elastica) integration in Symfony2
-## Installation
+### Installation
-### Install elasticsearch
+#### Bundle and Dependencies
-http://www.elasticsearch.org/guide/reference/setup/installation.html
+For Symfony 2.0.x projects, you must use a 1.x release of this bundle.
-### Install Elastica
+Add FOSElasticaBundle to your application's `composer.json` file:
-#### Download
+```json
+{
+ "require": {
+ "friendsofsymfony/elastica-bundle": "~1.0"
+ }
+}
+```
-**With submodule**
-
- `git submodule add git://github.com/ruflin/Elastica vendor/elastica`
-
-**With clone**
-
- `git clone git://github.com/ruflin/Elastica vendor/elastica`
-
-**Using the vendors script**
-
-Add the following lines to your deps file:
-
- [Elastica]
- git=git://github.com/ruflin/Elastica.git
- target=elastica
-
-#### Register autoloading
-
- // app/autoload.php
-
- $loader->registerPrefixes(array(
- ...
- 'Elastica' => __DIR__.'/../vendor/elastica/lib',
- ));
-
-### Install ElasticaBundle
-
-Use the master branch with Symfony2 master only, use the 2.0 branch with Symfony2.0.x releases.
-
-#### Download
-
-**With submodule**
-
- `git submodule add git://github.com/Exercise/FOSElasticaBundle vendor/bundles/FOS/ElasticaBundle`
-
-**With clone**
-
- `git clone git://github.com/Exercise/FOSElasticaBundle vendor/bundles/FOS/ElasticaBundle`
-
-**With the vendors script**
-
-Add the following lines to your deps file:
-
- [FOSElasticaBundle]
- git=git://github.com/Exercise/FOSElasticaBundle.git
- target=bundles/FOS/ElasticaBundle
-
-For the 2.0 branch for use with Symfony2.0.x releases add the following:
-
- [FOSElasticaBundle]
- git=git://github.com/Exercise/FOSElasticaBundle.git
- target=bundles/FOS/ElasticaBundle
- version=origin/2.0
-
-Run the vendors script:
+Install the bundle and its dependencies with the following command:
```bash
-$ php bin/vendors install
+$ php composer.phar update friendsofsymfony/elastica-bundle
```
-#### Register autoloading
- // app/autoload.php
+You may rely on Composer to fetch the appropriate version of Elastica. Lastly,
+enable the bundle in your application kernel:
- $loader->registerNamespaces(array(
- ...
- 'FOS' => __DIR__.'/../vendor/bundles',
- ));
+```php
+// app/AppKernel.php
-#### Register the bundle
+public function registerBundles()
+{
+ $bundles = array(
+ // ...
+ new FOS\ElasticaBundle\FOSElasticaBundle(),
+ );
+}
+```
- // app/AppKernel.php
+#### Elasticsearch
- public function registerBundles()
- {
- return array(
- // ...
- new FOS\ElasticaBundle\FOSElasticaBundle(),
- // ...
- );
- }
+Instructions for installing and deploying Elasticsearch may be found
+[here](http://www.elasticsearch.org/guide/reference/setup/installation/).
### Basic configuration
From 8ffd1a7c3de611eabcf61040dcb48ab605c768b9 Mon Sep 17 00:00:00 2001
From: Jeremy Mikola
Date: Tue, 16 Apr 2013 13:26:14 -0400
Subject: [PATCH 005/447] Update install version and add links to compatibility
info
---
README.md | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 9c80bdf..0bcae02 100644
--- a/README.md
+++ b/README.md
@@ -4,14 +4,18 @@
#### Bundle and Dependencies
-For Symfony 2.0.x projects, you must use a 1.x release of this bundle.
+For Symfony 2.0.x projects, you must use a 1.x release of this bundle. Please
+check the bundle
+[tags](https://github.com/FriendsOfSymfony/FOSElasticaBundle/tags) or the
+[Packagist](https://packagist.org/packages/friendsofsymfony/elastica-bundle)
+page for information on Symfony and Elastica compatibility.
Add FOSElasticaBundle to your application's `composer.json` file:
```json
{
"require": {
- "friendsofsymfony/elastica-bundle": "~1.0"
+ "friendsofsymfony/elastica-bundle": "~2.0"
}
}
```
From 4b4a56db1e42fd3bc30aca3cb553e7e1f636caee Mon Sep 17 00:00:00 2001
From: Thomas Tourlourat
Date: Wed, 17 Apr 2013 11:33:32 +0300
Subject: [PATCH 006/447] Check for "indexes" key in
Configuration::getNestings()
---
DependencyInjection/Configuration.php | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 7872e90..4482a4c 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -363,6 +363,10 @@ class Configuration implements ConfigurationInterface
*/
protected function getNestings()
{
+ if (!isset($this->configArray[0]['indexes'])) {
+ return array();
+ }
+
$nestings = array();
foreach ($this->configArray[0]['indexes'] as $index) {
if (empty($index['types'])) {
From c5ee26099bbfe846a558f0357704ddbd8b62750c Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Thu, 10 Jan 2013 14:05:50 +0100
Subject: [PATCH 007/447] Adding support to pass a serializer to elastica
---
DependencyInjection/Configuration.php | 10 ++++++++++
DependencyInjection/FOSElasticaExtension.php | 12 ++++++++----
2 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 4482a4c..6f5c35c 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -34,6 +34,7 @@ class Configuration implements ConfigurationInterface
->scalarNode('default_client')->end()
->scalarNode('default_index')->end()
->scalarNode('default_manager')->defaultValue('orm')->end()
+ ->scalarNode('serializer_id')->end()
->end()
;
@@ -205,6 +206,15 @@ class Configuration implements ConfigurationInterface
->prototype('array')
->treatNullLike(array())
->children()
+ ->arrayNode('serializer')
+ ->addDefaultsIfNotSet()
+ ->children()
+ ->arrayNode('groups')
+ ->treatNullLike(array())
+ ->prototype('scalar')->end()
+ ->end()
+ ->end()
+ ->end()
->scalarNode('index_analyzer')->end()
->scalarNode('search_analyzer')->end()
->arrayNode('persistence')
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 0cb5c27..4cad42c 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -40,7 +40,7 @@ class FOSElasticaExtension extends Extension
}
$clientIdsByName = $this->loadClients($config['clients'], $container);
- $indexIdsByName = $this->loadIndexes($config['indexes'], $container, $clientIdsByName, $config['default_client']);
+ $indexIdsByName = $this->loadIndexes($config['indexes'], $container, $clientIdsByName, $config['default_client'], $config['serializer_id']);
$indexRefsByName = array_map(function($id) {
return new Reference($id);
}, $indexIdsByName);
@@ -93,7 +93,7 @@ class FOSElasticaExtension extends Extension
* @throws \InvalidArgumentException
* @return array
*/
- protected function loadIndexes(array $indexes, ContainerBuilder $container, array $clientIdsByName, $defaultClientName)
+ protected function loadIndexes(array $indexes, ContainerBuilder $container, array $clientIdsByName, $defaultClientName, $serializerId)
{
$indexIds = array();
foreach ($indexes as $name => $index) {
@@ -128,7 +128,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);
+ $this->loadTypes(isset($index['types']) ? $index['types'] : array(), $container, $name, $indexId, $typePrototypeConfig, $serializerId);
}
return $indexIds;
@@ -169,8 +169,9 @@ class FOSElasticaExtension extends Extension
* @param $indexId
* @param array $typePrototypeConfig
*/
- protected function loadTypes(array $types, ContainerBuilder $container, $indexName, $indexId, array $typePrototypeConfig)
+ protected function loadTypes(array $types, ContainerBuilder $container, $indexName, $indexId, array $typePrototypeConfig, $serializerId)
{
+ $serializer = $serializerId ? new Reference($serializerId) : null;
foreach ($types as $name => $type) {
$type = self::deepArrayUnion($typePrototypeConfig, $type);
$typeId = sprintf('%s.%s', $indexId, $name);
@@ -178,6 +179,9 @@ class FOSElasticaExtension extends Extension
$typeDef = new Definition('%fos_elastica.type.class%', $typeDefArgs);
$typeDef->setFactoryService($indexId);
$typeDef->setFactoryMethod('getType');
+ if ($serializer) {
+ $typeDef->addMethodCall('setSerializer', array($serializer, $type['serializer']['groups']));
+ }
$container->setDefinition($typeId, $typeDef);
if (isset($type['_source'])) {
$this->indexConfigs[$indexName]['config']['mappings'][$name]['_source'] = $type['_source'];
From 73fd4fe6b00e22dfa582fd8e13261d341edb3ddb Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Thu, 24 Jan 2013 15:07:38 +0100
Subject: [PATCH 008/447] Creating a serializer callable for every type in an
index and passing it to elastica
---
DependencyInjection/Configuration.php | 10 ++++++++-
DependencyInjection/FOSElasticaExtension.php | 23 ++++++++++++++------
2 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 6f5c35c..7e0af16 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -34,7 +34,15 @@ class Configuration implements ConfigurationInterface
->scalarNode('default_client')->end()
->scalarNode('default_index')->end()
->scalarNode('default_manager')->defaultValue('orm')->end()
- ->scalarNode('serializer_id')->end()
+ ->arrayNode('serializer')
+ ->prototype('array')
+ ->treatNullLike(array())
+ ->children()
+ ->scalarNode('callable_class')->end()
+ ->scalarNode('id')->end()
+ ->end()
+ ->end()
+ ->end()
->end()
;
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 4cad42c..1469510 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -40,7 +40,7 @@ class FOSElasticaExtension extends Extension
}
$clientIdsByName = $this->loadClients($config['clients'], $container);
- $indexIdsByName = $this->loadIndexes($config['indexes'], $container, $clientIdsByName, $config['default_client'], $config['serializer_id']);
+ $indexIdsByName = $this->loadIndexes($config['indexes'], $container, $clientIdsByName, $config['default_client'], $config['serializer']);
$indexRefsByName = array_map(function($id) {
return new Reference($id);
}, $indexIdsByName);
@@ -93,7 +93,7 @@ class FOSElasticaExtension extends Extension
* @throws \InvalidArgumentException
* @return array
*/
- protected function loadIndexes(array $indexes, ContainerBuilder $container, array $clientIdsByName, $defaultClientName, $serializerId)
+ protected function loadIndexes(array $indexes, ContainerBuilder $container, array $clientIdsByName, $defaultClientName, $serializerConfig)
{
$indexIds = array();
foreach ($indexes as $name => $index) {
@@ -128,7 +128,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, $serializerId);
+ $this->loadTypes(isset($index['types']) ? $index['types'] : array(), $container, $name, $indexId, $typePrototypeConfig, $serializerConfig);
}
return $indexIds;
@@ -169,9 +169,8 @@ class FOSElasticaExtension extends Extension
* @param $indexId
* @param array $typePrototypeConfig
*/
- protected function loadTypes(array $types, ContainerBuilder $container, $indexName, $indexId, array $typePrototypeConfig, $serializerId)
+ protected function loadTypes(array $types, ContainerBuilder $container, $indexName, $indexId, array $typePrototypeConfig, $serializerConfig)
{
- $serializer = $serializerId ? new Reference($serializerId) : null;
foreach ($types as $name => $type) {
$type = self::deepArrayUnion($typePrototypeConfig, $type);
$typeId = sprintf('%s.%s', $indexId, $name);
@@ -179,8 +178,18 @@ class FOSElasticaExtension extends Extension
$typeDef = new Definition('%fos_elastica.type.class%', $typeDefArgs);
$typeDef->setFactoryService($indexId);
$typeDef->setFactoryMethod('getType');
- if ($serializer) {
- $typeDef->addMethodCall('setSerializer', array($serializer, $type['serializer']['groups']));
+ if ($serializerConfig) {
+
+ $serializerDefArgs = array(new Reference($serializerConfig['id']));
+ if (isset($type['serializer']['groups'])) {
+ $serializerDefArgs[] = $type['serializer']['groups'];
+ }
+
+ $serializerDef = new Definition("%{$serializerConfig['callable_class']}%", $serializerDefArgs);
+ $serializerId = sprintf('%s.%s.serializer', $indexId, $name);
+ $container->setDefinition($serializerId, $serializerDef);
+
+ $typeDef->addMethodCall('setSerializer', array(array(new Reference($serializerId), 'serialize')));
}
$container->setDefinition($typeId, $typeDef);
if (isset($type['_source'])) {
From c99eee9c4b0b8f1239e1d6256bd7f53a35cfd631 Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Thu, 24 Jan 2013 15:57:02 +0100
Subject: [PATCH 009/447] Adding some documentation
---
README.md | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 59 insertions(+)
diff --git a/README.md b/README.md
index 0bcae02..cc39175 100644
--- a/README.md
+++ b/README.md
@@ -58,6 +58,23 @@ Most of the time, you will need only one.
clients:
default: { host: localhost, port: 9200 }
+
+#### Declare a serializer
+
+Elastica can handle objects instead of data arrays if a serializer callable is configured
+
+ #app/config/config.yml
+ foq_elastica:
+ clients:
+ default: { host: localhost, port: 9200 }
+ serializer:
+ callable_class: %classname%
+ id: serializer
+
+"callable_class" is the class name of a class having a public method serialize($object). "id" is the service id for the
+actual serializer, e.g. 'serializer' if you're using the JMSSerializerBundle. If this is configured you can use
+Elastica_Type::addObject instead of Elastica_Type::addDocument to add data to the index.
+
#### Declare an index
Elasticsearch index is comparable to Doctrine entity manager.
@@ -66,6 +83,9 @@ Most of the time, you will need only one.
fos_elastica:
clients:
default: { host: localhost, port: 9200 }
+ serializer:
+ callable_class: %classname%
+ id: serializer
indexes:
website:
client: default
@@ -96,6 +116,9 @@ Elasticsearch type is comparable to Doctrine entity repository.
fos_elastica:
clients:
default: { host: localhost, port: 9200 }
+ serializer:
+ callable_class: %classname%
+ id: serializer
indexes:
website:
client: default
@@ -109,11 +132,38 @@ Elasticsearch type is comparable to Doctrine entity repository.
Our type is now available as a service: `fos_elastica.index.website.user`. It is an instance of `Elastica_Type`.
+### Declaring serializer groups
+
+If you are using the JMSSerializerBundle for serializing objects passed to elastica you can define serializer groups
+per type.
+
+ foq_elastica:
+ clients:
+ default: { host: localhost, port: 9200 }
+ serializer:
+ callable_class: %classname%
+ id: serializer
+ indexes:
+ website:
+ client: default
+ types:
+ user:
+ mappings:
+ username: { boost: 5 }
+ firstName: { boost: 3 }
+ lastName: { boost: 3 }
+ aboutMe:
+ serializer:
+ groups: [elastica, Default]
+
### Declaring parent field
fos_elastica:
clients:
default: { host: localhost, port: 9200 }
+ serializer:
+ callable_class: %classname%
+ id: serializer
indexes:
website:
client: default
@@ -129,6 +179,9 @@ Our type is now available as a service: `fos_elastica.index.website.user`. It is
fos_elastica:
clients:
default: { host: localhost, port: 9200 }
+ serializer:
+ callable_class: %classname%
+ id: serializer
indexes:
website:
client: default
@@ -164,6 +217,9 @@ some configuration will let ElasticaBundle do it for us.
fos_elastica:
clients:
default: { host: localhost, port: 9200 }
+ serializer:
+ callable_class: %classname%
+ id: serializer
indexes:
website:
client: default
@@ -281,6 +337,9 @@ Declare that you want a Doctrine/Propel finder in your configuration:
fos_elastica:
clients:
default: { host: localhost, port: 9200 }
+ serializer:
+ callable_class: %classname%
+ id: serializer
indexes:
website:
client: default
From a139d18b220b60334192669e6eb87c2dd143cdab Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Fri, 25 Jan 2013 16:48:29 +0100
Subject: [PATCH 010/447] Adding default callback for serialization if
serialization is turned on
---
DependencyInjection/Configuration.php | 10 ++++----
DependencyInjection/FOSElasticaExtension.php | 13 +++++-----
Resources/config/config.xml | 6 +++--
Serializer/Callback.php | 25 ++++++++++++++++++++
4 files changed, 39 insertions(+), 15 deletions(-)
create mode 100644 Serializer/Callback.php
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 7e0af16..f23f3a8 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -35,12 +35,10 @@ class Configuration implements ConfigurationInterface
->scalarNode('default_index')->end()
->scalarNode('default_manager')->defaultValue('orm')->end()
->arrayNode('serializer')
- ->prototype('array')
- ->treatNullLike(array())
- ->children()
- ->scalarNode('callable_class')->end()
- ->scalarNode('id')->end()
- ->end()
+ ->treatNullLike(array())
+ ->children()
+ ->scalarNode('callback')->defaultValue('foq_elastica.serializer.callback')->end()
+ ->scalarNode('serializer')->defaultValue('serializer')->end()
->end()
->end()
->end()
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 1469510..1c2cbe0 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -40,7 +40,8 @@ class FOSElasticaExtension extends Extension
}
$clientIdsByName = $this->loadClients($config['clients'], $container);
- $indexIdsByName = $this->loadIndexes($config['indexes'], $container, $clientIdsByName, $config['default_client'], $config['serializer']);
+ $serializerConfig = isset($config['serializer']) ? $config['serializer'] : null;
+ $indexIdsByName = $this->loadIndexes($config['indexes'], $container, $clientIdsByName, $config['default_client'], $serializerConfig);
$indexRefsByName = array_map(function($id) {
return new Reference($id);
}, $indexIdsByName);
@@ -179,14 +180,12 @@ class FOSElasticaExtension extends Extension
$typeDef->setFactoryService($indexId);
$typeDef->setFactoryMethod('getType');
if ($serializerConfig) {
-
- $serializerDefArgs = array(new Reference($serializerConfig['id']));
+ $serializerDef = clone $container->getDefinition($serializerConfig['callback']);
+ $serializerDef->addMethodCall('setSerializer', array(new Reference($serializerConfig['serializer'])));
if (isset($type['serializer']['groups'])) {
- $serializerDefArgs[] = $type['serializer']['groups'];
+ $serializerDef->addMethodCall('setGroups', array($type['serializer']['groups']));
}
-
- $serializerDef = new Definition("%{$serializerConfig['callable_class']}%", $serializerDefArgs);
- $serializerId = sprintf('%s.%s.serializer', $indexId, $name);
+ $serializerId = sprintf('%s.%s.serializer.callback', $indexId, $name);
$container->setDefinition($serializerId, $serializerDef);
$typeDef->addMethodCall('setSerializer', array(array(new Reference($serializerId), 'serialize')));
diff --git a/Resources/config/config.xml b/Resources/config/config.xml
index bf9d40d..f073aeb 100644
--- a/Resources/config/config.xml
+++ b/Resources/config/config.xml
@@ -14,6 +14,7 @@
FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerCollection
FOS\ElasticaBundle\Provider\ProviderRegistry
Symfony\Component\PropertyAccess\PropertyAccessor
+ FOQ\ElasticaBundle\Serializer\Callback
@@ -77,8 +78,9 @@
-
-
+
+
+
diff --git a/Serializer/Callback.php b/Serializer/Callback.php
new file mode 100644
index 0000000..576004a
--- /dev/null
+++ b/Serializer/Callback.php
@@ -0,0 +1,25 @@
+serializer = $serializer;
+ }
+
+ public function setGroups($groups){
+ $this->groups = $groups;
+ }
+
+ public function serialize($object)
+ {
+ $this->serializer->setGroups(null);
+ $this->serializer->setGroups($this->groups);
+ return $this->serializer->serialize($object, 'json');
+ }
+}
From bcf564d09c2116b2f9ed1df28503e54b9bc5f40d Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Mon, 28 Jan 2013 08:22:01 +0100
Subject: [PATCH 011/447] Adapting readme
---
README.md | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index cc39175..e8ba475 100644
--- a/README.md
+++ b/README.md
@@ -68,12 +68,18 @@ Elastica can handle objects instead of data arrays if a serializer callable is c
clients:
default: { host: localhost, port: 9200 }
serializer:
- callable_class: %classname%
- id: serializer
+ callback: callback
+ serializer: serializer
-"callable_class" is the class name of a class having a public method serialize($object). "id" is the service id for the
+"callback" is the service having a public method serialize($object). "serializer" is the service id for the
actual serializer, e.g. 'serializer' if you're using the JMSSerializerBundle. If this is configured you can use
Elastica_Type::addObject instead of Elastica_Type::addDocument to add data to the index.
+The bundle provides a default implementation with a serializer service id 'serializer' that can be turned on by adding
+the following line to your config.
+
+ #app/config/config.yml
+ foq_elastica:
+ serializer: ~
#### Declare an index
From 1abe1f48ddd92253f106c72f9bb77dd3601c5e41 Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Mon, 28 Jan 2013 08:54:53 +0100
Subject: [PATCH 012/447] Having a parameter name defining a class for the
serializer callback, because directly putting service id or parameter doesn't
work because these values are not available at bundle configuration time
---
DependencyInjection/Configuration.php | 2 +-
DependencyInjection/FOSElasticaExtension.php | 8 ++++++--
README.md | 2 +-
3 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index f23f3a8..c68aba5 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -37,7 +37,7 @@ class Configuration implements ConfigurationInterface
->arrayNode('serializer')
->treatNullLike(array())
->children()
- ->scalarNode('callback')->defaultValue('foq_elastica.serializer.callback')->end()
+ ->scalarNode('callback')->defaultValue('foq_elastica.serializer.callback.class')->end()
->scalarNode('serializer')->defaultValue('serializer')->end()
->end()
->end()
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 1c2cbe0..c1d8aa2 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -180,12 +180,16 @@ class FOSElasticaExtension extends Extension
$typeDef->setFactoryService($indexId);
$typeDef->setFactoryMethod('getType');
if ($serializerConfig) {
- $serializerDef = clone $container->getDefinition($serializerConfig['callback']);
+
+ $serializerDef = new Definition("%{$serializerConfig['callback']}%");
+ $serializerId = sprintf('%s.%s.serializer.callback', $indexId, $name);
+
+ $typeDef->addMethodCall('setSerializer', array(array(new Reference($serializerId), 'serialize')));
$serializerDef->addMethodCall('setSerializer', array(new Reference($serializerConfig['serializer'])));
if (isset($type['serializer']['groups'])) {
$serializerDef->addMethodCall('setGroups', array($type['serializer']['groups']));
}
- $serializerId = sprintf('%s.%s.serializer.callback', $indexId, $name);
+
$container->setDefinition($serializerId, $serializerDef);
$typeDef->addMethodCall('setSerializer', array(array(new Reference($serializerId), 'serialize')));
diff --git a/README.md b/README.md
index e8ba475..8580481 100644
--- a/README.md
+++ b/README.md
@@ -71,7 +71,7 @@ Elastica can handle objects instead of data arrays if a serializer callable is c
callback: callback
serializer: serializer
-"callback" is the service having a public method serialize($object). "serializer" is the service id for the
+"callback" is the name of a parameter defining a class having a public method serialize($object). "serializer" is the service id for the
actual serializer, e.g. 'serializer' if you're using the JMSSerializerBundle. If this is configured you can use
Elastica_Type::addObject instead of Elastica_Type::addDocument to add data to the index.
The bundle provides a default implementation with a serializer service id 'serializer' that can be turned on by adding
From d8f836d17929b0e15342a6bbe6dc849ba4ca70a1 Mon Sep 17 00:00:00 2001
From: Lukas Kahwe Smith
Date: Tue, 29 Jan 2013 23:17:40 +0100
Subject: [PATCH 013/447] CS fixes and minor tweaks in the Callback class
---
Serializer/Callback.php | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/Serializer/Callback.php b/Serializer/Callback.php
index 576004a..fff190d 100644
--- a/Serializer/Callback.php
+++ b/Serializer/Callback.php
@@ -2,24 +2,32 @@
namespace FOQ\ElasticaBundle\Serializer;
+use JMS\Serializer\Serializer;
+
class Callback
{
protected $serializer;
protected $groups;
- public function setSerializer($serializer){
+ public function setSerializer($serializer)
+ {
$this->serializer = $serializer;
}
- public function setGroups($groups){
+ public function setGroups(array $groups)
+ {
$this->groups = $groups;
}
public function serialize($object)
{
- $this->serializer->setGroups(null);
- $this->serializer->setGroups($this->groups);
+ if ($this->serializer instanceof Serializer) {
+ $this->serializer->setGroups($this->groups);
+ } elseif ($this->groups) {
+ throw new \RuntimeException('Setting serialization groups requires using "JMS\Serializer\Serializer"');
+ }
+
return $this->serializer->serialize($object, 'json');
}
}
From aafb6e53fb8f99e37f4113027189cbb7abd4b949 Mon Sep 17 00:00:00 2001
From: Lukas Kahwe Smith
Date: Mon, 22 Apr 2013 13:20:10 +0200
Subject: [PATCH 014/447] made the bundle compatible with Elastica 0.20.x
---
Client.php | 6 +--
Command/SearchCommand.php | 12 ++---
DependencyInjection/Configuration.php | 3 +-
DependencyInjection/FOSElasticaExtension.php | 3 ++
Finder/FinderInterface.php | 2 +-
Finder/PaginatedFinderInterface.php | 4 +-
Finder/TransformedFinder.php | 14 +++---
HybridResult.php | 4 +-
IndexManager.php | 10 +++--
Paginator/RawPaginatorAdapter.php | 20 ++++-----
Paginator/RawPartialResults.php | 10 ++---
Paginator/TransformedPaginatorAdapter.php | 12 ++---
Paginator/TransformedPartialResults.php | 6 +--
Persister/ObjectPersister.php | 8 ++--
Propel/ElasticaToModelTransformer.php | 5 ++-
README.md | 44 ++++++++++---------
Resetter.php | 6 ++-
Resources/config/config.xml | 6 +--
Serializer/Callback.php | 32 +++++++++++---
Tests/IndexManagerTest.php | 4 +-
Tests/Persister/ObjectPersisterTest.php | 34 +++++++-------
Tests/ResetterTest.php | 13 +++---
...asticaToModelTransformerCollectionTest.php | 9 ++--
.../ModelToElasticaAutoTransformerTest.php | 6 +--
.../ElasticaToModelTransformerCollection.php | 4 +-
.../ModelToElasticaAutoTransformer.php | 5 ++-
.../ModelToElasticaTransformerInterface.php | 2 +-
composer.json | 2 +-
28 files changed, 161 insertions(+), 125 deletions(-)
diff --git a/Client.php b/Client.php
index cd30cb2..31384e5 100644
--- a/Client.php
+++ b/Client.php
@@ -2,13 +2,13 @@
namespace FOS\ElasticaBundle;
-use Elastica_Client;
+use Elastica\Client as ElasticaClient;
use FOS\ElasticaBundle\Logger\ElasticaLogger;
/**
* @author Gordon Franke
*/
-class Client extends Elastica_Client
+class Client extends ElasticaClient
{
/**
* @var ElasticaLogger
@@ -20,7 +20,7 @@ class Client extends Elastica_Client
$this->logger = $logger;
}
- public function request($path, $method, $data = array(), array $query = array())
+ public function request($path, $method = Request::GET, $data = array(), array $query = array())
{
$start = microtime(true);
$response = parent::request($path, $method, $data, $query);
diff --git a/Command/SearchCommand.php b/Command/SearchCommand.php
index acf9449..62e3340 100644
--- a/Command/SearchCommand.php
+++ b/Command/SearchCommand.php
@@ -8,8 +8,8 @@ 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;
+use Elastica\Query;
+use Elastica\Result;
/**
* Searches a type
@@ -41,11 +41,11 @@ class SearchCommand extends ContainerAwareCommand
protected function execute(InputInterface $input, OutputInterface $output)
{
$indexName = $input->getOption('index');
- /** @var $index \Elastica_Index */
+ /** @var $index \Elastica\Index */
$index = $this->getContainer()->get('fos_elastica.index_manager')->getIndex($indexName ? $indexName : null);
$type = $index->getType($input->getArgument('type'));
- $query = Elastica_Query::create($input->getArgument('query'));
- $query->setLimit($input->getOption('limit'));
+ $query = Query::create($input->getArgument('query'));
+ $query->setSize($input->getOption('limit'));
if ($input->getOption('explain')) {
$query->setExplain(true);
}
@@ -58,7 +58,7 @@ class SearchCommand extends ContainerAwareCommand
}
}
- protected function formatResult(Elastica_Result $result, $showField, $showSource, $showId, $explain)
+ protected function formatResult(Result $result, $showField, $showSource, $showId, $explain)
{
$source = $result->getSource();
if ($showField) {
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index c68aba5..ba8e9f5 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -37,7 +37,7 @@ class Configuration implements ConfigurationInterface
->arrayNode('serializer')
->treatNullLike(array())
->children()
- ->scalarNode('callback')->defaultValue('foq_elastica.serializer.callback.class')->end()
+ ->scalarNode('callback')->defaultValue('fos_elastica.serializer.callback.class')->end()
->scalarNode('serializer')->defaultValue('serializer')->end()
->end()
->end()
@@ -219,6 +219,7 @@ class Configuration implements ConfigurationInterface
->treatNullLike(array())
->prototype('scalar')->end()
->end()
+ ->scalarNode('version')->end()
->end()
->end()
->scalarNode('index_analyzer')->end()
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index c1d8aa2..8628199 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -189,6 +189,9 @@ class FOSElasticaExtension extends Extension
if (isset($type['serializer']['groups'])) {
$serializerDef->addMethodCall('setGroups', array($type['serializer']['groups']));
}
+ if (isset($type['serializer']['version'])) {
+ $serializerDef->addMethodCall('version', array($type['serializer']['version']));
+ }
$container->setDefinition($serializerId, $serializerDef);
diff --git a/Finder/FinderInterface.php b/Finder/FinderInterface.php
index 2cc0838..4805d58 100644
--- a/Finder/FinderInterface.php
+++ b/Finder/FinderInterface.php
@@ -7,7 +7,7 @@ interface FinderInterface
/**
* Searches for query results within a given limit
*
- * @param mixed $query Can be a string, an array or an Elastica_Query object
+ * @param mixed $query Can be a string, an array or an \Elastica\Query object
* @param int $limit How many results to get
* @return array results
*/
diff --git a/Finder/PaginatedFinderInterface.php b/Finder/PaginatedFinderInterface.php
index e26a048..3581cda 100644
--- a/Finder/PaginatedFinderInterface.php
+++ b/Finder/PaginatedFinderInterface.php
@@ -4,14 +4,14 @@ namespace FOS\ElasticaBundle\Finder;
use FOS\ElasticaBundle\Paginator\PaginatorAdapterInterface;
use Pagerfanta\Pagerfanta;
-use Elastica_Query;
+use Elastica\Query;
interface PaginatedFinderInterface extends FinderInterface
{
/**
* Searches for query results and returns them wrapped in a paginator
*
- * @param mixed $query Can be a string, an array or an Elastica_Query object
+ * @param mixed $query Can be a string, an array or an \Elastica\Query object
* @return Pagerfanta paginated results
*/
function findPaginated($query);
diff --git a/Finder/TransformedFinder.php b/Finder/TransformedFinder.php
index e1eade8..e0b9cd0 100644
--- a/Finder/TransformedFinder.php
+++ b/Finder/TransformedFinder.php
@@ -7,8 +7,8 @@ use FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerInterface;
use FOS\ElasticaBundle\Paginator\TransformedPaginatorAdapter;
use FOS\ElasticaBundle\Paginator\FantaPaginatorAdapter;
use Pagerfanta\Pagerfanta;
-use Elastica_Searchable;
-use Elastica_Query;
+use Elastica\SearchableInterface;
+use Elastica\Query;
/**
* Finds elastica documents and map them to persisted objects
@@ -18,7 +18,7 @@ class TransformedFinder implements PaginatedFinderInterface
protected $searchable;
protected $transformer;
- public function __construct(Elastica_Searchable $searchable, ElasticaToModelTransformerInterface $transformer)
+ public function __construct(SearchableInterface $searchable, ElasticaToModelTransformerInterface $transformer)
{
$this->searchable = $searchable;
$this->transformer = $transformer;
@@ -52,9 +52,9 @@ class TransformedFinder implements PaginatedFinderInterface
*/
protected function search($query, $limit = null)
{
- $queryObject = Elastica_Query::create($query);
+ $queryObject = Query::create($query);
if (null !== $limit) {
- $queryObject->setLimit($limit);
+ $queryObject->setSize($limit);
}
$results = $this->searchable->search($queryObject)->getResults();
@@ -70,7 +70,7 @@ class TransformedFinder implements PaginatedFinderInterface
*/
public function findPaginated($query)
{
- $queryObject = Elastica_Query::create($query);
+ $queryObject = Query::create($query);
$paginatorAdapter = $this->createPaginatorAdapter($queryObject);
return new Pagerfanta(new FantaPaginatorAdapter($paginatorAdapter));
@@ -81,7 +81,7 @@ class TransformedFinder implements PaginatedFinderInterface
*/
public function createPaginatorAdapter($query)
{
- $query = Elastica_Query::create($query);
+ $query = Query::create($query);
return new TransformedPaginatorAdapter($this->searchable, $query, $this->transformer);
}
}
diff --git a/HybridResult.php b/HybridResult.php
index e2b8245..ebd0e99 100644
--- a/HybridResult.php
+++ b/HybridResult.php
@@ -2,14 +2,14 @@
namespace FOS\ElasticaBundle;
-use Elastica_Result;
+use Elastica\Result;
class HybridResult
{
protected $result;
protected $transformed;
- public function __construct(Elastica_Result $result, $transformed = null)
+ public function __construct(Result $result, $transformed = null)
{
$this->result = $result;
$this->transformed = $transformed;
diff --git a/IndexManager.php b/IndexManager.php
index ae844d0..e20a791 100644
--- a/IndexManager.php
+++ b/IndexManager.php
@@ -2,6 +2,8 @@
namespace FOS\ElasticaBundle;
+use Elastica\Index;
+
class IndexManager
{
protected $indexesByName;
@@ -11,9 +13,9 @@ class IndexManager
* Constructor.
*
* @param array $indexesByName
- * @param \Elastica_Index $defaultIndex
+ * @param Index $defaultIndex
*/
- public function __construct(array $indexesByName, \Elastica_Index $defaultIndex)
+ public function __construct(array $indexesByName, Index $defaultIndex)
{
$this->indexesByName = $indexesByName;
$this->defaultIndexName = $defaultIndex->getName();
@@ -33,7 +35,7 @@ class IndexManager
* Gets an index by its name
*
* @param string $name Index to return, or the default index if null
- * @return \Elastica_Index
+ * @return Index
* @throws \InvalidArgumentException if no index exists for the given name
*/
public function getIndex($name = null)
@@ -52,7 +54,7 @@ class IndexManager
/**
* Gets the default index
*
- * @return \Elastica_Index
+ * @return Index
*/
public function getDefaultIndex()
{
diff --git a/Paginator/RawPaginatorAdapter.php b/Paginator/RawPaginatorAdapter.php
index 9a80d39..3ed8638 100644
--- a/Paginator/RawPaginatorAdapter.php
+++ b/Paginator/RawPaginatorAdapter.php
@@ -2,35 +2,35 @@
namespace FOS\ElasticaBundle\Paginator;
-use Elastica_Searchable;
-use Elastica_Query;
-use Elastica_ResultSet;
+use Elastica\SearchableInterface;
+use Elastica\Query;
+use Elastica\ResultSet;
use FOS\ElasticaBundle\Paginator\PaginatorAdapterInterface;
use FOS\ElasticaBundle\Paginator\RawPartialResults;
use FOS\ElasticaBundle\Paginator\PartialResultsInterface;
/**
- * Allows pagination of Elastica_Query. Does not map results
+ * Allows pagination of Elastica\Query. Does not map results
*/
class RawPaginatorAdapter implements PaginatorAdapterInterface
{
/**
- * @var Elastica_Searchable the object to search in
+ * @var SearchableInterface the object to search in
*/
private $searchable = null;
/**
- * @var Elastica_Query the query to search
+ * @var Query the query to search
*/
private $query = null;
/**
* @see PaginatorAdapterInterface::__construct
*
- * @param Elastica_Searchable $searchable the object to search in
- * @param Elastica_Query $query the query to search
+ * @param SearchableInterface $searchable the object to search in
+ * @param Query $query the query to search
*/
- public function __construct(Elastica_Searchable $searchable, Elastica_Query $query)
+ public function __construct(SearchableInterface $searchable, Query $query)
{
$this->searchable = $searchable;
$this->query = $query;
@@ -41,7 +41,7 @@ class RawPaginatorAdapter implements PaginatorAdapterInterface
*
* @param $offset
* @param $itemCountPerPage
- * @return Elastica_ResultSet
+ * @return ResultSet
*/
protected function getElasticaResults($offset, $itemCountPerPage)
{
diff --git a/Paginator/RawPartialResults.php b/Paginator/RawPartialResults.php
index ef1ed6b..270e4cd 100644
--- a/Paginator/RawPartialResults.php
+++ b/Paginator/RawPartialResults.php
@@ -3,8 +3,8 @@
namespace FOS\ElasticaBundle\Paginator;
use FOS\ElasticaBundle\Paginator\PartialResultsInterface;
-use Elastica_ResultSet;
-use Elastica_Result;
+use Elastica\ResultSet;
+use Elastica\Result;
/**
* Raw partial results transforms to a simple array
@@ -14,9 +14,9 @@ class RawPartialResults implements PartialResultsInterface
protected $resultSet;
/**
- * @param \Elastica_ResultSet $resultSet
+ * @param ResultSet $resultSet
*/
- public function __construct(Elastica_ResultSet $resultSet)
+ public function __construct(ResultSet $resultSet)
{
$this->resultSet = $resultSet;
}
@@ -26,7 +26,7 @@ class RawPartialResults implements PartialResultsInterface
*/
public function toArray()
{
- return array_map(function(Elastica_Result $result) {
+ return array_map(function(Result $result) {
return $result->getSource();
}, $this->resultSet->getResults());
}
diff --git a/Paginator/TransformedPaginatorAdapter.php b/Paginator/TransformedPaginatorAdapter.php
index 59a94d0..a668636 100644
--- a/Paginator/TransformedPaginatorAdapter.php
+++ b/Paginator/TransformedPaginatorAdapter.php
@@ -4,22 +4,22 @@ namespace FOS\ElasticaBundle\Paginator;
use FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerInterface;
use FOS\ElasticaBundle\Paginator\TransformedPartialResults;
-use Elastica_Searchable;
-use Elastica_Query;
+use Elastica\SearchableInterface;
+use Elastica\Query;
/**
- * Allows pagination of Elastica_Query
+ * Allows pagination of \Elastica\Query
*/
class TransformedPaginatorAdapter extends RawPaginatorAdapter
{
private $transformer;
/**
- * @param Elastica_Searchable $searchable the object to search in
- * @param Elastica_Query $query the query to search
+ * @param SearchableInterface $searchable the object to search in
+ * @param Query $query the query to search
* @param ElasticaToModelTransformerInterface $transformer the transformer for fetching the results
*/
- public function __construct(Elastica_Searchable $searchable, Elastica_Query $query, ElasticaToModelTransformerInterface $transformer)
+ public function __construct(SearchableInterface $searchable, Query $query, ElasticaToModelTransformerInterface $transformer)
{
parent::__construct($searchable, $query);
diff --git a/Paginator/TransformedPartialResults.php b/Paginator/TransformedPartialResults.php
index 7afd6d4..f7f125a 100644
--- a/Paginator/TransformedPartialResults.php
+++ b/Paginator/TransformedPartialResults.php
@@ -4,7 +4,7 @@ namespace FOS\ElasticaBundle\Paginator;
use FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerInterface;
use FOS\ElasticaBundle\Paginator\RawPartialResults;
-use Elastica_ResultSet;
+use Elastica\ResultSet;
/**
* Partial transformed result set
@@ -14,10 +14,10 @@ class TransformedPartialResults extends RawPartialResults
protected $transformer;
/**
- * @param \Elastica_ResultSet $resultSet
+ * @param ResultSet $resultSet
* @param \FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerInterface $transformer
*/
- public function __construct(Elastica_ResultSet $resultSet, ElasticaToModelTransformerInterface $transformer)
+ public function __construct(ResultSet $resultSet, ElasticaToModelTransformerInterface $transformer)
{
parent::__construct($resultSet);
diff --git a/Persister/ObjectPersister.php b/Persister/ObjectPersister.php
index db94880..643b817 100644
--- a/Persister/ObjectPersister.php
+++ b/Persister/ObjectPersister.php
@@ -3,8 +3,8 @@
namespace FOS\ElasticaBundle\Persister;
use FOS\ElasticaBundle\Transformer\ModelToElasticaTransformerInterface;
-use Elastica_Type;
-use Elastica_Document;
+use Elastica\Type;
+use Elastica\Document;
/**
* Inserts, replaces and deletes single documents in an elastica type
@@ -19,7 +19,7 @@ class ObjectPersister implements ObjectPersisterInterface
protected $objectClass;
protected $fields;
- public function __construct(Elastica_Type $type, ModelToElasticaTransformerInterface $transformer, $objectClass, array $fields)
+ public function __construct(Type $type, ModelToElasticaTransformerInterface $transformer, $objectClass, array $fields)
{
$this->type = $type;
$this->transformer = $transformer;
@@ -95,7 +95,7 @@ class ObjectPersister implements ObjectPersisterInterface
* Transforms an object to an elastica document
*
* @param object $object
- * @return Elastica_Document the elastica document
+ * @return Document the elastica document
*/
public function transformToElasticaDocument($object)
{
diff --git a/Propel/ElasticaToModelTransformer.php b/Propel/ElasticaToModelTransformer.php
index 2678cd6..4f006a7 100644
--- a/Propel/ElasticaToModelTransformer.php
+++ b/Propel/ElasticaToModelTransformer.php
@@ -2,6 +2,7 @@
namespace FOS\ElasticaBundle\Propel;
+use Elastica\Document;
use FOS\ElasticaBundle\HybridResult;
use FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerInterface;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
@@ -65,12 +66,12 @@ class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface
* Transforms an array of elastica objects into an array of
* model objects fetched from the propel repository
*
- * @param \Elastica_Document[] $elasticaObjects array of elastica objects
+ * @param Document[] $elasticaObjects array of elastica objects
* @return array
*/
public function transform(array $elasticaObjects)
{
- $ids = array_map(function(\Elastica_Document $elasticaObject) {
+ $ids = array_map(function(Document $elasticaObject) {
return $elasticaObject->getId();
}, $elasticaObjects);
diff --git a/README.md b/README.md
index 8580481..e3f43ce 100644
--- a/README.md
+++ b/README.md
@@ -64,7 +64,7 @@ Most of the time, you will need only one.
Elastica can handle objects instead of data arrays if a serializer callable is configured
#app/config/config.yml
- foq_elastica:
+ fos_elastica:
clients:
default: { host: localhost, port: 9200 }
serializer:
@@ -73,12 +73,12 @@ Elastica can handle objects instead of data arrays if a serializer callable is c
"callback" is the name of a parameter defining a class having a public method serialize($object). "serializer" is the service id for the
actual serializer, e.g. 'serializer' if you're using the JMSSerializerBundle. If this is configured you can use
-Elastica_Type::addObject instead of Elastica_Type::addDocument to add data to the index.
+\Elastica\Type::addObject instead of \Elastica\Type::addDocument to add data to the index.
The bundle provides a default implementation with a serializer service id 'serializer' that can be turned on by adding
the following line to your config.
#app/config/config.yml
- foq_elastica:
+ fos_elastica:
serializer: ~
#### Declare an index
@@ -98,7 +98,7 @@ Most of the time, you will need only one.
Here we created a "website" index, that uses our "default" client.
-Our index is now available as a service: `fos_elastica.index.website`. It is an instance of `Elastica_Index`.
+Our index is now available as a service: `fos_elastica.index.website`. It is an instance of `\Elastica\Index`.
If you need to have different index name from the service name, for example,
in order to have different indexes for different environments then you can
@@ -136,14 +136,14 @@ Elasticsearch type is comparable to Doctrine entity repository.
lastName: { boost: 3 }
aboutMe: ~
-Our type is now available as a service: `fos_elastica.index.website.user`. It is an instance of `Elastica_Type`.
+Our type is now available as a service: `fos_elastica.index.website.user`. It is an instance of `\Elastica\Type`.
### Declaring serializer groups
If you are using the JMSSerializerBundle for serializing objects passed to elastica you can define serializer groups
per type.
- foq_elastica:
+ fos_elastica:
clients:
default: { host: localhost, port: 9200 }
serializer:
@@ -294,13 +294,14 @@ Its class must implement `FOS\ElasticaBundle\Provider\ProviderInterface`.
namespace Acme\UserBundle\Provider;
use FOS\ElasticaBundle\Provider\ProviderInterface;
- use Elastica_Type;
+ use Elastica\Type;
+ use Elastica\Document;
class UserProvider implements ProviderInterface
{
protected $userType;
- public function __construct(Elastica_Type $userType)
+ public function __construct(Type $userType)
{
$this->userType = $userType;
}
@@ -316,7 +317,7 @@ Its class must implement `FOS\ElasticaBundle\Provider\ProviderInterface`.
$loggerClosure('Indexing users');
}
- $document = new \Elastica_Document();
+ $document = new Document();
$document->setData(array('username' => 'Bob'));
$this->userType->addDocuments(array($document));
}
@@ -328,10 +329,10 @@ You will find a more complete implementation example in `src/FOS/ElasticaBundle/
You can just use the index and type Elastica objects, provided as services, to perform searches.
- /** var Elastica_Type */
+ /** var Elastica\Type */
$userType = $this->container->get('fos_elastica.index.website.user');
- /** var Elastica_ResultSet */
+ /** var Elastica\ResultSet */
$resultSet = $userType->search('bob');
#### Doctrine/Propel finder
@@ -383,7 +384,7 @@ Knp paginator:
$userPaginator = $paginator->paginate($finder->createPaginatorAdapter('bob'));
You can also get both the Elastica results and the entities together from the finder.
-You can then access the score, highlights etc. from the Elastica_Result whilst
+You can then access the score, highlights etc. from the Elastica\Result whilst
still also getting the entity.
/** var array of FOS\ElasticaBundle\HybridResult */
@@ -393,7 +394,7 @@ still also getting the entity.
/** var Acme\UserBundle\Entity\User */
$user = $hybridResult->getTransformed();
- /** var Elastica_Result */
+ /** var Elastica\Result */
$result = $hybridResult->getResult();
}
@@ -628,7 +629,7 @@ Any setting can be specified when declaring a type. For example, to enable a cus
By default, exceptions from the Elastica client library will propagate through
the bundle's Client class. For instance, if the elasticsearch server is offline,
-issuing a request will result in an `Elastica_Exception_Client` being thrown.
+issuing a request will result in an `Elastica\Exception\Connection` being thrown.
Depending on your needs, it may be desirable to suppress these exceptions and
allow searches to fail silently.
@@ -644,14 +645,17 @@ namespace Acme\ElasticaBundle;
use FOS\ElasticaBundle\Client as BaseClient;
+use Elastica\Exception\AbstractException;
+use Elastica\Response;
+
class Client extends BaseClient
{
public function request($path, $method, $data = array())
{
try {
return parent::request($path, $method, $data);
- } catch (\Elastica_Exception_Abstract $e) {
- return new \Elastica_Response('{"took":0,"timed_out":false,"hits":{"total":0,"max_score":0,"hits":[]}}');
+ } catch (AbstractException $e) {
+ return new Response('{"took":0,"timed_out":false,"hits":{"total":0,"max_score":0,"hits":[]}}');
}
}
}
@@ -669,18 +673,18 @@ apply to queries against the `title` field.
```php
$finder = $this->container->get('fos_elastica.finder.website.article');
-$boolQuery = new \Elastica_Query_Bool();
+$boolQuery = new \Elastica\Query\Bool();
-$fieldQuery = new \Elastica_Query_Text();
+$fieldQuery = new \Elastica\Query\Text();
$fieldQuery->setFieldQuery('title', 'I am a title string');
$fieldQuery->setFieldParam('title', 'analyzer', 'my_analyzer');
$boolQuery->addShould($fieldQuery);
-$tagsQuery = new \Elastica_Query_Terms();
+$tagsQuery = new \Elastica\Query\Terms();
$tagsQuery->setTerms('tags', array('tag1', 'tag2'));
$boolQuery->addShould($tagsQuery);
-$categoryQuery = new \Elastica_Query_Terms();
+$categoryQuery = new \Elastica\Query\Terms();
$categoryQuery->setTerms('categoryIds', array('1', '2', '3'));
$boolQuery->addMust($categoryQuery);
diff --git a/Resetter.php b/Resetter.php
index 7614675..7ef2895 100644
--- a/Resetter.php
+++ b/Resetter.php
@@ -2,6 +2,8 @@
namespace FOS\ElasticaBundle;
+use Elastica\Type\Mapping;
+
/**
* Deletes and recreates indexes
*/
@@ -66,11 +68,11 @@ class Resetter
* create type mapping object
*
* @param array $indexConfig
- * @return \Elastica_Type_Mapping
+ * @return Mapping
*/
protected function createMapping($indexConfig)
{
- $mapping = \Elastica_Type_Mapping::create($indexConfig['properties']);
+ $mapping = Mapping::create($indexConfig['properties']);
foreach($indexConfig['properties'] as $type) {
if (!empty($type['_parent']) && $type['_parent'] !== '~') {
diff --git a/Resources/config/config.xml b/Resources/config/config.xml
index f073aeb..7f6351d 100644
--- a/Resources/config/config.xml
+++ b/Resources/config/config.xml
@@ -6,15 +6,15 @@
FOS\ElasticaBundle\Client
- Elastica_Index
- Elastica_Type
+ Elastica\Index
+ Elastica\Type
FOS\ElasticaBundle\Logger\ElasticaLogger
FOS\ElasticaBundle\DataCollector\ElasticaDataCollector
FOS\ElasticaBundle\Manager\RepositoryManager
FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerCollection
FOS\ElasticaBundle\Provider\ProviderRegistry
Symfony\Component\PropertyAccess\PropertyAccessor
- FOQ\ElasticaBundle\Serializer\Callback
+ FOS\ElasticaBundle\Serializer\Callback
diff --git a/Serializer/Callback.php b/Serializer/Callback.php
index fff190d..a563da9 100644
--- a/Serializer/Callback.php
+++ b/Serializer/Callback.php
@@ -1,7 +1,8 @@
serializer = $serializer;
@@ -20,14 +23,31 @@ class Callback
$this->groups = $groups;
}
+ public function setVersion($version)
+ {
+ $this->version = $version;
+ }
+
public function serialize($object)
{
- if ($this->serializer instanceof Serializer) {
- $this->serializer->setGroups($this->groups);
- } elseif ($this->groups) {
- throw new \RuntimeException('Setting serialization groups requires using "JMS\Serializer\Serializer"');
+ $context = $this->serializer instanceof Serializer ? new SerializationContext() : null;
+
+ if ($this->groups) {
+ if (!$context) {
+ throw new \RuntimeException('Setting serialization groups requires using "JMS\Serializer\Serializer"');
+ }
+
+ $context->setGroups($this->groups);
}
- return $this->serializer->serialize($object, 'json');
+ if ($this->version) {
+ if (!$context) {
+ throw new \RuntimeException('Setting serialization version requires using "JMS\Serializer\Serializer"');
+ }
+
+ $context->setVersion($this->version);
+ }
+
+ return $this->serializer->serialize($object, 'json', $context);
}
}
diff --git a/Tests/IndexManagerTest.php b/Tests/IndexManagerTest.php
index 9a03986..0a8ea37 100644
--- a/Tests/IndexManagerTest.php
+++ b/Tests/IndexManagerTest.php
@@ -19,8 +19,8 @@ class IndexManagerTest extends \PHPUnit_Framework_TestCase
'index2' => 'test2',
);
- /** @var $defaultIndex \PHPUnit_Framework_MockObject_MockObject|\Elastica_Index */
- $defaultIndex = $this->getMockBuilder('Elastica_Index')
+ /** @var $defaultIndex \PHPUnit_Framework_MockObject_MockObject|\Elastica\Index */
+ $defaultIndex = $this->getMockBuilder('Elastica\Index')
->disableOriginalConstructor()
->getMock();
diff --git a/Tests/Persister/ObjectPersisterTest.php b/Tests/Persister/ObjectPersisterTest.php
index e672e12..497c286 100644
--- a/Tests/Persister/ObjectPersisterTest.php
+++ b/Tests/Persister/ObjectPersisterTest.php
@@ -33,7 +33,7 @@ class ObjectPersisterTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
- if (!class_exists('Elastica_Type')) {
+ if (!class_exists('Elastica\Type')) {
$this->markTestSkipped('The Elastica library classes are not available');
}
}
@@ -42,8 +42,8 @@ class ObjectPersisterTest extends \PHPUnit_Framework_TestCase
{
$transformer = $this->getTransformer();
- /** @var $typeMock \PHPUnit_Framework_MockObject_MockObject|\Elastica_Type */
- $typeMock = $this->getMockBuilder('Elastica_Type')
+ /** @var $typeMock \PHPUnit_Framework_MockObject_MockObject|\Elastica\Type */
+ $typeMock = $this->getMockBuilder('Elastica\Type')
->disableOriginalConstructor()
->getMock();
$typeMock->expects($this->once())
@@ -65,8 +65,8 @@ class ObjectPersisterTest extends \PHPUnit_Framework_TestCase
{
$transformer = $this->getTransformer();
- /** @var $typeMock \PHPUnit_Framework_MockObject_MockObject|\Elastica_Type */
- $typeMock = $this->getMockBuilder('Elastica_Type')
+ /** @var $typeMock \PHPUnit_Framework_MockObject_MockObject|\Elastica\Type */
+ $typeMock = $this->getMockBuilder('Elastica\Type')
->disableOriginalConstructor()
->getMock();
$typeMock->expects($this->never())
@@ -84,8 +84,8 @@ class ObjectPersisterTest extends \PHPUnit_Framework_TestCase
{
$transformer = $this->getTransformer();
- /** @var $typeMock \PHPUnit_Framework_MockObject_MockObject|\Elastica_Type */
- $typeMock = $this->getMockBuilder('Elastica_Type')
+ /** @var $typeMock \PHPUnit_Framework_MockObject_MockObject|\Elastica\Type */
+ $typeMock = $this->getMockBuilder('Elastica\Type')
->disableOriginalConstructor()
->getMock();
$typeMock->expects($this->never())
@@ -106,8 +106,8 @@ class ObjectPersisterTest extends \PHPUnit_Framework_TestCase
{
$transformer = $this->getTransformer();
- /** @var $typeMock \PHPUnit_Framework_MockObject_MockObject|\Elastica_Type */
- $typeMock = $this->getMockBuilder('Elastica_Type')
+ /** @var $typeMock \PHPUnit_Framework_MockObject_MockObject|\Elastica\Type */
+ $typeMock = $this->getMockBuilder('Elastica\Type')
->disableOriginalConstructor()
->getMock();
$typeMock->expects($this->never())
@@ -125,8 +125,8 @@ class ObjectPersisterTest extends \PHPUnit_Framework_TestCase
{
$transformer = $this->getTransformer();
- /** @var $typeMock \PHPUnit_Framework_MockObject_MockObject|\Elastica_Type */
- $typeMock = $this->getMockBuilder('Elastica_Type')
+ /** @var $typeMock \PHPUnit_Framework_MockObject_MockObject|\Elastica\Type */
+ $typeMock = $this->getMockBuilder('Elastica\Type')
->disableOriginalConstructor()
->getMock();
$typeMock->expects($this->once())
@@ -147,8 +147,8 @@ class ObjectPersisterTest extends \PHPUnit_Framework_TestCase
{
$transformer = $this->getTransformer();
- /** @var $typeMock \PHPUnit_Framework_MockObject_MockObject|\Elastica_Type */
- $typeMock = $this->getMockBuilder('Elastica_Type')
+ /** @var $typeMock \PHPUnit_Framework_MockObject_MockObject|\Elastica\Type */
+ $typeMock = $this->getMockBuilder('Elastica\Type')
->disableOriginalConstructor()
->getMock();
$typeMock->expects($this->never())
@@ -166,8 +166,8 @@ class ObjectPersisterTest extends \PHPUnit_Framework_TestCase
{
$transformer = $this->getTransformer();
- /** @var $typeMock \PHPUnit_Framework_MockObject_MockObject|\Elastica_Type */
- $typeMock = $this->getMockBuilder('Elastica_Type')
+ /** @var $typeMock \PHPUnit_Framework_MockObject_MockObject|\Elastica\Type */
+ $typeMock = $this->getMockBuilder('Elastica\Type')
->disableOriginalConstructor()
->getMock();
$typeMock->expects($this->never())
@@ -190,8 +190,8 @@ class ObjectPersisterTest extends \PHPUnit_Framework_TestCase
{
$transformer = $this->getTransformer();
- /** @var $typeMock \PHPUnit_Framework_MockObject_MockObject|\Elastica_Type */
- $typeMock = $this->getMockBuilder('Elastica_Type')
+ /** @var $typeMock \PHPUnit_Framework_MockObject_MockObject|\Elastica\Type */
+ $typeMock = $this->getMockBuilder('Elastica\Type')
->disableOriginalConstructor()
->getMock();
$typeMock->expects($this->never())
diff --git a/Tests/ResetterTest.php b/Tests/ResetterTest.php
index 61a18a9..1a7190e 100644
--- a/Tests/ResetterTest.php
+++ b/Tests/ResetterTest.php
@@ -3,6 +3,7 @@
namespace FOS\ElasticaBundle\Tests\Resetter;
use FOS\ElasticaBundle\Resetter;
+use Elastica\Type\Mapping;
class ResetterTest extends \PHPUnit_Framework_TestCase
{
@@ -91,7 +92,7 @@ class ResetterTest extends \PHPUnit_Framework_TestCase
$type->expects($this->once())
->method('delete');
- $mapping = \Elastica_Type_Mapping::create($this->indexConfigsByName['foo']['config']['mappings']['a']['properties']);
+ $mapping = Mapping::create($this->indexConfigsByName['foo']['config']['mappings']['a']['properties']);
$type->expects($this->once())
->method('setMapping')
->with($mapping);
@@ -130,7 +131,7 @@ class ResetterTest extends \PHPUnit_Framework_TestCase
$type->expects($this->once())
->method('delete');
- $mapping = \Elastica_Type_Mapping::create($this->indexConfigsByName['parent']['config']['mappings']['a']['properties']);
+ $mapping = Mapping::create($this->indexConfigsByName['parent']['config']['mappings']['a']['properties']);
$mapping->setParam('_parent', array('type' => 'b'));
$type->expects($this->once())
->method('setMapping')
@@ -141,21 +142,21 @@ class ResetterTest extends \PHPUnit_Framework_TestCase
}
/**
- * @return \Elastica_Index
+ * @return \Elastica\Index
*/
private function getMockElasticaIndex()
{
- return $this->getMockBuilder('Elastica_Index')
+ return $this->getMockBuilder('Elastica\Index')
->disableOriginalConstructor()
->getMock();
}
/**
- * @return \Elastica_Type
+ * @return \Elastica\Type
*/
private function getMockElasticaType()
{
- return $this->getMockBuilder('Elastica_Type')
+ return $this->getMockBuilder('Elastica\Type')
->disableOriginalConstructor()
->getMock();
}
diff --git a/Tests/Transformer/ElasticaToModelTransformerCollectionTest.php b/Tests/Transformer/ElasticaToModelTransformerCollectionTest.php
index 2660f07..9b1d782 100644
--- a/Tests/Transformer/ElasticaToModelTransformerCollectionTest.php
+++ b/Tests/Transformer/ElasticaToModelTransformerCollectionTest.php
@@ -2,6 +2,7 @@
namespace FOS\ElasticaBundle\Tests\Transformer;
+use Elastica\Document;
use FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerCollection;
class ElasticaToModelTransformerCollectionTest extends \PHPUnit_Framework_TestCase
@@ -53,8 +54,8 @@ class ElasticaToModelTransformerCollectionTest extends \PHPUnit_Framework_TestCa
{
$this->collectionSetup();
- $document1 = new \Elastica_Document(123, array('data' => 'lots of data'), 'type1');
- $document2 = new \Elastica_Document(124, array('data' => 'not so much data'), 'type2');
+ $document1 = new Document(123, array('data' => 'lots of data'), 'type1');
+ $document2 = new Document(124, array('data' => 'not so much data'), 'type2');
$result1 = new POPO(123, 'lots of data');
$result2 = new POPO2(124, 'not so much data');
@@ -80,8 +81,8 @@ class ElasticaToModelTransformerCollectionTest extends \PHPUnit_Framework_TestCa
{
$this->collectionSetup();
- $document1 = new \Elastica_Document(123, array('data' => 'lots of data'), 'type1');
- $document2 = new \Elastica_Document(124, array('data' => 'not so much data'), 'type1');
+ $document1 = new Document(123, array('data' => 'lots of data'), 'type1');
+ $document2 = new Document(124, array('data' => 'not so much data'), 'type1');
$result1 = new POPO(123, 'lots of data');
$result2 = new POPO2(124, 'not so much data');
diff --git a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
index 5ac13e6..8bfbbae 100644
--- a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
+++ b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
@@ -112,7 +112,7 @@ class ModelToElasticaAutoTransformerTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
- if (!class_exists('Elastica_Document')) {
+ if (!class_exists('Elastica\Document')) {
;
$this->markTestSkipped('The Elastica library classes are not available');
}
@@ -124,7 +124,7 @@ class ModelToElasticaAutoTransformerTest extends \PHPUnit_Framework_TestCase
$document = $transformer->transform(new POPO(), array('name' => array()));
$data = $document->getData();
- $this->assertInstanceOf('Elastica_Document', $document);
+ $this->assertInstanceOf('Elastica\Document', $document);
$this->assertEquals(123, $document->getId());
$this->assertEquals('someName', $data['name']);
}
@@ -143,7 +143,7 @@ class ModelToElasticaAutoTransformerTest extends \PHPUnit_Framework_TestCase
);
$data = $document->getData();
- $this->assertInstanceOf('Elastica_Document', $document);
+ $this->assertInstanceOf('Elastica\Document', $document);
$this->assertEquals(123, $document->getId());
$this->assertEquals('someName', $data['name']);
$this->assertEquals(7.2, $data['float']);
diff --git a/Transformer/ElasticaToModelTransformerCollection.php b/Transformer/ElasticaToModelTransformerCollection.php
index 8f750c5..6264959 100644
--- a/Transformer/ElasticaToModelTransformerCollection.php
+++ b/Transformer/ElasticaToModelTransformerCollection.php
@@ -3,7 +3,7 @@
namespace FOS\ElasticaBundle\Transformer;
use FOS\ElasticaBundle\HybridResult;
-use Elastica_Document;
+use Elastica\Document;
/**
* Holds a collection of transformers for an index wide transformation.
@@ -40,7 +40,7 @@ class ElasticaToModelTransformerCollection implements ElasticaToModelTransformer
}
/**
- * @param Elastica_Document[] $elasticaObjects
+ * @param Document[] $elasticaObjects
* @return array
*/
public function transform(array $elasticaObjects)
diff --git a/Transformer/ModelToElasticaAutoTransformer.php b/Transformer/ModelToElasticaAutoTransformer.php
index ad20529..38bd065 100644
--- a/Transformer/ModelToElasticaAutoTransformer.php
+++ b/Transformer/ModelToElasticaAutoTransformer.php
@@ -3,6 +3,7 @@
namespace FOS\ElasticaBundle\Transformer;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
+use Elastica\Document;
/**
* Maps Elastica documents with Doctrine objects
@@ -53,12 +54,12 @@ class ModelToElasticaAutoTransformer implements ModelToElasticaTransformerInterf
* @param object $object the object to convert
* @param array $fields the keys we want to have in the returned array
*
- * @return \Elastica_Document
+ * @return Document
**/
public function transform($object, array $fields)
{
$identifier = $this->propertyAccessor->getValue($object, $this->options['identifier']);
- $document = new \Elastica_Document($identifier);
+ $document = new Document($identifier);
foreach ($fields as $key => $mapping) {
$value = $this->propertyAccessor->getValue($object, $key);
diff --git a/Transformer/ModelToElasticaTransformerInterface.php b/Transformer/ModelToElasticaTransformerInterface.php
index 924bc7c..ec9ada3 100644
--- a/Transformer/ModelToElasticaTransformerInterface.php
+++ b/Transformer/ModelToElasticaTransformerInterface.php
@@ -12,7 +12,7 @@ interface ModelToElasticaTransformerInterface
*
* @param object $object the object to convert
* @param array $fields the keys we want to have in the returned array
- * @return \Elastica_Document
+ * @return \Elastica\Document
**/
function transform($object, array $fields);
}
diff --git a/composer.json b/composer.json
index b1be5fa..bbd502f 100644
--- a/composer.json
+++ b/composer.json
@@ -16,7 +16,7 @@
"symfony/console": ">=2.1.0,<2.3.0-dev",
"symfony/form": ">=2.1.0,<2.3.0-dev",
"symfony/property-access": "2.2.*",
- "ruflin/elastica": "0.19.8"
+ "ruflin/elastica": "dev-master"
},
"require-dev":{
"doctrine/orm": ">=2.2,<2.5-dev",
From 965ee39c5a67497bea59513eda5fc89dff4f3166 Mon Sep 17 00:00:00 2001
From: Lukas Kahwe Smith
Date: Mon, 22 Apr 2013 16:08:21 +0200
Subject: [PATCH 015/447] typo fix
---
README.md | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/README.md b/README.md
index e3f43ce..02c600f 100644
--- a/README.md
+++ b/README.md
@@ -90,7 +90,7 @@ Most of the time, you will need only one.
clients:
default: { host: localhost, port: 9200 }
serializer:
- callable_class: %classname%
+ callback: %classname%
id: serializer
indexes:
website:
@@ -123,7 +123,7 @@ Elasticsearch type is comparable to Doctrine entity repository.
clients:
default: { host: localhost, port: 9200 }
serializer:
- callable_class: %classname%
+ callback: %classname%
id: serializer
indexes:
website:
@@ -147,7 +147,7 @@ per type.
clients:
default: { host: localhost, port: 9200 }
serializer:
- callable_class: %classname%
+ callback: %classname%
id: serializer
indexes:
website:
@@ -168,7 +168,7 @@ per type.
clients:
default: { host: localhost, port: 9200 }
serializer:
- callable_class: %classname%
+ callback: %classname%
id: serializer
indexes:
website:
@@ -186,7 +186,7 @@ per type.
clients:
default: { host: localhost, port: 9200 }
serializer:
- callable_class: %classname%
+ callback: %classname%
id: serializer
indexes:
website:
@@ -224,7 +224,7 @@ some configuration will let ElasticaBundle do it for us.
clients:
default: { host: localhost, port: 9200 }
serializer:
- callable_class: %classname%
+ callback: %classname%
id: serializer
indexes:
website:
@@ -345,7 +345,7 @@ Declare that you want a Doctrine/Propel finder in your configuration:
clients:
default: { host: localhost, port: 9200 }
serializer:
- callable_class: %classname%
+ callback: %classname%
id: serializer
indexes:
website:
From 8a9a9686babbff82320fd8e249d5d6f2719e6de5 Mon Sep 17 00:00:00 2001
From: Lukas Kahwe Smith
Date: Mon, 22 Apr 2013 17:00:26 +0200
Subject: [PATCH 016/447] various tweaks
---
DependencyInjection/FOSElasticaExtension.php | 2 +-
README.md | 10 +++++-----
Serializer/Callback.php | 4 ++--
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 8628199..e67ba53 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -190,7 +190,7 @@ class FOSElasticaExtension extends Extension
$serializerDef->addMethodCall('setGroups', array($type['serializer']['groups']));
}
if (isset($type['serializer']['version'])) {
- $serializerDef->addMethodCall('version', array($type['serializer']['version']));
+ $serializerDef->addMethodCall('setVersion', array($type['serializer']['version']));
}
$container->setDefinition($serializerId, $serializerDef);
diff --git a/README.md b/README.md
index 02c600f..87b01aa 100644
--- a/README.md
+++ b/README.md
@@ -71,11 +71,11 @@ Elastica can handle objects instead of data arrays if a serializer callable is c
callback: callback
serializer: serializer
-"callback" is the name of a parameter defining a class having a public method serialize($object). "serializer" is the service id for the
-actual serializer, e.g. 'serializer' if you're using the JMSSerializerBundle. If this is configured you can use
-\Elastica\Type::addObject instead of \Elastica\Type::addDocument to add data to the index.
-The bundle provides a default implementation with a serializer service id 'serializer' that can be turned on by adding
-the following line to your config.
+``callback`` is the name of a parameter defining a class having a public method serialize($object).
+``serializer`` is the service id for the actual serializer, e.g. ``serializer`` if you're using
+JMSSerializerBundle. If this is configured you can use ``\Elastica\Type::addObject`` instead of
+``\Elastica\Type::addDocument`` to add data to the index. The bundle provides a default implementation
+with a serializer service id 'serializer' that can be turned on by adding the following line to your config.
#app/config/config.yml
fos_elastica:
diff --git a/Serializer/Callback.php b/Serializer/Callback.php
index a563da9..fbf391e 100644
--- a/Serializer/Callback.php
+++ b/Serializer/Callback.php
@@ -3,7 +3,7 @@
namespace FOS\ElasticaBundle\Serializer;
use JMS\Serializer\SerializationContext;
-use JMS\Serializer\Serializer;
+use JMS\Serializer\SerializerInterface;
class Callback
{
@@ -30,7 +30,7 @@ class Callback
public function serialize($object)
{
- $context = $this->serializer instanceof Serializer ? new SerializationContext() : null;
+ $context = $this->serializer instanceof SerializerInterface ? new SerializationContext() : array();
if ($this->groups) {
if (!$context) {
From 800e38f8aa9666860440f9eab1d622d04b0c3725 Mon Sep 17 00:00:00 2001
From: Lukas Kahwe Smith
Date: Mon, 22 Apr 2013 20:02:12 +0200
Subject: [PATCH 017/447] tweaked the callback handling
---
DependencyInjection/Configuration.php | 2 +-
DependencyInjection/FOSElasticaExtension.php | 17 +++++----
README.md | 36 +++++++++++---------
Serializer/Callback.php | 23 ++++++++-----
4 files changed, 43 insertions(+), 35 deletions(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index ba8e9f5..966f04f 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -37,7 +37,7 @@ class Configuration implements ConfigurationInterface
->arrayNode('serializer')
->treatNullLike(array())
->children()
- ->scalarNode('callback')->defaultValue('fos_elastica.serializer.callback.class')->end()
+ ->scalarNode('callback_class')->defaultValue('FOS\ElasticaBundle\Serializer\Callback')->end()
->scalarNode('serializer')->defaultValue('serializer')->end()
->end()
->end()
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index e67ba53..3f757df 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -180,22 +180,21 @@ class FOSElasticaExtension extends Extension
$typeDef->setFactoryService($indexId);
$typeDef->setFactoryMethod('getType');
if ($serializerConfig) {
+ $callbackDef = new Definition($serializerConfig['callback_class']);
+ $callbackId = sprintf('%s.%s.serializer.callback', $indexId, $name);
- $serializerDef = new Definition("%{$serializerConfig['callback']}%");
- $serializerId = sprintf('%s.%s.serializer.callback', $indexId, $name);
-
- $typeDef->addMethodCall('setSerializer', array(array(new Reference($serializerId), 'serialize')));
- $serializerDef->addMethodCall('setSerializer', array(new Reference($serializerConfig['serializer'])));
+ $typeDef->addMethodCall('setSerializer', array(array(new Reference($callbackId), 'serialize')));
+ $callbackDef->addMethodCall('setSerializer', array(new Reference($serializerConfig['serializer'])));
if (isset($type['serializer']['groups'])) {
- $serializerDef->addMethodCall('setGroups', array($type['serializer']['groups']));
+ $callbackDef->addMethodCall('setGroups', array($type['serializer']['groups']));
}
if (isset($type['serializer']['version'])) {
- $serializerDef->addMethodCall('setVersion', array($type['serializer']['version']));
+ $callbackDef->addMethodCall('setVersion', array($type['serializer']['version']));
}
- $container->setDefinition($serializerId, $serializerDef);
+ $container->setDefinition($callbackId, $callbackDef);
- $typeDef->addMethodCall('setSerializer', array(array(new Reference($serializerId), 'serialize')));
+ $typeDef->addMethodCall('setSerializer', array(array(new Reference($callbackId), 'serialize')));
}
$container->setDefinition($typeId, $typeDef);
if (isset($type['_source'])) {
diff --git a/README.md b/README.md
index 87b01aa..a0acec2 100644
--- a/README.md
+++ b/README.md
@@ -68,10 +68,12 @@ Elastica can handle objects instead of data arrays if a serializer callable is c
clients:
default: { host: localhost, port: 9200 }
serializer:
- callback: callback
+ callback_class: callback_class
serializer: serializer
-``callback`` is the name of a parameter defining a class having a public method serialize($object).
+``callback_class`` is the name of a class having a public method serialize($object) and should
+extends from ``FOS\ElasticaBundle\Serializer\Callback``.
+
``serializer`` is the service id for the actual serializer, e.g. ``serializer`` if you're using
JMSSerializerBundle. If this is configured you can use ``\Elastica\Type::addObject`` instead of
``\Elastica\Type::addDocument`` to add data to the index. The bundle provides a default implementation
@@ -90,7 +92,7 @@ Most of the time, you will need only one.
clients:
default: { host: localhost, port: 9200 }
serializer:
- callback: %classname%
+ callback_class: FOS\ElasticaBundle\Serializer\Callback
id: serializer
indexes:
website:
@@ -123,7 +125,7 @@ Elasticsearch type is comparable to Doctrine entity repository.
clients:
default: { host: localhost, port: 9200 }
serializer:
- callback: %classname%
+ callback_class: FOS\ElasticaBundle\Serializer\Callback
id: serializer
indexes:
website:
@@ -147,7 +149,7 @@ per type.
clients:
default: { host: localhost, port: 9200 }
serializer:
- callback: %classname%
+ callback_class: %classname%
id: serializer
indexes:
website:
@@ -168,7 +170,7 @@ per type.
clients:
default: { host: localhost, port: 9200 }
serializer:
- callback: %classname%
+ callback_class_class: FOS\ElasticaBundle\Serializer\Callback
id: serializer
indexes:
website:
@@ -186,7 +188,7 @@ per type.
clients:
default: { host: localhost, port: 9200 }
serializer:
- callback: %classname%
+ callback_class: FOS\ElasticaBundle\Serializer\Callback
id: serializer
indexes:
website:
@@ -224,7 +226,7 @@ some configuration will let ElasticaBundle do it for us.
clients:
default: { host: localhost, port: 9200 }
serializer:
- callback: %classname%
+ callback_class: FOS\ElasticaBundle\Serializer\Callback
id: serializer
indexes:
website:
@@ -345,7 +347,7 @@ Declare that you want a Doctrine/Propel finder in your configuration:
clients:
default: { host: localhost, port: 9200 }
serializer:
- callback: %classname%
+ callback_class: FOS\ElasticaBundle\Serializer\Callback
id: serializer
indexes:
website:
@@ -575,28 +577,28 @@ You can also choose to only listen for some of the events:
If you use listeners to update your index, you may need to validate your
entities before you index them (e.g. only index "public" entities). Typically,
you'll want the listener to be consistent with the provider's query criteria.
-This may be achieved by using the `is_indexable_callback` config parameter:
+This may be achieved by using the `is_indexable_callback_class` config parameter:
persistence:
listener:
- is_indexable_callback: "isPublic"
+ is_indexable_callback_class: "isPublic"
-If `is_indexable_callback` is a string and the entity has a method with the
+If `is_indexable_callback_class` is a string and the entity has a method with the
specified name, the listener will only index entities for which the method
returns `true`. Additionally, you may provide a service and method name pair:
persistence:
listener:
- is_indexable_callback: [ "%custom_service_id%", "isIndexable" ]
+ is_indexable_callback_class: [ "%custom_service_id%", "isIndexable" ]
-In this case, the callback will be the `isIndexable()` method on the specified
+In this case, the callback_class will be the `isIndexable()` method on the specified
service and the object being considered for indexing will be passed as the only
argument. This allows you to do more complex validation (e.g. ACL checks).
-As you might expect, new entities will only be indexed if the callback returns
+As you might expect, new entities will only be indexed if the callback_class returns
`true`. Additionally, modified entities will be updated or removed from the
-index depending on whether the callback returns `true` or `false`, respectively.
-The delete listener disregards the callback.
+index depending on whether the callback_class returns `true` or `false`, respectively.
+The delete listener disregards the callback_class.
> **Propel** doesn't support this feature yet.
diff --git a/Serializer/Callback.php b/Serializer/Callback.php
index fbf391e..50307e0 100644
--- a/Serializer/Callback.php
+++ b/Serializer/Callback.php
@@ -16,16 +16,31 @@ class Callback
public function setSerializer($serializer)
{
$this->serializer = $serializer;
+ if (!method_exists($this->serializer, 'serialize')) {
+ throw new \RuntimeException('The serializer must have a "serialize" method.');
+ }
}
public function setGroups(array $groups)
{
$this->groups = $groups;
+
+ if ($this->groups) {
+ if (!$this->serializer instanceof SerializerInterface) {
+ throw new \RuntimeException('Setting serialization groups requires using "JMS\Serializer\Serializer".');
+ }
+ }
}
public function setVersion($version)
{
$this->version = $version;
+
+ if ($this->version) {
+ if (!$this->serializer instanceof SerializerInterface) {
+ throw new \RuntimeException('Setting serialization version requires using "JMS\Serializer\Serializer".');
+ }
+ }
}
public function serialize($object)
@@ -33,18 +48,10 @@ class Callback
$context = $this->serializer instanceof SerializerInterface ? new SerializationContext() : array();
if ($this->groups) {
- if (!$context) {
- throw new \RuntimeException('Setting serialization groups requires using "JMS\Serializer\Serializer"');
- }
-
$context->setGroups($this->groups);
}
if ($this->version) {
- if (!$context) {
- throw new \RuntimeException('Setting serialization version requires using "JMS\Serializer\Serializer"');
- }
-
$context->setVersion($this->version);
}
From 0af8f6ce199c89e9e4de852c0d2208f9a1eaa12d Mon Sep 17 00:00:00 2001
From: Lukas Kahwe Smith
Date: Wed, 24 Apr 2013 09:02:33 +0200
Subject: [PATCH 018/447] updated for Elastica master changes
---
README.md | 4 ++--
composer.json | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index a0acec2..822cf3f 100644
--- a/README.md
+++ b/README.md
@@ -647,7 +647,7 @@ namespace Acme\ElasticaBundle;
use FOS\ElasticaBundle\Client as BaseClient;
-use Elastica\Exception\AbstractException;
+use Elastica\Exception\ExceptionInterface;
use Elastica\Response;
class Client extends BaseClient
@@ -656,7 +656,7 @@ class Client extends BaseClient
{
try {
return parent::request($path, $method, $data);
- } catch (AbstractException $e) {
+ } catch (ExceptionInterface $e) {
return new Response('{"took":0,"timed_out":false,"hits":{"total":0,"max_score":0,"hits":[]}}');
}
}
diff --git a/composer.json b/composer.json
index bbd502f..701cfde 100644
--- a/composer.json
+++ b/composer.json
@@ -16,7 +16,7 @@
"symfony/console": ">=2.1.0,<2.3.0-dev",
"symfony/form": ">=2.1.0,<2.3.0-dev",
"symfony/property-access": "2.2.*",
- "ruflin/elastica": "dev-master"
+ "ruflin/elastica": "0.20.5.0.*@dev"
},
"require-dev":{
"doctrine/orm": ">=2.2,<2.5-dev",
@@ -38,7 +38,7 @@
"target-dir": "FOS/ElasticaBundle",
"extra": {
"branch-alias": {
- "dev-master": "2.1.x-dev"
+ "dev-master": "3.0.x-dev"
}
}
}
From c35cb1b25f333de990ec0e3d2d454eea55b762f9 Mon Sep 17 00:00:00 2001
From: Lukas Kahwe Smith
Date: Wed, 24 Apr 2013 10:02:41 +0200
Subject: [PATCH 019/447] fixed Elastica dependency
---
composer.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/composer.json b/composer.json
index 701cfde..69edc36 100644
--- a/composer.json
+++ b/composer.json
@@ -16,7 +16,7 @@
"symfony/console": ">=2.1.0,<2.3.0-dev",
"symfony/form": ">=2.1.0,<2.3.0-dev",
"symfony/property-access": "2.2.*",
- "ruflin/elastica": "0.20.5.0.*@dev"
+ "ruflin/elastica": "0.20.5.*@dev"
},
"require-dev":{
"doctrine/orm": ">=2.2,<2.5-dev",
From e898deb6df0accc4a9f994f480fb90ea5fa99780 Mon Sep 17 00:00:00 2001
From: Lukas Kahwe Smith
Date: Fri, 26 Apr 2013 14:12:28 +0200
Subject: [PATCH 020/447] cleanups
---
Resources/config/config.xml | 3 ---
1 file changed, 3 deletions(-)
diff --git a/Resources/config/config.xml b/Resources/config/config.xml
index 7f6351d..cd91961 100644
--- a/Resources/config/config.xml
+++ b/Resources/config/config.xml
@@ -14,7 +14,6 @@
FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerCollection
FOS\ElasticaBundle\Provider\ProviderRegistry
Symfony\Component\PropertyAccess\PropertyAccessor
- FOS\ElasticaBundle\Serializer\Callback
@@ -79,8 +78,6 @@
-
-
From 813f57e3d06a58abea9605bb297f199682f86b3e Mon Sep 17 00:00:00 2001
From: Lukas Kahwe Smith
Date: Fri, 26 Apr 2013 14:15:57 +0200
Subject: [PATCH 021/447] added purge command
---
Command/PurgeCommand.php | 78 ++++++++++++++++++++++++++++++++++
Doctrine/RepositoryManager.php | 2 +-
Manager/RepositoryManager.php | 2 +-
Repository.php | 2 +-
4 files changed, 81 insertions(+), 3 deletions(-)
create mode 100755 Command/PurgeCommand.php
diff --git a/Command/PurgeCommand.php b/Command/PurgeCommand.php
new file mode 100755
index 0000000..3f5fa00
--- /dev/null
+++ b/Command/PurgeCommand.php
@@ -0,0 +1,78 @@
+setName('fos:elastica:purge')
+ ->addOption('index', null, InputOption::VALUE_OPTIONAL, 'The index to purge')
+ ->addOption('type', null, InputOption::VALUE_OPTIONAL, 'The type to purge')
+ ->setDescription('Purge search indexes')
+ ;
+ }
+
+ /**
+ * @see Symfony\Component\Console\Command\Command::initialize()
+ */
+ protected function initialize(InputInterface $input, OutputInterface $output)
+ {
+ $this->indexManager = $this->getContainer()->get('fos_elastica.index_manager');
+ $this->resetter = $this->getContainer()->get('fos_elastica.resetter');
+ }
+
+ /**
+ * @see Symfony\Component\Console\Command\Command::execute()
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $index = $input->getOption('index');
+ $type = $input->getOption('type');
+
+ if (null === $index && null !== $type) {
+ throw new \InvalidArgumentException('Cannot specify type option without an index.');
+ }
+
+ if (null !== $type) {
+ $output->writeln(sprintf('Resetting: %s/%s', $index, $type));
+ $this->resetter->resetIndex($index, $type);
+ } else {
+ $indexes = null === $index
+ ? array_keys($this->indexManager->getAllIndexes())
+ : array($index)
+ ;
+
+ foreach ($indexes as $index) {
+ $output->writeln(sprintf('Resetting %s', $index));
+ $this->resetter->resetIndex($index);
+ }
+ }
+ }
+}
diff --git a/Doctrine/RepositoryManager.php b/Doctrine/RepositoryManager.php
index 8224ffb..6ba6bf5 100644
--- a/Doctrine/RepositoryManager.php
+++ b/Doctrine/RepositoryManager.php
@@ -28,7 +28,7 @@ class RepositoryManager extends BaseManager
* Return repository for entity
*
* Returns custom repository if one specified otherwise
- * returns a basic respository.
+ * returns a basic repository.
*/
public function getRepository($entityName)
{
diff --git a/Manager/RepositoryManager.php b/Manager/RepositoryManager.php
index 7701ec9..6459c19 100644
--- a/Manager/RepositoryManager.php
+++ b/Manager/RepositoryManager.php
@@ -33,7 +33,7 @@ class RepositoryManager implements RepositoryManagerInterface
* Return repository for entity
*
* Returns custom repository if one specified otherwise
- * returns a basic respository.
+ * returns a basic repository.
*/
public function getRepository($entityName)
{
diff --git a/Repository.php b/Repository.php
index dde07c6..413f1e4 100644
--- a/Repository.php
+++ b/Repository.php
@@ -7,7 +7,7 @@ use FOS\ElasticaBundle\Finder\PaginatedFinderInterface;
/**
* @author Richard Miller
*
- * Basic respoitory to be extended to hold custom queries to be run
+ * Basic repository to be extended to hold custom queries to be run
* in the finder.
*/
class Repository
From b204f5bf5f416f5dc2d45c7bf44bd5923c0142ad Mon Sep 17 00:00:00 2001
From: Tom Corrigan
Date: Fri, 3 May 2013 01:01:29 +1000
Subject: [PATCH 022/447] Allow symfony >= 2.3
This required a small tweak to the tests as
Symfony\Component\PropertyAccess\Exception\PropertyAccessDeniedException
has been removed in 2.3
---
Tests/Transformer/ModelToElasticaAutoTransformerTest.php | 2 +-
composer.json | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
index 8bfbbae..1c8905b 100644
--- a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
+++ b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
@@ -203,7 +203,7 @@ class ModelToElasticaAutoTransformerTest extends \PHPUnit_Framework_TestCase
public function testThatCannotTransformObjectWhenGetterDoesNotExistForPrivateMethod()
{
- $this->setExpectedException('Symfony\Component\PropertyAccess\Exception\PropertyAccessDeniedException');
+ $this->setExpectedException('Symfony\Component\PropertyAccess\Exception\ExceptionInterface');
$transformer = $this->getTransformer();
$transformer->transform(new POPO(), array('desc' => array()));
diff --git a/composer.json b/composer.json
index 69edc36..1f7098b 100644
--- a/composer.json
+++ b/composer.json
@@ -12,10 +12,10 @@
],
"require": {
"php": ">=5.3.2",
- "symfony/framework-bundle": ">=2.1.0,<2.3.0-dev",
- "symfony/console": ">=2.1.0,<2.3.0-dev",
- "symfony/form": ">=2.1.0,<2.3.0-dev",
- "symfony/property-access": "2.2.*",
+ "symfony/framework-bundle": "~2.1",
+ "symfony/console": "~2.1",
+ "symfony/form": "~2.1",
+ "symfony/property-access": "~2.2",
"ruflin/elastica": "0.20.5.*@dev"
},
"require-dev":{
From ee6f3cb04d8f3678596ed9557d7dd1e1b2265072 Mon Sep 17 00:00:00 2001
From: Jeremy Mikola
Date: Thu, 2 May 2013 11:24:27 -0400
Subject: [PATCH 023/447] Expect a more specific PropertyAccess exception
RuntimeException is the nearest common ancestor of the PropertyAccessDeniedException (removed in 2.3) and NoSuchPropertyException.
See: symfony/symfony@2a666cb7c3ecbaa6226e5a9da0476b10b6e997db
---
Tests/Transformer/ModelToElasticaAutoTransformerTest.php | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
index 1c8905b..cbcb6bd 100644
--- a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
+++ b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
@@ -201,10 +201,11 @@ class ModelToElasticaAutoTransformerTest extends \PHPUnit_Framework_TestCase
$this->assertTrue(array_key_exists('nullValue', $data));
}
+ /**
+ * @expectedException Symfony\Component\PropertyAccess\Exception\RuntimeException
+ */
public function testThatCannotTransformObjectWhenGetterDoesNotExistForPrivateMethod()
{
- $this->setExpectedException('Symfony\Component\PropertyAccess\Exception\ExceptionInterface');
-
$transformer = $this->getTransformer();
$transformer->transform(new POPO(), array('desc' => array()));
}
From 4ffc499c66e5ba721abfe40ee5530b7517a458d0 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Fri, 3 May 2013 11:20:44 +1000
Subject: [PATCH 024/447] Saner version constraints
---
composer.json | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/composer.json b/composer.json
index 1f7098b..7b54d57 100644
--- a/composer.json
+++ b/composer.json
@@ -12,10 +12,10 @@
],
"require": {
"php": ">=5.3.2",
- "symfony/framework-bundle": "~2.1",
- "symfony/console": "~2.1",
- "symfony/form": "~2.1",
- "symfony/property-access": "~2.2",
+ "symfony/framework-bundle": ">=2.1,<2.4-dev",
+ "symfony/console": ">=2.1,<2.4-dev",
+ "symfony/form": ">=2.1,<2.4-dev",
+ "symfony/property-access": ">=2.2,<2.4-dev",
"ruflin/elastica": "0.20.5.*@dev"
},
"require-dev":{
From f48ae85cc88e58c3e649b8d12caf34612dc56a28 Mon Sep 17 00:00:00 2001
From: Lukas Kahwe Smith
Date: Mon, 6 May 2013 10:32:50 +0200
Subject: [PATCH 025/447] added missing use statement
---
Client.php | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Client.php b/Client.php
index 31384e5..27cff7f 100644
--- a/Client.php
+++ b/Client.php
@@ -3,6 +3,8 @@
namespace FOS\ElasticaBundle;
use Elastica\Client as ElasticaClient;
+use Elastica\Request;
+
use FOS\ElasticaBundle\Logger\ElasticaLogger;
/**
From b8a4a47b38ae840970329ede869f7fe5ab32e210 Mon Sep 17 00:00:00 2001
From: Lukas Kahwe Smith
Date: Wed, 8 May 2013 09:10:40 +0200
Subject: [PATCH 026/447] renamed PurgeCommand to ResetCommand
---
Command/{PurgeCommand.php => ResetCommand.php} | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
rename Command/{PurgeCommand.php => ResetCommand.php} (90%)
diff --git a/Command/PurgeCommand.php b/Command/ResetCommand.php
similarity index 90%
rename from Command/PurgeCommand.php
rename to Command/ResetCommand.php
index 3f5fa00..f223d63 100755
--- a/Command/PurgeCommand.php
+++ b/Command/ResetCommand.php
@@ -12,9 +12,9 @@ use FOS\ElasticaBundle\IndexManager;
use FOS\ElasticaBundle\Resetter;
/**
- * Purge search indexes
+ * Reset search indexes
*/
-class PurgeCommand extends ContainerAwareCommand
+class ResetCommand extends ContainerAwareCommand
{
/**
* @var IndexManager
@@ -32,10 +32,10 @@ class PurgeCommand extends ContainerAwareCommand
protected function configure()
{
$this
- ->setName('fos:elastica:purge')
- ->addOption('index', null, InputOption::VALUE_OPTIONAL, 'The index to purge')
- ->addOption('type', null, InputOption::VALUE_OPTIONAL, 'The type to purge')
- ->setDescription('Purge search indexes')
+ ->setName('fos:elastica:reset')
+ ->addOption('index', null, InputOption::VALUE_OPTIONAL, 'The index to reset')
+ ->addOption('type', null, InputOption::VALUE_OPTIONAL, 'The type to reset')
+ ->setDescription('Reset search indexes')
;
}
From 23dfd3f595a9d9d6e93e2dff9fac1bc3a5541aaa Mon Sep 17 00:00:00 2001
From: Arne Stockmans
Date: Wed, 8 May 2013 14:29:22 +0200
Subject: [PATCH 027/447] Renamed is_indexable_callback_class back to
is_indexable_callback
---
README.md | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index 822cf3f..5fec319 100644
--- a/README.md
+++ b/README.md
@@ -577,19 +577,19 @@ You can also choose to only listen for some of the events:
If you use listeners to update your index, you may need to validate your
entities before you index them (e.g. only index "public" entities). Typically,
you'll want the listener to be consistent with the provider's query criteria.
-This may be achieved by using the `is_indexable_callback_class` config parameter:
+This may be achieved by using the `is_indexable_callback` config parameter:
persistence:
listener:
- is_indexable_callback_class: "isPublic"
+ is_indexable_callback: "isPublic"
-If `is_indexable_callback_class` is a string and the entity has a method with the
+If `is_indexable_callback` is a string and the entity has a method with the
specified name, the listener will only index entities for which the method
returns `true`. Additionally, you may provide a service and method name pair:
persistence:
listener:
- is_indexable_callback_class: [ "%custom_service_id%", "isIndexable" ]
+ is_indexable_callback: [ "%custom_service_id%", "isIndexable" ]
In this case, the callback_class will be the `isIndexable()` method on the specified
service and the object being considered for indexing will be passed as the only
From d6e8134189971e03cba66442ccd703f977b65b36 Mon Sep 17 00:00:00 2001
From: Philipp Wahala
Date: Wed, 15 May 2013 15:56:21 +0200
Subject: [PATCH 028/447] Correct serializer configuration in README
---
README.md | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/README.md b/README.md
index 822cf3f..43cf4b1 100644
--- a/README.md
+++ b/README.md
@@ -93,7 +93,7 @@ Most of the time, you will need only one.
default: { host: localhost, port: 9200 }
serializer:
callback_class: FOS\ElasticaBundle\Serializer\Callback
- id: serializer
+ serializer: serializer
indexes:
website:
client: default
@@ -126,7 +126,7 @@ Elasticsearch type is comparable to Doctrine entity repository.
default: { host: localhost, port: 9200 }
serializer:
callback_class: FOS\ElasticaBundle\Serializer\Callback
- id: serializer
+ serializer: serializer
indexes:
website:
client: default
@@ -150,7 +150,7 @@ per type.
default: { host: localhost, port: 9200 }
serializer:
callback_class: %classname%
- id: serializer
+ serializer: serializer
indexes:
website:
client: default
@@ -170,8 +170,8 @@ per type.
clients:
default: { host: localhost, port: 9200 }
serializer:
- callback_class_class: FOS\ElasticaBundle\Serializer\Callback
- id: serializer
+ callback_class: FOS\ElasticaBundle\Serializer\Callback
+ serializer: serializer
indexes:
website:
client: default
@@ -189,7 +189,7 @@ per type.
default: { host: localhost, port: 9200 }
serializer:
callback_class: FOS\ElasticaBundle\Serializer\Callback
- id: serializer
+ serializer: serializer
indexes:
website:
client: default
@@ -227,7 +227,7 @@ some configuration will let ElasticaBundle do it for us.
default: { host: localhost, port: 9200 }
serializer:
callback_class: FOS\ElasticaBundle\Serializer\Callback
- id: serializer
+ serializer: serializer
indexes:
website:
client: default
@@ -348,7 +348,7 @@ Declare that you want a Doctrine/Propel finder in your configuration:
default: { host: localhost, port: 9200 }
serializer:
callback_class: FOS\ElasticaBundle\Serializer\Callback
- id: serializer
+ serializer: serializer
indexes:
website:
client: default
From 00b67fd8a4e10c132bb3ed7a82d40169bd420ab4 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Thu, 18 Apr 2013 10:01:34 +1000
Subject: [PATCH 029/447] Ignore missing index hits
---
DependencyInjection/Configuration.php | 2 ++
DependencyInjection/FOSElasticaExtension.php | 5 +++--
Doctrine/AbstractElasticaToModelTransformer.php | 7 ++++---
3 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 4482a4c..df0fe19 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -170,6 +170,7 @@ class Configuration implements ConfigurationInterface
->addDefaultsIfNotSet()
->children()
->scalarNode('hydrate')->defaultTrue()->end()
+ ->scalarNode('ignore_missing')->defaultFalse()->end()
->scalarNode('service')->end()
->end()
->end()
@@ -250,6 +251,7 @@ class Configuration implements ConfigurationInterface
->addDefaultsIfNotSet()
->children()
->scalarNode('hydrate')->defaultTrue()->end()
+ ->scalarNode('ignore_missing')->defaultFalse()->end()
->scalarNode('service')->end()
->end()
->end()
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 0cb5c27..6d38714 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -272,8 +272,9 @@ class FOSElasticaExtension extends Extension
$serviceDef->replaceArgument($argPos, $typeConfig['model']);
$serviceDef->replaceArgument($argPos + 1, array(
- 'identifier' => $typeConfig['identifier'],
- 'hydrate' => $typeConfig['elastica_to_model_transformer']['hydrate']
+ 'hydrate' => $typeConfig['elastica_to_model_transformer']['hydrate'],
+ 'identifier' => $typeConfig['identifier'],
+ 'ignore_missing' => $typeConfig['elastica_to_model_transformer']['ignore_missing']
));
$container->setDefinition($serviceId, $serviceDef);
diff --git a/Doctrine/AbstractElasticaToModelTransformer.php b/Doctrine/AbstractElasticaToModelTransformer.php
index f796eec..e8f9472 100755
--- a/Doctrine/AbstractElasticaToModelTransformer.php
+++ b/Doctrine/AbstractElasticaToModelTransformer.php
@@ -32,8 +32,9 @@ abstract class AbstractElasticaToModelTransformer implements ElasticaToModelTran
* @var array
*/
protected $options = array(
- 'hydrate' => true,
- 'identifier' => 'id'
+ 'hydrate' => true,
+ 'identifier' => 'id',
+ 'ignore_missing' => false,
);
/**
@@ -94,7 +95,7 @@ abstract class AbstractElasticaToModelTransformer implements ElasticaToModelTran
}
$objects = $this->findByIdentifiers($ids, $this->options['hydrate']);
- if (count($objects) < count($elasticaObjects)) {
+ if (!$this->options['ignore_missing'] && count($objects) < count($elasticaObjects)) {
throw new \RuntimeException('Cannot find corresponding Doctrine objects for all Elastica results.');
};
From c05e0caa9cdc5c599780dd740be843c92bfdbbce Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Thu, 2 May 2013 10:18:05 +1000
Subject: [PATCH 030/447] Added documentation for ignoring missing hits
---
README.md | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/README.md b/README.md
index 0bcae02..c289cd6 100644
--- a/README.md
+++ b/README.md
@@ -534,6 +534,23 @@ The delete listener disregards the callback.
> **Propel** doesn't support this feature yet.
+### Ignoring missing index results
+
+By default, FOSElasticaBundle will throw an exception if the results returned from
+Elasticsearch are different from the results it finds from the chosen persistence
+provider. This may pose problems for a large index where updates do not occur instantly
+or another process has removed the results from your persistence provider without
+updating Elasticsearch.
+
+The error you're likely to see is something like:
+'Cannot find corresponding Doctrine objects for all Elastica results.'
+
+To solve this issue, each mapped object can be configured to ignore the missing results:
+
+ persistence:
+ elastica_to_model_transformer:
+ ignore_missing: true
+
### Advanced elasticsearch configuration
Any setting can be specified when declaring a type. For example, to enable a custom analyzer, you could write:
From 41c747907c483043c47d6160daf7a048030d7a9d Mon Sep 17 00:00:00 2001
From: Jeremy Mikola
Date: Wed, 15 May 2013 10:55:30 -0500
Subject: [PATCH 031/447] Create 2.1.x changelog
---
CHANGELOG-2.1.md | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
create mode 100644 CHANGELOG-2.1.md
diff --git a/CHANGELOG-2.1.md b/CHANGELOG-2.1.md
new file mode 100644
index 0000000..f4373e7
--- /dev/null
+++ b/CHANGELOG-2.1.md
@@ -0,0 +1,18 @@
+CHANGELOG for 2.1.x
+===================
+
+This changelog references the relevant changes (bug and security fixes) done
+in 2.1 minor versions.
+
+To get the diff for a specific change, go to
+https://github.com/FriendsOfSymfony/FOSElasticaBundle/commit/XXX where XXX is
+the commit hash. To get the diff between two versions, go to
+https://github.com/FriendsOfSymfony/FOSElasticaBundle/compare/v2.1.0...v2.1.1
+
+To generate a changelog summary since the last version, run
+`git log --no-merges --oneline v2.1.0...2.1.x`
+
+* 2.1.0 (2013-5-15)
+
+ * c05e0ca: Added documentation for ignoring missing hits
+ * 00b67fd: Ignore missing index hits
From 50730cca3d59f3429bfc0908424c4e998ab780df Mon Sep 17 00:00:00 2001
From: Lukas Kahwe Smith
Date: Fri, 17 May 2013 00:22:46 +0200
Subject: [PATCH 032/447] added path support, see
http://www.elasticsearch.org/guide/reference/mapping/id-field/
---
DependencyInjection/Configuration.php | 18 ++++++++++++++++++
DependencyInjection/FOSElasticaExtension.php | 3 +++
2 files changed, 21 insertions(+)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index f79eece..d901bfb 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -281,6 +281,7 @@ class Configuration implements ConfigurationInterface
->end()
->end()
->end()
+ ->append($this->getIdNode())
->append($this->getMappingsNode())
->append($this->getSourceNode())
->append($this->getBoostNode())
@@ -435,6 +436,23 @@ class Configuration implements ConfigurationInterface
$nestings[$property] = array_merge_recursive($nestings[$property], $this->getNestingsForType($field[$property]));
}
+ /**
+ * Returns the array node used for "_id".
+ */
+ protected function getIdNode()
+ {
+ $builder = new TreeBuilder();
+ $node = $builder->root('_id');
+
+ $node
+ ->children()
+ ->scalarNode('path')->end()
+ ->end()
+ ;
+
+ return $node;
+ }
+
/**
* Returns the array node used for "_source".
*/
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 473cec3..c28fb99 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -197,6 +197,9 @@ class FOSElasticaExtension extends Extension
$typeDef->addMethodCall('setSerializer', array(array(new Reference($callbackId), 'serialize')));
}
$container->setDefinition($typeId, $typeDef);
+ if (isset($type['_id'])) {
+ $this->indexConfigs[$indexName]['config']['mappings'][$name]['_id'] = $type['_id'];
+ }
if (isset($type['_source'])) {
$this->indexConfigs[$indexName]['config']['mappings'][$name]['_source'] = $type['_source'];
}
From be065735c13c2934200fcb59b29c604908c1d950 Mon Sep 17 00:00:00 2001
From: Lukas Kahwe Smith
Date: Wed, 22 May 2013 21:52:48 +0200
Subject: [PATCH 033/447] master is 3.0.x
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 555f5b1..e0915b8 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@ Add FOSElasticaBundle to your application's `composer.json` file:
```json
{
"require": {
- "friendsofsymfony/elastica-bundle": "~2.0"
+ "friendsofsymfony/elastica-bundle": "3.0.*@dev"
}
}
```
From 43d1531cd412f3ac9613702898a14a2dbfca628f Mon Sep 17 00:00:00 2001
From: Lukas Kahwe Smith
Date: Thu, 23 May 2013 00:25:38 +0300
Subject: [PATCH 034/447] cs fix
---
DependencyInjection/Configuration.php | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index d901bfb..79cadf2 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -12,7 +12,8 @@ class Configuration implements ConfigurationInterface
private $configArray = array();
- public function __construct($configArray){
+ public function __construct($configArray)
+ {
$this->configArray = $configArray;
}
From fab42fa0ceef2c5c5966f8cbf06480aac13cbfbe Mon Sep 17 00:00:00 2001
From: Patrick McAndrew
Date: Fri, 24 May 2013 12:27:37 +0100
Subject: [PATCH 035/447] Properities should not be required for object as
elastica can automap
---
README.md | 8 +++++++
.../ModelToElasticaAutoTransformerTest.php | 24 +++++++++++++++++++
.../ModelToElasticaAutoTransformer.php | 2 +-
3 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 555f5b1..fac11d1 100644
--- a/README.md
+++ b/README.md
@@ -184,6 +184,8 @@ per type.
### Declaring `nested` or `object`
+Note that object can autodetect properties
+
fos_elastica:
clients:
default: { host: localhost, port: 9200 }
@@ -204,6 +206,12 @@ per type.
properties:
date: { boost: 5 }
content: ~
+ user:
+ type: "object"
+ approver:
+ type: "object"
+ properties:
+ date: { boost: 5 }
### Populate the types
diff --git a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
index cbcb6bd..080cbfe 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');
@@ -268,6 +273,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/Transformer/ModelToElasticaAutoTransformer.php b/Transformer/ModelToElasticaAutoTransformer.php
index 38bd065..ebeacfb 100644
--- a/Transformer/ModelToElasticaAutoTransformer.php
+++ b/Transformer/ModelToElasticaAutoTransformer.php
@@ -72,7 +72,7 @@ class ModelToElasticaAutoTransformer implements ModelToElasticaTransformerInterf
continue;
}
- 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.
*/
From f374dbbaa2d3db3797907e3caed4db99432aaec9 Mon Sep 17 00:00:00 2001
From: Anthon Pang
Date: Thu, 30 May 2013 16:26:16 +0000
Subject: [PATCH 036/447] update to PSR3 LoggerInterface per change in
ruflin/elastica
---
Client.php | 4 ++-
Logger/ElasticaLogger.php | 76 +++++++++++++++++++++++++++++++++++++--
2 files changed, 77 insertions(+), 3 deletions(-)
diff --git a/Client.php b/Client.php
index 27cff7f..517fa8b 100644
--- a/Client.php
+++ b/Client.php
@@ -7,6 +7,8 @@ use Elastica\Request;
use FOS\ElasticaBundle\Logger\ElasticaLogger;
+use PSR\Log\LoggerInterface;
+
/**
* @author Gordon Franke
*/
@@ -17,7 +19,7 @@ class Client extends ElasticaClient
*/
protected $logger;
- public function setLogger(ElasticaLogger $logger)
+ public function setLogger(LoggerInterface $logger)
{
$this->logger = $logger;
}
diff --git a/Logger/ElasticaLogger.php b/Logger/ElasticaLogger.php
index e8840da..1705d06 100644
--- a/Logger/ElasticaLogger.php
+++ b/Logger/ElasticaLogger.php
@@ -2,7 +2,7 @@
namespace FOS\ElasticaBundle\Logger;
-use Symfony\Component\HttpKernel\Log\LoggerInterface;
+use Psr\Log\LoggerInterface;
/**
* Logger for the Elastica.
@@ -12,7 +12,7 @@ use Symfony\Component\HttpKernel\Log\LoggerInterface;
*
* @author Gordon Franke
*/
-class ElasticaLogger
+class ElasticaLogger implements LoggerInterface
{
protected $logger;
protected $queries;
@@ -75,4 +75,76 @@ class ElasticaLogger
{
return $this->queries;
}
+
+ /**
+ * {@inheritdoc}
+ */
+ public function emergency($message, array $context = array())
+ {
+ return $this->logger->emergency($message, $context);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function alert($message, array $context = array())
+ {
+ return $this->logger->alert($message, $context);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function critical($message, array $context = array())
+ {
+ return $this->logger->critical($message, $context);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function error($message, array $context = array())
+ {
+ return $this->logger->error($message, $context);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function warning($message, array $context = array())
+ {
+ return $this->logger->warning($message, $context);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function notice($message, array $context = array())
+ {
+ return $this->logger->notice($message, $context);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function info($message, array $context = array())
+ {
+ return $this->logger->info($message, $context);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function debug($message, array $context = array())
+ {
+ return $this->logger->debug($message, $context);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function log($level, $message, array $context = array())
+ {
+ return $this->logger->log($message, $context);
+ }
}
From 55edceadcb4a7152f6aefe1ccba047e769edb05e Mon Sep 17 00:00:00 2001
From: Anthon Pang
Date: Thu, 30 May 2013 16:43:10 +0000
Subject: [PATCH 037/447] remove redundant property/method
---
Client.php | 14 --------------
1 file changed, 14 deletions(-)
diff --git a/Client.php b/Client.php
index 517fa8b..ef9a8bd 100644
--- a/Client.php
+++ b/Client.php
@@ -5,25 +5,11 @@ namespace FOS\ElasticaBundle;
use Elastica\Client as ElasticaClient;
use Elastica\Request;
-use FOS\ElasticaBundle\Logger\ElasticaLogger;
-
-use PSR\Log\LoggerInterface;
-
/**
* @author Gordon Franke
*/
class Client extends ElasticaClient
{
- /**
- * @var ElasticaLogger
- */
- protected $logger;
-
- public function setLogger(LoggerInterface $logger)
- {
- $this->logger = $logger;
- }
-
public function request($path, $method = Request::GET, $data = array(), array $query = array())
{
$start = microtime(true);
From 929c1bfc0d61f11c18fb265ede9c6e26db673ce2 Mon Sep 17 00:00:00 2001
From: ceednee
Date: Thu, 30 May 2013 21:27:31 +0200
Subject: [PATCH 038/447] Fixes Undefined property: FOS\ElasticaBundle\Client::
---
Client.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Client.php b/Client.php
index ef9a8bd..8430b36 100644
--- a/Client.php
+++ b/Client.php
@@ -15,9 +15,9 @@ class Client extends ElasticaClient
$start = microtime(true);
$response = parent::request($path, $method, $data, $query);
- if (null !== $this->logger) {
+ if (null !== $this->_logger) {
$time = microtime(true) - $start;
- $this->logger->logQuery($path, $method, $data, $time);
+ $this->_logger->logQuery($path, $method, $data, $time);
}
return $response;
From 94ab3b1d3ccdd45fe0aa780c9b52a5e0fd386df7 Mon Sep 17 00:00:00 2001
From: Jeremy Mikola
Date: Fri, 31 May 2013 13:16:49 -0400
Subject: [PATCH 039/447] Add PSR Log dependency (see: #304)
---
composer.json | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/composer.json b/composer.json
index 7b54d57..a2951f0 100644
--- a/composer.json
+++ b/composer.json
@@ -16,7 +16,8 @@
"symfony/console": ">=2.1,<2.4-dev",
"symfony/form": ">=2.1,<2.4-dev",
"symfony/property-access": ">=2.2,<2.4-dev",
- "ruflin/elastica": "0.20.5.*@dev"
+ "ruflin/elastica": "0.20.5.*@dev",
+ "psr/log": "~1.0"
},
"require-dev":{
"doctrine/orm": ">=2.2,<2.5-dev",
From 1fc94b22133e5803123c6b5a8523756b585e6d99 Mon Sep 17 00:00:00 2001
From: Richard Fullmer
Date: Tue, 4 Jun 2013 11:45:45 -0700
Subject: [PATCH 040/447] Ignore failed deletions in ObjectPersister
This probably isn't the best way to solve my problem,
but the issue is this.
Step 1: Create a new doctrine entity for which it's `is_indexable_callback`
returns false. When doctrine flushes this entity to the database,
elastia will not index it with elastic search. (Correct)
Step 2: Update your doctrine entity and change some fields so
that `is_indexable_callback` _still_ returns false. Persist and flush
to the database.
At this point, the postUpdate listener on ElastiaBundle is called
and since the `is_indexable_callback` returns false, it believes
it needs to remove it from the elastic search index and queues it
for deletion. The deletion of course fails because it was never there
in the first place.
This solution simply ignores failures from deletions in the index.
Perhaps a better solution would be to have a smarter listener
that could determine if the entity was previously present in the
elastic search index or not, but that would require significant
refactoring.
Addresses issues discuseed in #284
Credit to @bbeaulant for simple solution. Opening a PR to
discuss more generally.
---
Persister/ObjectPersister.php | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/Persister/ObjectPersister.php b/Persister/ObjectPersister.php
index 643b817..450e43b 100644
--- a/Persister/ObjectPersister.php
+++ b/Persister/ObjectPersister.php
@@ -2,6 +2,7 @@
namespace FOS\ElasticaBundle\Persister;
+use Elastica\Exception\NotFoundException;
use FOS\ElasticaBundle\Transformer\ModelToElasticaTransformerInterface;
use Elastica\Type;
use Elastica\Document;
@@ -48,7 +49,9 @@ class ObjectPersister implements ObjectPersisterInterface
public function replaceOne($object)
{
$document = $this->transformToElasticaDocument($object);
- $this->type->deleteById($document->getId());
+ try {
+ $this->type->deleteById($document->getId());
+ } catch (NotFoundException $e) {}
$this->type->addDocument($document);
}
@@ -61,7 +64,9 @@ class ObjectPersister implements ObjectPersisterInterface
public function deleteOne($object)
{
$document = $this->transformToElasticaDocument($object);
- $this->type->deleteById($document->getId());
+ try {
+ $this->type->deleteById($document->getId());
+ } catch (NotFoundException $e) {}
}
/**
@@ -73,7 +78,9 @@ class ObjectPersister implements ObjectPersisterInterface
**/
public function deleteById($id)
{
- $this->type->deleteById($id);
+ try {
+ $this->type->deleteById($id);
+ } catch (NotFoundException $e) {}
}
From 00e9a49460142aeb099a314e00ef151ae2728d53 Mon Sep 17 00:00:00 2001
From: Jeremy Mikola
Date: Thu, 6 Jun 2013 11:02:55 -0400
Subject: [PATCH 041/447] Allow Symfony dependencies until 3.0
---
composer.json | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/composer.json b/composer.json
index a4969a0..def510b 100644
--- a/composer.json
+++ b/composer.json
@@ -12,9 +12,9 @@
],
"require": {
"php": ">=5.3.2",
- "symfony/framework-bundle": ">=2.1.0,<2.3.0-dev",
- "symfony/console": ">=2.1.0,<2.3.0-dev",
- "symfony/form": ">=2.1.0,<2.3.0-dev",
+ "symfony/framework-bundle": "~2.1",
+ "symfony/console": "~2.1",
+ "symfony/form": "~2.1",
"ruflin/elastica": "0.19.8"
},
"require-dev":{
@@ -25,7 +25,7 @@
"knplabs/knp-components": "1.2.*"
},
"suggest": {
- "symfony/property-access": "2.2.*",
+ "symfony/property-access": "~2.2",
"doctrine/orm": ">=2.2,<2.5-dev",
"doctrine/mongodb-odm": "1.0.*@dev",
"propel/propel1": "1.6.*",
From cd48a3668794fbc548192da10e0c60033eac1a78 Mon Sep 17 00:00:00 2001
From: Jeremy Mikola
Date: Thu, 6 Jun 2013 11:05:31 -0400
Subject: [PATCH 042/447] Update 2.0.x changelog
---
CHANGELOG-2.0.md | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/CHANGELOG-2.0.md b/CHANGELOG-2.0.md
index b384948..26c779c 100644
--- a/CHANGELOG-2.0.md
+++ b/CHANGELOG-2.0.md
@@ -12,6 +12,13 @@ https://github.com/FriendsOfSymfony/FOSElasticaBundle/compare/v2.0.0...v2.0.1
To generate a changelog summary since the last version, run
`git log --no-merges --oneline v2.0.0...2.0.x`
+* 2.0.2 (2013-06-06)
+
+ * 00e9a49: Allow Symfony dependencies until 3.0
+ * 4b4a56d: Check for "indexes" key in Configuration::getNestings()
+ * 8ffd1a7: Update install version and add links to compatibility info
+ * 58e983f: Document installation via composer in README (closes #271)
+
* 2.0.1 (2013-04-04)
* f0d3a4d: Ensure mongo extension is available in Travis CI
From 2dfbfffbd0dce5071e29c525f48aa760c5417b9f Mon Sep 17 00:00:00 2001
From: Jeremy Mikola
Date: Thu, 6 Jun 2013 11:19:59 -0400
Subject: [PATCH 043/447] Update 2.1.x changelog
---
CHANGELOG-2.1.md | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG-2.1.md b/CHANGELOG-2.1.md
index f4373e7..4069cdd 100644
--- a/CHANGELOG-2.1.md
+++ b/CHANGELOG-2.1.md
@@ -12,7 +12,11 @@ https://github.com/FriendsOfSymfony/FOSElasticaBundle/compare/v2.1.0...v2.1.1
To generate a changelog summary since the last version, run
`git log --no-merges --oneline v2.1.0...2.1.x`
-* 2.1.0 (2013-5-15)
+* 2.1.2 (2013-06-06)
+
+ * 00e9a49: Allow Symfony dependencies until 3.0
+
+* 2.1.1 (2013-05-15)
* c05e0ca: Added documentation for ignoring missing hits
* 00b67fd: Ignore missing index hits
From 16ecd7cca306063a0fff9ac27d38af3f416e98f5 Mon Sep 17 00:00:00 2001
From: Patrick McAndrew
Date: Thu, 16 May 2013 15:56:44 +0100
Subject: [PATCH 044/447] Tag client with fos_elastica.client
---
Resources/config/config.xml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Resources/config/config.xml b/Resources/config/config.xml
index cd91961..4097289 100644
--- a/Resources/config/config.xml
+++ b/Resources/config/config.xml
@@ -33,6 +33,7 @@
+
From b9da709f22dc36c2e7934a6af933a3282bb932b2 Mon Sep 17 00:00:00 2001
From: Jeremy Mikola
Date: Mon, 10 Jun 2013 10:36:28 -0400
Subject: [PATCH 045/447] Add documentation for client tagging
---
README.md | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/README.md b/README.md
index c31bc29..475de02 100644
--- a/README.md
+++ b/README.md
@@ -680,6 +680,14 @@ class Client extends BaseClient
}
```
+### Clients as Tagged Services
+
+Clients will be tagged as `fos_elastica.client`, which makes it possible to
+retrieve all clients from the service container and interact with them via a
+compiler pass. See
+[Working with Tagged Services](http://symfony.com/doc/current/components/dependency_injection/tags.html)
+for more information.
+
### Example of Advanced Query
If you would like to perform more advanced queries, here is one example using
From c4cc199fbeaafbdfc21511778594d3e2c94c7a70 Mon Sep 17 00:00:00 2001
From: RobertPlant
Date: Wed, 12 Jun 2013 10:34:42 +0200
Subject: [PATCH 046/447] Document object mapping implications for Doctrine ORM
---
README.md | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/README.md b/README.md
index 475de02..7cc86c2 100644
--- a/README.md
+++ b/README.md
@@ -205,6 +205,12 @@ per type.
date: { boost: 5 }
content: ~
+#### Doctrine ORM and `object` mappings
+
+Objects operate in the same way as the nested results but they need to have associations set up in Doctrine ORM so that they can be referenced correctly when indexing.
+
+If an "Entity was not found" error occurs while indexing, a null association has been discovered in the database. A custom Doctrine query must be used to utilize left joins instead of the default inner join.
+
### Populate the types
php app/console fos:elastica:populate
From fd5ef8005e68a27e9568c46a02780652a3c947a5 Mon Sep 17 00:00:00 2001
From: RobertPlant
Date: Thu, 13 Jun 2013 11:28:49 +0200
Subject: [PATCH 047/447] Update README.md
---
README.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/README.md b/README.md
index 7cc86c2..e575f88 100644
--- a/README.md
+++ b/README.md
@@ -386,6 +386,9 @@ Pagerfanta:
/** var Pagerfanta\Pagerfanta */
$userPaginator = $finder->findPaginated('bob');
+ /** Number of results to be used for paging the results */
+ $countOfResults = $userPaginator->getNbResults();
+
Knp paginator:
$paginator = $this->get('knp_paginator');
From a386ffefe332d23e7ac9bcfcb71e667302a49d47 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Antonio=20J=2E=20Garc=C3=ADa=20Lagar?=
Date: Mon, 17 Jun 2013 21:19:11 +0200
Subject: [PATCH 048/447] Fix parent mapping
---
DependencyInjection/Configuration.php | 28 ++++++++++++++-----
DependencyInjection/FOSElasticaExtension.php | 6 +++-
README.md | 2 +-
Resetter.php | 6 ++--
Tests/ResetterTest.php | 13 +++++++--
.../ModelToElasticaAutoTransformerTest.php | 12 +++-----
.../ModelToElasticaAutoTransformer.php | 12 ++++----
7 files changed, 48 insertions(+), 31 deletions(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 79cadf2..da63a2d 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -287,6 +287,7 @@ class Configuration implements ConfigurationInterface
->append($this->getSourceNode())
->append($this->getBoostNode())
->append($this->getRoutingNode())
+ ->append($this->getParentNode())
->end()
;
@@ -338,13 +339,7 @@ class Configuration implements ConfigurationInterface
->scalarNode('index_options')->end()
->scalarNode('ignore_above')->end()
->scalarNode('position_offset_gap')->end()
- ->arrayNode('_parent')
- ->treatNullLike(array())
- ->children()
- ->scalarNode('type')->end()
- ->scalarNode('identifier')->defaultValue('id')->end()
- ->end()
- ->end();
+ ;
if (isset($nestings['fields'])) {
$this->addNestedFieldConfig($node, $nestings, 'fields');
@@ -516,4 +511,23 @@ class Configuration implements ConfigurationInterface
return $node;
}
+
+ /**
+ * Returns the array node used for "_parent".
+ */
+ protected function getParentNode()
+ {
+ $builder = new TreeBuilder();
+ $node = $builder->root('_parent');
+
+ $node
+ ->children()
+ ->scalarNode('type')->end()
+ ->scalarNode('property')->end()
+ ->scalarNode('identifier')->defaultValue('id')->end()
+ ->end()
+ ;
+
+ return $node;
+ }
}
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index c28fb99..d83b604 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -214,6 +214,11 @@ class FOSElasticaExtension extends Extension
$typeName = sprintf('%s/%s', $indexName, $name);
$this->typeFields[$typeName] = $type['mappings'];
}
+ if (isset($type['_parent'])) {
+ $this->indexConfigs[$indexName]['config']['mappings'][$name]['_parent'] = array('type' => $type['_parent']['type']);
+ $typeName = sprintf('%s/%s', $indexName, $name);
+ $this->typeFields[$typeName]['_parent'] = $type['_parent'];
+ }
if (isset($type['persistence'])) {
$this->loadTypePersistenceIntegration($type['persistence'], $container, $typeDef, $indexName, $name);
}
@@ -476,5 +481,4 @@ class FOSElasticaExtension extends Extension
$container->setAlias('fos_elastica.manager', sprintf('fos_elastica.manager.%s', $defaultManagerService));
}
-
}
diff --git a/README.md b/README.md
index e575f88..47789b7 100644
--- a/README.md
+++ b/README.md
@@ -178,9 +178,9 @@ per type.
types:
comment:
mappings:
- post: {_parent: { type: "post", identifier: "id" } }
date: { boost: 5 }
content: ~
+ _parent: { type: "post", property: "post", identifier: "id" }
### Declaring `nested` or `object`
diff --git a/Resetter.php b/Resetter.php
index 7ef2895..9a9da0b 100644
--- a/Resetter.php
+++ b/Resetter.php
@@ -74,10 +74,8 @@ class Resetter
{
$mapping = Mapping::create($indexConfig['properties']);
- foreach($indexConfig['properties'] as $type) {
- if (!empty($type['_parent']) && $type['_parent'] !== '~') {
- $mapping->setParam('_parent', array('type' => $type['_parent']['type']));
- }
+ if (isset($indexConfig['_parent'])) {
+ $mapping->setParam('_parent', array('type' => $indexConfig['_parent']['type']));
}
return $mapping;
diff --git a/Tests/ResetterTest.php b/Tests/ResetterTest.php
index 1a7190e..18cbe06 100644
--- a/Tests/ResetterTest.php
+++ b/Tests/ResetterTest.php
@@ -34,9 +34,16 @@ class ResetterTest extends \PHPUnit_Framework_TestCase
'index' => $this->getMockElasticaIndex(),
'config' => array(
'mappings' => array(
- 'a' => array('properties' => array(
- 'field_1' => array('_parent' => array('type' => 'b', 'identifier' => 'id')),
- 'field_2' => array())),
+ 'a' => array(
+ 'properties' => array(
+ 'field_2' => array()
+ ),
+ '_parent' => array(
+ 'type' => 'b',
+ 'property' => 'b',
+ 'identifier' => 'id'
+ ),
+ ),
'b' => array('properties' => array()),
),
),
diff --git a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
index cbcb6bd..8b6b3ae 100644
--- a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
+++ b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
@@ -272,10 +272,8 @@ class ModelToElasticaAutoTransformerTest extends \PHPUnit_Framework_TestCase
{
$transformer = $this->getTransformer();
$document = $transformer->transform(new POPO(), array(
- 'upper' => array(
- '_parent' => array('type' => 'upper', 'identifier' => 'id'),
- )
- ));
+ '_parent' => array('type' => 'upper', 'property'=>'upper', 'identifier' => 'id'),
+ ));
$this->assertEquals("parent", $document->getParent());
}
@@ -284,10 +282,8 @@ class ModelToElasticaAutoTransformerTest extends \PHPUnit_Framework_TestCase
{
$transformer = $this->getTransformer();
$document = $transformer->transform(new POPO(), array(
- 'upper' => array(
- '_parent' => array('type' => 'upper', 'identifier' => 'name'),
- )
- ));
+ '_parent' => array('type' => 'upper', 'property'=>'upper', 'identifier' => 'name'),
+ ));
$this->assertEquals("a random name", $document->getParent());
}
diff --git a/Transformer/ModelToElasticaAutoTransformer.php b/Transformer/ModelToElasticaAutoTransformer.php
index 38bd065..5d8701a 100644
--- a/Transformer/ModelToElasticaAutoTransformer.php
+++ b/Transformer/ModelToElasticaAutoTransformer.php
@@ -62,15 +62,13 @@ class ModelToElasticaAutoTransformer implements ModelToElasticaTransformerInterf
$document = new Document($identifier);
foreach ($fields as $key => $mapping) {
- $value = $this->propertyAccessor->getValue($object, $key);
-
- if (isset($mapping['_parent']['identifier'])) {
- /* $value is the parent. Read its identifier and set that as the
- * document's parent.
- */
- $document->setParent($this->propertyAccessor->getValue($value, $mapping['_parent']['identifier']));
+ if ($key == '_parent') {
+ $value = $this->propertyAccessor->getValue($object, $mapping['property']);
+ $document->setParent($this->propertyAccessor->getValue($value, $mapping['identifier']));
continue;
}
+
+ $value = $this->propertyAccessor->getValue($object, $key);
if (isset($mapping['type']) && in_array($mapping['type'], array('nested', 'object'))) {
/* $value is a nested document or object. Transform $value into
From 0bf6e0b09a0a10de34203598c7b1aa64974cfce6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Antonio=20J=2E=20Garc=C3=ADa=20Lagar?=
Date: Tue, 18 Jun 2013 09:52:44 +0200
Subject: [PATCH 049/447] Fix output colors
---
Command/PopulateCommand.php | 6 +++---
Command/ResetCommand.php | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/Command/PopulateCommand.php b/Command/PopulateCommand.php
index 4f88b75..3fa7cd2 100755
--- a/Command/PopulateCommand.php
+++ b/Command/PopulateCommand.php
@@ -125,18 +125,18 @@ class PopulateCommand extends ContainerAwareCommand
private function populateIndexType(OutputInterface $output, $index, $type, $reset)
{
if ($reset) {
- $output->writeln(sprintf('Resetting: %s/%s', $index, $type));
+ $output->writeln(sprintf('Resetting %s/%s', $index, $type));
$this->resetter->resetIndexType($index, $type);
}
$loggerClosure = function($message) use ($output, $index, $type) {
- $output->writeln(sprintf('Populating: %s/%s, %s', $index, $type, $message));
+ $output->writeln(sprintf('Populating %s/%s, %s', $index, $type, $message));
};
$provider = $this->providerRegistry->getProvider($index, $type);
$provider->populate($loggerClosure);
- $output->writeln(sprintf('Refreshing: %s', $index));
+ $output->writeln(sprintf('Refreshing %s', $index));
$this->indexManager->getIndex($index)->refresh();
}
}
diff --git a/Command/ResetCommand.php b/Command/ResetCommand.php
index f223d63..b318827 100755
--- a/Command/ResetCommand.php
+++ b/Command/ResetCommand.php
@@ -61,7 +61,7 @@ class ResetCommand extends ContainerAwareCommand
}
if (null !== $type) {
- $output->writeln(sprintf('Resetting: %s/%s', $index, $type));
+ $output->writeln(sprintf('Resetting %s/%s', $index, $type));
$this->resetter->resetIndex($index, $type);
} else {
$indexes = null === $index
From b11b4299ef58d3c964a227f889527f2c484cc2c3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Antonio=20J=2E=20Garc=C3=ADa=20Lagar?=
Date: Wed, 19 Jun 2013 12:36:59 +0200
Subject: [PATCH 050/447] An orderBy DQL part is required to avoid feching the
same row twice
---
Doctrine/ORM/Provider.php | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/Doctrine/ORM/Provider.php b/Doctrine/ORM/Provider.php
index 0f130fc..cbd69f0 100644
--- a/Doctrine/ORM/Provider.php
+++ b/Doctrine/ORM/Provider.php
@@ -8,6 +8,8 @@ use FOS\ElasticaBundle\Exception\InvalidArgumentTypeException;
class Provider extends AbstractProvider
{
+ const ENTITY_ALIAS = 'a';
+
/**
* @see FOS\ElasticaBundle\Doctrine\AbstractProvider::countObjects()
*/
@@ -40,6 +42,24 @@ class Provider extends AbstractProvider
throw new InvalidArgumentTypeException($queryBuilder, 'Doctrine\ORM\QueryBuilder');
}
+ /**
+ * An orderBy DQL part is required to avoid feching the same row twice.
+ * @see http://stackoverflow.com/questions/6314879/does-limit-offset-length-require-order-by-for-pagination
+ * @see http://www.postgresql.org/docs/current/static/queries-limit.html
+ * @see http://www.sqlite.org/lang_select.html#orderby
+ */
+ $orderBy = $queryBuilder->getDQLPart('orderBy');
+ if (empty($orderBy)) {
+ $identifierFieldNames = $this->managerRegistry
+ ->getManagerForClass($this->objectClass)
+ ->getClassMetadata($this->objectClass)
+ ->getIdentifierFieldNames();
+ sort($identifierFieldNames);
+ foreach ($identifierFieldNames as $fieldName) {
+ $queryBuilder->addOrderBy(static::ENTITY_ALIAS.'.'.$fieldName);
+ }
+ }
+
return $queryBuilder
->setFirstResult($offset)
->setMaxResults($limit)
@@ -56,6 +76,6 @@ class Provider extends AbstractProvider
->getManagerForClass($this->objectClass)
->getRepository($this->objectClass)
// ORM query builders require an alias argument
- ->{$this->options['query_builder_method']}('a');
+ ->{$this->options['query_builder_method']}(static::ENTITY_ALIAS);
}
}
From 7f3cfa49fb3f569d6a2d733221317992b54e17a8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Antonio=20J=2E=20Garc=C3=ADa=20Lagar?=
Date: Wed, 19 Jun 2013 13:57:15 +0200
Subject: [PATCH 051/447] Make the property param optional
---
DependencyInjection/Configuration.php | 4 +--
README.md | 6 +++++
.../ModelToElasticaAutoTransformerTest.php | 25 +++++++++++++++++++
.../ModelToElasticaAutoTransformer.php | 5 ++--
4 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index da63a2d..f9f633f 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -511,7 +511,7 @@ class Configuration implements ConfigurationInterface
return $node;
}
-
+
/**
* Returns the array node used for "_parent".
*/
@@ -523,7 +523,7 @@ class Configuration implements ConfigurationInterface
$node
->children()
->scalarNode('type')->end()
- ->scalarNode('property')->end()
+ ->scalarNode('property')->defaultValue(null)->end()
->scalarNode('identifier')->defaultValue('id')->end()
->end()
;
diff --git a/README.md b/README.md
index 47789b7..0b6c3af 100644
--- a/README.md
+++ b/README.md
@@ -182,6 +182,12 @@ per type.
content: ~
_parent: { type: "post", property: "post", identifier: "id" }
+The parent filed 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`.
+
### Declaring `nested` or `object`
fos_elastica:
diff --git a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
index 8b6b3ae..9990fa2 100644
--- a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
+++ b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
@@ -106,6 +106,11 @@ class POPO
{
return (object) array('id' => 'parent', 'name' => 'a random name');
}
+
+ public function getUpperAlias()
+ {
+ return $this->getUpper();
+ }
}
class ModelToElasticaAutoTransformerTest extends \PHPUnit_Framework_TestCase
@@ -288,6 +293,26 @@ class ModelToElasticaAutoTransformerTest extends \PHPUnit_Framework_TestCase
$this->assertEquals("a random name", $document->getParent());
}
+ public function testParentMappingWithNullProperty()
+ {
+ $transformer = $this->getTransformer();
+ $document = $transformer->transform(new POPO(), array(
+ '_parent' => array('type' => 'upper', 'property'=>null, 'identifier' => 'id'),
+ ));
+
+ $this->assertEquals("parent", $document->getParent());
+ }
+
+ public function testParentMappingWithCustomProperty()
+ {
+ $transformer = $this->getTransformer();
+ $document = $transformer->transform(new POPO(), array(
+ '_parent' => array('type' => 'upper', 'property'=>'upperAlias', 'identifier' => 'id'),
+ ));
+
+ $this->assertEquals("parent", $document->getParent());
+ }
+
/**
* @return ModelToElasticaAutoTransformer
*/
diff --git a/Transformer/ModelToElasticaAutoTransformer.php b/Transformer/ModelToElasticaAutoTransformer.php
index 5d8701a..d99f301 100644
--- a/Transformer/ModelToElasticaAutoTransformer.php
+++ b/Transformer/ModelToElasticaAutoTransformer.php
@@ -63,11 +63,12 @@ class ModelToElasticaAutoTransformer implements ModelToElasticaTransformerInterf
foreach ($fields as $key => $mapping) {
if ($key == '_parent') {
- $value = $this->propertyAccessor->getValue($object, $mapping['property']);
+ $property = (null !== $mapping['property'])?$mapping['property']:$mapping['type'];
+ $value = $this->propertyAccessor->getValue($object, $property);
$document->setParent($this->propertyAccessor->getValue($value, $mapping['identifier']));
continue;
}
-
+
$value = $this->propertyAccessor->getValue($object, $key);
if (isset($mapping['type']) && in_array($mapping['type'], array('nested', 'object'))) {
From 8b785c57c3d33be4e00e87bd2c77bcac35c03aac Mon Sep 17 00:00:00 2001
From: Tobias Schultze
Date: Mon, 24 Jun 2013 18:44:46 +0300
Subject: [PATCH 052/447] Allow elastica 0.90. Elasticsearch made the jump from
0.20 to 0.90
---
composer.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/composer.json b/composer.json
index 22e492e..099868b 100644
--- a/composer.json
+++ b/composer.json
@@ -16,7 +16,7 @@
"symfony/console": "~2.1",
"symfony/form": "~2.1",
"symfony/property-access": "~2.2",
- "ruflin/elastica": "0.20.5.*@dev",
+ "ruflin/elastica": "~0.20",
"psr/log": "~1.0"
},
"require-dev":{
From 170864a30d2f2bc451dbb794c78d51bd735e31d9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Antonio=20J=2E=20Garc=C3=ADa=20Lagar?=
Date: Thu, 4 Jul 2013 08:07:00 +0200
Subject: [PATCH 053/447] Removes sort call
---
Doctrine/ORM/Provider.php | 1 -
1 file changed, 1 deletion(-)
diff --git a/Doctrine/ORM/Provider.php b/Doctrine/ORM/Provider.php
index cbd69f0..3549550 100644
--- a/Doctrine/ORM/Provider.php
+++ b/Doctrine/ORM/Provider.php
@@ -54,7 +54,6 @@ class Provider extends AbstractProvider
->getManagerForClass($this->objectClass)
->getClassMetadata($this->objectClass)
->getIdentifierFieldNames();
- sort($identifierFieldNames);
foreach ($identifierFieldNames as $fieldName) {
$queryBuilder->addOrderBy(static::ENTITY_ALIAS.'.'.$fieldName);
}
From 9beb2777458771763cadb969646d83cbdbf5f8fb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=A1bor=20T=C3=B3th?=
Date: Thu, 4 Jul 2013 18:47:58 +0200
Subject: [PATCH 054/447] Remove unused parameter from
ModelToElasticaAutoTransformer.php
---
Transformer/ModelToElasticaAutoTransformer.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Transformer/ModelToElasticaAutoTransformer.php b/Transformer/ModelToElasticaAutoTransformer.php
index 38bd065..559bb59 100644
--- a/Transformer/ModelToElasticaAutoTransformer.php
+++ b/Transformer/ModelToElasticaAutoTransformer.php
@@ -76,7 +76,7 @@ class ModelToElasticaAutoTransformer implements ModelToElasticaTransformerInterf
/* $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));
+ $document->add($key, $this->transformNested($value, $mapping['properties']));
continue;
}
From 9e2e8ab1c94e937f35378bdb5e291817941157fb Mon Sep 17 00:00:00 2001
From: Jeremy Mikola
Date: Fri, 12 Jul 2013 17:32:33 -0400
Subject: [PATCH 055/447] Fix missing getter for private field test for
PropertyAccess 2.3+
See: https://github.com/symfony/PropertyAccess/commit/df67239b02a9cef12cf84579f6cf569680298238
---
.../ModelToElasticaAutoTransformerTest.php | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
index 798ea38..daa6512 100644
--- a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
+++ b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
@@ -203,10 +203,17 @@ class ModelToElasticaAutoTransformerTest extends \PHPUnit_Framework_TestCase
public function testThatCannotTransformObjectWhenGetterDoesNotExistForPrivateMethod()
{
- // Support both Symfony 2.1 (Form component) and 2.2 (PropertyAccess component)
- $expectedException = class_exists('Symfony\Component\PropertyAccess\PropertyAccess')
- ? 'Symfony\Component\PropertyAccess\Exception\PropertyAccessDeniedException'
- : 'Symfony\Component\Form\Exception\PropertyAccessDeniedException';
+ // Support both Symfony 2.1 (Form component) and 2.2+ (PropertyAccess component)
+ if (class_exists('Symfony\Component\PropertyAccess\PropertyAccess')) {
+ /* ProperyAccess 2.3+ removed PropertyAccessDeniedException, so we
+ * must expect NoSuchPropertyException in its absence.
+ */
+ $expectedException = class_exists('Symfony\Component\Form\Exception\PropertyAccessDeniedException')
+ ? 'Symfony\Component\Form\Exception\PropertyAccessDeniedException'
+ : 'Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException';
+ } else {
+ $expectedException = 'Symfony\Component\Form\Exception\PropertyAccessDeniedException';
+ }
$this->setExpectedException($expectedException);
From cce1ffb06c519d59c00322687d507aea2dc7dd54 Mon Sep 17 00:00:00 2001
From: RobertPlant
Date: Fri, 14 Jun 2013 11:28:19 +0200
Subject: [PATCH 056/447] Add filtered query example to README.md
---
README.md | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/README.md b/README.md
index e575f88..2c1aef2 100644
--- a/README.md
+++ b/README.md
@@ -754,3 +754,32 @@ fos_elastica:
provider:
finder:
```
+
+### Filtering Results and executing a default query
+
+You may want to remove a certain section of results from a query, filtering is ideal because it is slightly faster in performance compared to a standard query because the only the filtered subset of results are cached. This improves query speed because the query is ran against the predetermined subset from previous queries rather than recalculating the whole query again. Filtering can effectively when trying to look for only active records which are indicated by a field in the database. `FilteredQuery` should be used to combine the `QueryString` operator with the `Filter`, an example of `FilteredQuery` is shown Below.
+
+```php
+$term = new \Elastica\Filter\Term();
+$term->setParams(array(
+ 'active' => 'active',
+ 'address.postCode' => $postCode //Accessing elements nested within an object. address is the object and postCode is the property within it.
+ 'companyGroup' => $department
+ ));
+
+$query = new \Elastica\Query\QueryString();
+$query->setQuery($queryString);
+
+$filteredQuery = new \Elastica\Query\Filtered($query, $term);
+
+$results = $this->container->get('fos_elastica.finder.company.company')->findPaginated($filteredQuery);
+
+// Filter results for paging
+$results->setMaxPerPage($limit);
+$results->setCurrentPage($page);
+
+// Number of total results for paging
+$total = $results->getNbResults();
+
+```
+
From 00f37835fc554e976710482be5d811e9c791ccc1 Mon Sep 17 00:00:00 2001
From: Jeremy Mikola
Date: Tue, 16 Jul 2013 13:33:21 -0400
Subject: [PATCH 057/447] Rewrite filtered query example in README
Cleaning up the description paragraph and removing extra fields and pagination from the example, since we already have pagination examples elsewhere in the README.
---
README.md | 32 ++++++++++----------------------
1 file changed, 10 insertions(+), 22 deletions(-)
diff --git a/README.md b/README.md
index 2c1aef2..ccae8db 100644
--- a/README.md
+++ b/README.md
@@ -755,31 +755,19 @@ fos_elastica:
finder:
```
-### Filtering Results and executing a default query
+### Filtering Results and Executing a Default Query
-You may want to remove a certain section of results from a query, filtering is ideal because it is slightly faster in performance compared to a standard query because the only the filtered subset of results are cached. This improves query speed because the query is ran against the predetermined subset from previous queries rather than recalculating the whole query again. Filtering can effectively when trying to look for only active records which are indicated by a field in the database. `FilteredQuery` should be used to combine the `QueryString` operator with the `Filter`, an example of `FilteredQuery` is shown Below.
+If may want to omit certain results from a query, filtering can be more
+performant than a basic query because the filter results can be cached. In turn,
+the query is run against only a subset of the results. A common use case for
+filtering would be if your data has fields that indicate whether records are
+"active" or "inactive". The following example illustrates how to issue such a
+query with Elastica:
```php
-$term = new \Elastica\Filter\Term();
-$term->setParams(array(
- 'active' => 'active',
- 'address.postCode' => $postCode //Accessing elements nested within an object. address is the object and postCode is the property within it.
- 'companyGroup' => $department
- ));
-
-$query = new \Elastica\Query\QueryString();
-$query->setQuery($queryString);
+$query = new \Elastica\Query\QueryString($queryString);
+$term = new \Elastica\Filter\Term(array('active' => true));
$filteredQuery = new \Elastica\Query\Filtered($query, $term);
-
-$results = $this->container->get('fos_elastica.finder.company.company')->findPaginated($filteredQuery);
-
-// Filter results for paging
-$results->setMaxPerPage($limit);
-$results->setCurrentPage($page);
-
-// Number of total results for paging
-$total = $results->getNbResults();
-
+$results = $this->container->get('fos_elastica.finder.index.type')->find($filteredQuery);
```
-
From 5b6a1f7bd656f6c8490035aa309334cdce415457 Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Wed, 17 Jul 2013 08:58:15 +0200
Subject: [PATCH 058/447] Adding new persister and new transformer to make use
of the serializer support of elastica when persisting doctrine objects
---
DependencyInjection/FOSElasticaExtension.php | 47 ++++++---
Persister/ObjectSerializerPersister.php | 97 +++++++++++++++++++
Resources/config/config.xml | 13 +++
.../ModelToElasticaIdentifierTransformer.php | 26 +++++
4 files changed, 169 insertions(+), 14 deletions(-)
create mode 100644 Persister/ObjectSerializerPersister.php
create mode 100644 Transformer/ModelToElasticaIdentifierTransformer.php
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index c28fb99..9a15a83 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);
@@ -94,7 +95,7 @@ class FOSElasticaExtension extends Extension
* @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 +130,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,7 +171,7 @@ class FOSElasticaExtension extends Extension
* @param $indexId
* @param array $typePrototypeConfig
*/
- 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);
@@ -179,12 +180,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']));
}
@@ -307,7 +308,11 @@ class FOSElasticaExtension extends Extension
if (isset($typeConfig['model_to_elastica_transformer']['service'])) {
return $typeConfig['model_to_elastica_transformer']['service'];
}
- $abstractId = sprintf('fos_elastica.model_to_elastica_transformer.prototype.auto');
+ if ($this->serializerConfig) {
+ $abstractId = sprintf('fos_elastica.model_to_elastica_transformer.prototype.identifier');
+ } else {
+ $abstractId = sprintf('fos_elastica.model_to_elastica_transformer.prototype.auto');
+ }
$serviceId = sprintf('fos_elastica.model_to_elastica_transformer.%s.%s', $indexName, $typeName);
$serviceDef = new DefinitionDecorator($abstractId);
$serviceDef->replaceArgument(0, array(
@@ -320,13 +325,27 @@ class FOSElasticaExtension extends Extension
protected function loadObjectPersister(array $typeConfig, Definition $typeDef, ContainerBuilder $container, $indexName, $typeName, $transformerId)
{
- $abstractId = sprintf('fos_elastica.object_persister.prototype');
+ if ($this->serializerConfig) {
+ $abstractId = sprintf('fos_elastica.object_serializer_persister.prototype');
+ $arguments = array(
+ $typeDef,
+ new Reference($transformerId),
+ $typeConfig['model'],
+ );
+ } else {
+ $abstractId = sprintf('fos_elastica.object_persister.prototype');
+ $arguments = array(
+ $typeDef,
+ new Reference($transformerId),
+ $typeConfig['model'],
+ $this->typeFields[sprintf('%s/%s', $indexName, $typeName)],
+ );
+ }
$serviceId = sprintf('fos_elastica.object_persister.%s.%s', $indexName, $typeName);
$serviceDef = new DefinitionDecorator($abstractId);
- $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)]);
+ foreach ($arguments as $i => $argument) {
+ $serviceDef->replaceArgument($i, $argument);
+ }
$container->setDefinition($serviceId, $serviceDef);
return $serviceId;
diff --git a/Persister/ObjectSerializerPersister.php b/Persister/ObjectSerializerPersister.php
new file mode 100644
index 0000000..db8122a
--- /dev/null
+++ b/Persister/ObjectSerializerPersister.php
@@ -0,0 +1,97 @@
+
+ */
+class ObjectSerializerPersister extends ObjectPersister
+{
+ public function __construct(Type $type, ModelToElasticaTransformerInterface $transformer, $objectClass)
+ {
+ $this->type = $type;
+ $this->transformer = $transformer;
+ $this->objectClass = $objectClass;
+ }
+
+ /**
+ * Insert one object into the type
+ * The object will be transformed to an elastica document
+ *
+ * @param object $object
+ */
+ public function insertOne($object)
+ {
+ $document = $this->transformToElasticaDocument($object);
+ $this->type->addObject($object, $document);
+ }
+
+ /**
+ * Replaces one object in the type
+ *
+ * @param object $object
+ * @return null
+ **/
+ public function replaceOne($object)
+ {
+ $document = $this->transformToElasticaDocument($object);
+ $this->type->deleteById($document->getId());
+ $this->type->addObject($object, $document);
+ }
+
+ /**
+ * Deletes one object in the type
+ *
+ * @param object $object
+ * @return null
+ **/
+ public function deleteOne($object)
+ {
+ $document = $this->transformToElasticaDocument($object);
+ $this->type->deleteById($document->getId());
+ }
+
+ /**
+ * Deletes one object in the type by id
+ *
+ * @param mixed $id
+ *
+ * @return null
+ **/
+ public function deleteById($id)
+ {
+ $this->type->deleteById($id);
+ }
+
+
+ /**
+ * Inserts an array of objects in the type
+ *
+ * @param array $objects array of domain model objects
+ **/
+ public function insertMany(array $objects)
+ {
+ foreach ($objects as $object) {
+ $this->insertOne($object);
+ }
+ }
+
+ /**
+ * Transforms an object to an elastica document
+ * with just the identifier set
+ *
+ * @param object $object
+ * @return Document the elastica document
+ */
+ public function transformToElasticaDocument($object)
+ {
+ return $this->transformer->transform($object, array());
+ }
+}
diff --git a/Resources/config/config.xml b/Resources/config/config.xml
index 4097289..3f5f7cf 100644
--- a/Resources/config/config.xml
+++ b/Resources/config/config.xml
@@ -52,6 +52,12 @@
+
+
+
+
+
+
@@ -64,6 +70,13 @@
+
+
+
+
+
+
+
diff --git a/Transformer/ModelToElasticaIdentifierTransformer.php b/Transformer/ModelToElasticaIdentifierTransformer.php
new file mode 100644
index 0000000..416eaf7
--- /dev/null
+++ b/Transformer/ModelToElasticaIdentifierTransformer.php
@@ -0,0 +1,26 @@
+propertyAccessor->getValue($object, $this->options['identifier']);
+ return new Document($identifier);
+ }
+}
From d10e8f56c8b7e1374dae924e1a0efd2067986208 Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Wed, 17 Jul 2013 10:10:07 +0200
Subject: [PATCH 059/447] Tests for new provider and new transformer
---
.../ObjectSerializerPersisterTest.php | 117 ++++++++++++++++++
...delToElasticaIdentifierTransformerTest.php | 66 ++++++++++
2 files changed, 183 insertions(+)
create mode 100644 Tests/Persister/ObjectSerializerPersisterTest.php
create mode 100644 Tests/Transformer/ModelToElasticaIdentifierTransformerTest.php
diff --git a/Tests/Persister/ObjectSerializerPersisterTest.php b/Tests/Persister/ObjectSerializerPersisterTest.php
new file mode 100644
index 0000000..10c63ab
--- /dev/null
+++ b/Tests/Persister/ObjectSerializerPersisterTest.php
@@ -0,0 +1,117 @@
+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('addObject');
+
+ $objectPersister = new ObjectSerializerPersister($typeMock, $transformer, 'SomeClass');
+ $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('addObject');
+
+ $objectPersister = new ObjectSerializerPersister($typeMock, $transformer, 'SomeClass');
+ $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('addObject');
+
+ $objectPersister = new ObjectSerializerPersister($typeMock, $transformer, 'SomeClass');
+ $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->exactly(2))
+ ->method('addObject');
+ $typeMock->expects($this->never())
+ ->method('addObjects');
+
+ $objectPersister = new ObjectSerializerPersister($typeMock, $transformer, 'SomeClass');
+ $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/Transformer/ModelToElasticaIdentifierTransformerTest.php b/Tests/Transformer/ModelToElasticaIdentifierTransformerTest.php
new file mode 100644
index 0000000..59a747a
--- /dev/null
+++ b/Tests/Transformer/ModelToElasticaIdentifierTransformerTest.php
@@ -0,0 +1,66 @@
+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;
+ }
+}
From ab0c27c4819bba166511bde3705861ca68001717 Mon Sep 17 00:00:00 2001
From: Jeremy Mikola
Date: Wed, 17 Jul 2013 15:53:32 -0400
Subject: [PATCH 060/447] Fix expected exception class (related to #338)
This corrects a typo in a66a37aebd7424e9a82e81bd1a3760abb735ea7e.
---
Tests/Transformer/ModelToElasticaAutoTransformerTest.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
index daa6512..cb980da 100644
--- a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
+++ b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
@@ -208,8 +208,8 @@ class ModelToElasticaAutoTransformerTest extends \PHPUnit_Framework_TestCase
/* ProperyAccess 2.3+ removed PropertyAccessDeniedException, so we
* must expect NoSuchPropertyException in its absence.
*/
- $expectedException = class_exists('Symfony\Component\Form\Exception\PropertyAccessDeniedException')
- ? 'Symfony\Component\Form\Exception\PropertyAccessDeniedException'
+ $expectedException = class_exists('Symfony\Component\PropertyAccess\Exception\PropertyAccessDeniedException')
+ ? 'Symfony\Component\PropertyAccess\Exception\PropertyAccessDeniedException'
: 'Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException';
} else {
$expectedException = 'Symfony\Component\Form\Exception\PropertyAccessDeniedException';
From 300d189a9d62559c2fc7c65d1cef03f060cc7d9f Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Thu, 18 Jul 2013 10:51:51 +0200
Subject: [PATCH 061/447] renaming services to avoid potential conflicts
---
DependencyInjection/FOSElasticaExtension.php | 4 ++--
Resources/config/config.xml | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 9a15a83..e0f7a2d 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -309,7 +309,7 @@ class FOSElasticaExtension extends Extension
return $typeConfig['model_to_elastica_transformer']['service'];
}
if ($this->serializerConfig) {
- $abstractId = sprintf('fos_elastica.model_to_elastica_transformer.prototype.identifier');
+ $abstractId = sprintf('fos_elastica.model_to_elastica_identifier_transformer');
} else {
$abstractId = sprintf('fos_elastica.model_to_elastica_transformer.prototype.auto');
}
@@ -326,7 +326,7 @@ class FOSElasticaExtension extends Extension
protected function loadObjectPersister(array $typeConfig, Definition $typeDef, ContainerBuilder $container, $indexName, $typeName, $transformerId)
{
if ($this->serializerConfig) {
- $abstractId = sprintf('fos_elastica.object_serializer_persister.prototype');
+ $abstractId = sprintf('fos_elastica.object_serializer_persister');
$arguments = array(
$typeDef,
new Reference($transformerId),
diff --git a/Resources/config/config.xml b/Resources/config/config.xml
index 3f5f7cf..4d85d9f 100644
--- a/Resources/config/config.xml
+++ b/Resources/config/config.xml
@@ -52,7 +52,7 @@
-
+
@@ -70,7 +70,7 @@
-
+
From 77156b35aa0f70420b555151d9700591de1f6fc8 Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Thu, 18 Jul 2013 10:54:11 +0200
Subject: [PATCH 062/447] some formatting and cleaning up
---
Persister/ObjectSerializerPersister.php | 8 ++++----
Tests/Transformer/ModelToElasticaAutoTransformerTest.php | 1 -
.../ModelToElasticaIdentifierTransformerTest.php | 1 -
Transformer/ModelToElasticaIdentifierTransformer.php | 4 ++--
4 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/Persister/ObjectSerializerPersister.php b/Persister/ObjectSerializerPersister.php
index db8122a..269515b 100644
--- a/Persister/ObjectSerializerPersister.php
+++ b/Persister/ObjectSerializerPersister.php
@@ -16,9 +16,9 @@ class ObjectSerializerPersister extends ObjectPersister
{
public function __construct(Type $type, ModelToElasticaTransformerInterface $transformer, $objectClass)
{
- $this->type = $type;
- $this->transformer = $transformer;
- $this->objectClass = $objectClass;
+ $this->type = $type;
+ $this->transformer = $transformer;
+ $this->objectClass = $objectClass;
}
/**
@@ -38,7 +38,7 @@ class ObjectSerializerPersister extends ObjectPersister
*
* @param object $object
* @return null
- **/
+ */
public function replaceOne($object)
{
$document = $this->transformToElasticaDocument($object);
diff --git a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
index cbcb6bd..16bb5cd 100644
--- a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
+++ b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
@@ -113,7 +113,6 @@ class ModelToElasticaAutoTransformerTest extends \PHPUnit_Framework_TestCase
public function setUp()
{
if (!class_exists('Elastica\Document')) {
- ;
$this->markTestSkipped('The Elastica library classes are not available');
}
}
diff --git a/Tests/Transformer/ModelToElasticaIdentifierTransformerTest.php b/Tests/Transformer/ModelToElasticaIdentifierTransformerTest.php
index 59a747a..f1a77d4 100644
--- a/Tests/Transformer/ModelToElasticaIdentifierTransformerTest.php
+++ b/Tests/Transformer/ModelToElasticaIdentifierTransformerTest.php
@@ -26,7 +26,6 @@ class ModelToElasticaIdentifierTransformerTest extends \PHPUnit_Framework_TestCa
public function setUp()
{
if (!class_exists('Elastica\Document')) {
- ;
$this->markTestSkipped('The Elastica library classes are not available');
}
}
diff --git a/Transformer/ModelToElasticaIdentifierTransformer.php b/Transformer/ModelToElasticaIdentifierTransformer.php
index 416eaf7..654850f 100644
--- a/Transformer/ModelToElasticaIdentifierTransformer.php
+++ b/Transformer/ModelToElasticaIdentifierTransformer.php
@@ -5,8 +5,8 @@ namespace FOS\ElasticaBundle\Transformer;
use Elastica\Document;
/**
- * Creates an elastica document with the id of
- * the doctrine object as elastica document id
+ * Creates an Elastica document with the ID of
+ * the Doctrine object as Elastica document ID
*/
class ModelToElasticaIdentifierTransformer extends ModelToElasticaAutoTransformer
{
From 37cfdb0df79298ece68280984a8313e71a58fde0 Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Thu, 18 Jul 2013 10:56:25 +0200
Subject: [PATCH 063/447] refactoring some code
---
DependencyInjection/FOSElasticaExtension.php | 21 ++++++++------------
1 file changed, 8 insertions(+), 13 deletions(-)
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index e0f7a2d..68e21dd 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -325,21 +325,16 @@ 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 = sprintf('fos_elastica.object_serializer_persister');
- $arguments = array(
- $typeDef,
- new Reference($transformerId),
- $typeConfig['model'],
- );
+ $abstractId = 'fos_elastica.object_serializer_persister';
} else {
- $abstractId = sprintf('fos_elastica.object_persister.prototype');
- $arguments = array(
- $typeDef,
- new Reference($transformerId),
- $typeConfig['model'],
- $this->typeFields[sprintf('%s/%s', $indexName, $typeName)],
- );
+ $abstractId = 'fos_elastica.object_persister.prototype';
+ $arguments[] = $this->typeFields[sprintf('%s/%s', $indexName, $typeName)];
}
$serviceId = sprintf('fos_elastica.object_persister.%s.%s', $indexName, $typeName);
$serviceDef = new DefinitionDecorator($abstractId);
From 617b9d3f4b025ba38f33bfa3989f8fa451982dff Mon Sep 17 00:00:00 2001
From: NicolasBadey
Date: Wed, 17 Jul 2013 13:35:55 +0200
Subject: [PATCH 064/447] Recalculate pagination Query size if a limit is
already set
---
Paginator/RawPaginatorAdapter.php | 39 +++++++++++++++++++++++++++----
1 file changed, 34 insertions(+), 5 deletions(-)
diff --git a/Paginator/RawPaginatorAdapter.php b/Paginator/RawPaginatorAdapter.php
index 3ed8638..ab92dd4 100644
--- a/Paginator/RawPaginatorAdapter.php
+++ b/Paginator/RawPaginatorAdapter.php
@@ -8,6 +8,7 @@ use Elastica\ResultSet;
use FOS\ElasticaBundle\Paginator\PaginatorAdapterInterface;
use FOS\ElasticaBundle\Paginator\RawPartialResults;
use FOS\ElasticaBundle\Paginator\PartialResultsInterface;
+use InvalidArgumentException;
/**
* Allows pagination of Elastica\Query. Does not map results
@@ -17,12 +18,17 @@ class RawPaginatorAdapter implements PaginatorAdapterInterface
/**
* @var SearchableInterface the object to search in
*/
- private $searchable = null;
+ private $searchable;
/**
* @var Query the query to search
*/
- private $query = null;
+ private $query;
+
+ /**
+ * @var integer the number of hits
+ */
+ private $totalHits;
/**
* @see PaginatorAdapterInterface::__construct
@@ -45,11 +51,28 @@ class RawPaginatorAdapter implements PaginatorAdapterInterface
*/
protected function getElasticaResults($offset, $itemCountPerPage)
{
+ $offset = (integer) $offset;
+ $itemCountPerPage = (integer) $itemCountPerPage;
+ $size = $this->query->hasParam('size')
+ ? (integer) $this->query->getParam('size')
+ : null;
+
+ if ($size && $size < $offset + $itemCountPerPage) {
+ $itemCountPerPage = $size - $offset;
+ }
+
+ if ($itemCountPerPage < 1) {
+ throw new InvalidArgumentException('$itemCountPerPage must be greater than zero');
+ }
+
$query = clone $this->query;
$query->setFrom($offset);
- $query->setLimit($itemCountPerPage);
+ $query->setSize($itemCountPerPage);
- return $this->searchable->search($query);
+ $resultSet = $this->searchable->search($query);
+ $this->totalHits = $resultSet->getTotalHits();
+
+ return $resultSet;
}
/**
@@ -71,6 +94,12 @@ class RawPaginatorAdapter implements PaginatorAdapterInterface
*/
public function getTotalHits()
{
- return $this->searchable->search($this->query)->getTotalHits();
+ if ( ! isset($this->totalHits)) {
+ $this->totalHits = $this->searchable->search($this->query)->getTotalHits();
+ }
+
+ return $this->query->hasParam('size')
+ ? min($this->totalHits, (integer) $this->query->getParam('size'))
+ : $this->totalHits;
}
}
From e2b6177a33050a7dcfcb424e0c9697d81f840221 Mon Sep 17 00:00:00 2001
From: cedric lombardot
Date: Tue, 6 Aug 2013 20:48:38 +0200
Subject: [PATCH 065/447] Fix ElasticaToModelTransformer the transform closure
use Result instead of Document
---
Propel/ElasticaToModelTransformer.php | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/Propel/ElasticaToModelTransformer.php b/Propel/ElasticaToModelTransformer.php
index 4f006a7..952673b 100644
--- a/Propel/ElasticaToModelTransformer.php
+++ b/Propel/ElasticaToModelTransformer.php
@@ -2,7 +2,6 @@
namespace FOS\ElasticaBundle\Propel;
-use Elastica\Document;
use FOS\ElasticaBundle\HybridResult;
use FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerInterface;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
@@ -71,9 +70,10 @@ class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface
*/
public function transform(array $elasticaObjects)
{
- $ids = array_map(function(Document $elasticaObject) {
- return $elasticaObject->getId();
- }, $elasticaObjects);
+ $ids = array();
+ foreach ($elasticaObjects as $elasticaObject) {
+ $ids[] = $elasticaObject->getId();
+ }
$objects = $this->findByIdentifiers($ids, $this->options['hydrate']);
From c15caf309632c95b840e797a7ae54f501b1abe3b Mon Sep 17 00:00:00 2001
From: Jeremy Mikola
Date: Fri, 9 Aug 2013 13:56:51 -0400
Subject: [PATCH 066/447] Code and documentation formatting in Propel
transformer class
---
Propel/ElasticaToModelTransformer.php | 67 ++++++++++++++-------------
1 file changed, 35 insertions(+), 32 deletions(-)
diff --git a/Propel/ElasticaToModelTransformer.php b/Propel/ElasticaToModelTransformer.php
index 952673b..af5f8ab 100644
--- a/Propel/ElasticaToModelTransformer.php
+++ b/Propel/ElasticaToModelTransformer.php
@@ -7,40 +7,41 @@ use FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerInterface;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
/**
- * Maps Elastica documents with Propel objects
- * This mapper assumes an exact match between
- * elastica documents ids and propel object ids
+ * Maps Elastica documents with Propel objects.
+ *
+ * This mapper assumes an exact match between Elastica document IDs and Propel
+ * entity IDs.
*
* @author William Durand
*/
class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface
{
/**
- * Class of the model to map to the elastica documents
+ * Propel model class to map to Elastica documents.
*
* @var string
*/
protected $objectClass = null;
/**
- * Optional parameters
+ * Transformer options.
*
* @var array
*/
protected $options = array(
'hydrate' => true,
- 'identifier' => 'id'
+ 'identifier' => 'id',
);
/**
- * PropertyAccessor instance
+ * PropertyAccessor instance.
*
* @var PropertyAccessorInterface
*/
protected $propertyAccessor;
/**
- * Instantiates a new Mapper
+ * Constructor.
*
* @param string $objectClass
* @param array $options
@@ -48,11 +49,11 @@ class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface
public function __construct($objectClass, array $options = array())
{
$this->objectClass = $objectClass;
- $this->options = array_merge($this->options, $options);
+ $this->options = array_merge($this->options, $options);
}
/**
- * Set the PropertyAccessor
+ * Set the PropertyAccessor instance.
*
* @param PropertyAccessorInterface $propertyAccessor
*/
@@ -62,11 +63,11 @@ class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface
}
/**
- * Transforms an array of elastica objects into an array of
- * model objects fetched from the propel repository
+ * Transforms an array of Elastica document into an array of Propel entities
+ * fetched from the database.
*
- * @param Document[] $elasticaObjects array of elastica objects
- * @return array
+ * @param array $elasticaObjects
+ * @return array|\ArrayObject
*/
public function transform(array $elasticaObjects)
{
@@ -77,18 +78,19 @@ class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface
$objects = $this->findByIdentifiers($ids, $this->options['hydrate']);
- // sort objects in the order of ids
+ // Sort objects in the order of their IDs
$idPos = array_flip($ids);
$identifier = $this->options['identifier'];
$propertyAccessor = $this->propertyAccessor;
+
+ $sortCallback = function($a, $b) use ($idPos, $identifier, $propertyAccessor) {
+ return $idPos[$propertyAccessor->getValue($a, $identifier)] > $idPos[$propertyAccessor->getValue($b, $identifier)];
+ };
+
if (is_object($objects)) {
- $objects->uasort(function($a, $b) use ($idPos, $identifier, $propertyAccessor) {
- return $idPos[$propertyAccessor->getValue($a, $identifier)] > $idPos[$propertyAccessor->getValue($b, $identifier)];
- });
+ $objects->uasort($sortCallback);
} else {
- usort($objects, function($a, $b) use ($idPos, $identifier, $propertyAccessor) {
- return $idPos[$propertyAccessor->getValue($a, $identifier)] > $idPos[$propertyAccessor->getValue($b, $identifier)];
- });
+ usort($objects, $sortCallback);
}
return $objects;
@@ -126,11 +128,14 @@ class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface
}
/**
- * Fetch objects for theses identifier values
+ * Fetch Propel entities for the given identifier values.
*
- * @param array $identifierValues ids values
- * @param boolean $hydrate whether or not to hydrate the objects, false returns arrays
- * @return array of objects or arrays
+ * If $hydrate is false, the returned array elements will be arrays.
+ * Otherwise, the results will be hydrated to instances of the model class.
+ *
+ * @param array $identifierValues Identifier values
+ * @param boolean $hydrate Whether or not to hydrate the results
+ * @return array
*/
protected function findByIdentifiers(array $identifierValues, $hydrate)
{
@@ -140,7 +145,7 @@ class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface
$query = $this->createQuery($this->objectClass, $this->options['identifier'], $identifierValues);
- if (!$hydrate) {
+ if ( ! $hydrate) {
return $query->toArray();
}
@@ -150,9 +155,9 @@ class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface
/**
* Create a query to use in the findByIdentifiers() method.
*
- * @param string $class the model class
- * @param string $identifierField like 'id'
- * @param array $identifierValues ids values
+ * @param string $class Propel model class
+ * @param string $identifierField Identifier field name (e.g. "id")
+ * @param array $identifierValues Identifier values
* @return \ModelCriteria
*/
protected function createQuery($class, $identifierField, array $identifierValues)
@@ -160,9 +165,7 @@ class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface
$queryClass = $class.'Query';
$filterMethod = 'filterBy'.$this->camelize($identifierField);
- return $queryClass::create()
- ->$filterMethod($identifierValues)
- ;
+ return $queryClass::create()->$filterMethod($identifierValues);
}
/**
From 79501dc319606971b2fa35b088ae23336e42f423 Mon Sep 17 00:00:00 2001
From: Richard Miller
Date: Mon, 12 Aug 2013 11:04:54 +0100
Subject: [PATCH 067/447] Add moreLikeThis query to finder
---
Finder/TransformedFinder.php | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/Finder/TransformedFinder.php b/Finder/TransformedFinder.php
index e1eade8..c520f08 100644
--- a/Finder/TransformedFinder.php
+++ b/Finder/TransformedFinder.php
@@ -45,6 +45,22 @@ class TransformedFinder implements PaginatedFinderInterface
return $this->transformer->hybridTransform($results);
}
+ /**
+ * Find documents similar to one with passed id.
+ *
+ * @param integer $id
+ * @param array $params
+ * @param array $query
+ * @return array of model objects
+ **/
+ public function moreLikeThis($id, $params = array(), $query = array())
+ {
+ $doc = new Document($id);
+ $results = $this->searchable->moreLikeThis($doc, $params, $query)->getResults();
+
+ return $this->transformer->transform($results);
+ }
+
/**
* @param $query
* @param null|int $limit
From e97b60fc7e4315a7ae62174f000f620bb1ae0203 Mon Sep 17 00:00:00 2001
From: Richard Fullmer
Date: Tue, 4 Jun 2013 11:45:45 -0700
Subject: [PATCH 068/447] Ignore failed deletions in ObjectPersister
This probably isn't the best way to solve my problem,
but the issue is this.
Step 1: Create a new doctrine entity for which it's `is_indexable_callback`
returns false. When doctrine flushes this entity to the database,
elastia will not index it with elastic search. (Correct)
Step 2: Update your doctrine entity and change some fields so
that `is_indexable_callback` _still_ returns false. Persist and flush
to the database.
At this point, the postUpdate listener on ElastiaBundle is called
and since the `is_indexable_callback` returns false, it believes
it needs to remove it from the elastic search index and queues it
for deletion. The deletion of course fails because it was never there
in the first place.
This solution simply ignores failures from deletions in the index.
Perhaps a better solution would be to have a smarter listener
that could determine if the entity was previously present in the
elastic search index or not, but that would require significant
refactoring.
Addresses issues discuseed in #284
Credit to @bbeaulant for simple solution. Opening a PR to
discuss more generally.
---
Persister/ObjectPersister.php | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/Persister/ObjectPersister.php b/Persister/ObjectPersister.php
index 643b817..450e43b 100644
--- a/Persister/ObjectPersister.php
+++ b/Persister/ObjectPersister.php
@@ -2,6 +2,7 @@
namespace FOS\ElasticaBundle\Persister;
+use Elastica\Exception\NotFoundException;
use FOS\ElasticaBundle\Transformer\ModelToElasticaTransformerInterface;
use Elastica\Type;
use Elastica\Document;
@@ -48,7 +49,9 @@ class ObjectPersister implements ObjectPersisterInterface
public function replaceOne($object)
{
$document = $this->transformToElasticaDocument($object);
- $this->type->deleteById($document->getId());
+ try {
+ $this->type->deleteById($document->getId());
+ } catch (NotFoundException $e) {}
$this->type->addDocument($document);
}
@@ -61,7 +64,9 @@ class ObjectPersister implements ObjectPersisterInterface
public function deleteOne($object)
{
$document = $this->transformToElasticaDocument($object);
- $this->type->deleteById($document->getId());
+ try {
+ $this->type->deleteById($document->getId());
+ } catch (NotFoundException $e) {}
}
/**
@@ -73,7 +78,9 @@ class ObjectPersister implements ObjectPersisterInterface
**/
public function deleteById($id)
{
- $this->type->deleteById($id);
+ try {
+ $this->type->deleteById($id);
+ } catch (NotFoundException $e) {}
}
From 3c01ebb7756a487e2809afeecdc3af87d7bbe20a Mon Sep 17 00:00:00 2001
From: cedric lombardot
Date: Tue, 6 Aug 2013 20:48:38 +0200
Subject: [PATCH 069/447] Fix ElasticaToModelTransformer the transform closure
use Result instead of Document
---
Propel/ElasticaToModelTransformer.php | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/Propel/ElasticaToModelTransformer.php b/Propel/ElasticaToModelTransformer.php
index 4f006a7..952673b 100644
--- a/Propel/ElasticaToModelTransformer.php
+++ b/Propel/ElasticaToModelTransformer.php
@@ -2,7 +2,6 @@
namespace FOS\ElasticaBundle\Propel;
-use Elastica\Document;
use FOS\ElasticaBundle\HybridResult;
use FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerInterface;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
@@ -71,9 +70,10 @@ class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface
*/
public function transform(array $elasticaObjects)
{
- $ids = array_map(function(Document $elasticaObject) {
- return $elasticaObject->getId();
- }, $elasticaObjects);
+ $ids = array();
+ foreach ($elasticaObjects as $elasticaObject) {
+ $ids[] = $elasticaObject->getId();
+ }
$objects = $this->findByIdentifiers($ids, $this->options['hydrate']);
From b40149cbdc74d916b6035bdbd36a9ad85d9de043 Mon Sep 17 00:00:00 2001
From: Jeremy Mikola
Date: Fri, 9 Aug 2013 13:56:51 -0400
Subject: [PATCH 070/447] Code and documentation formatting in Propel
transformer class
---
Propel/ElasticaToModelTransformer.php | 67 ++++++++++++++-------------
1 file changed, 35 insertions(+), 32 deletions(-)
diff --git a/Propel/ElasticaToModelTransformer.php b/Propel/ElasticaToModelTransformer.php
index 952673b..af5f8ab 100644
--- a/Propel/ElasticaToModelTransformer.php
+++ b/Propel/ElasticaToModelTransformer.php
@@ -7,40 +7,41 @@ use FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerInterface;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
/**
- * Maps Elastica documents with Propel objects
- * This mapper assumes an exact match between
- * elastica documents ids and propel object ids
+ * Maps Elastica documents with Propel objects.
+ *
+ * This mapper assumes an exact match between Elastica document IDs and Propel
+ * entity IDs.
*
* @author William Durand
*/
class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface
{
/**
- * Class of the model to map to the elastica documents
+ * Propel model class to map to Elastica documents.
*
* @var string
*/
protected $objectClass = null;
/**
- * Optional parameters
+ * Transformer options.
*
* @var array
*/
protected $options = array(
'hydrate' => true,
- 'identifier' => 'id'
+ 'identifier' => 'id',
);
/**
- * PropertyAccessor instance
+ * PropertyAccessor instance.
*
* @var PropertyAccessorInterface
*/
protected $propertyAccessor;
/**
- * Instantiates a new Mapper
+ * Constructor.
*
* @param string $objectClass
* @param array $options
@@ -48,11 +49,11 @@ class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface
public function __construct($objectClass, array $options = array())
{
$this->objectClass = $objectClass;
- $this->options = array_merge($this->options, $options);
+ $this->options = array_merge($this->options, $options);
}
/**
- * Set the PropertyAccessor
+ * Set the PropertyAccessor instance.
*
* @param PropertyAccessorInterface $propertyAccessor
*/
@@ -62,11 +63,11 @@ class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface
}
/**
- * Transforms an array of elastica objects into an array of
- * model objects fetched from the propel repository
+ * Transforms an array of Elastica document into an array of Propel entities
+ * fetched from the database.
*
- * @param Document[] $elasticaObjects array of elastica objects
- * @return array
+ * @param array $elasticaObjects
+ * @return array|\ArrayObject
*/
public function transform(array $elasticaObjects)
{
@@ -77,18 +78,19 @@ class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface
$objects = $this->findByIdentifiers($ids, $this->options['hydrate']);
- // sort objects in the order of ids
+ // Sort objects in the order of their IDs
$idPos = array_flip($ids);
$identifier = $this->options['identifier'];
$propertyAccessor = $this->propertyAccessor;
+
+ $sortCallback = function($a, $b) use ($idPos, $identifier, $propertyAccessor) {
+ return $idPos[$propertyAccessor->getValue($a, $identifier)] > $idPos[$propertyAccessor->getValue($b, $identifier)];
+ };
+
if (is_object($objects)) {
- $objects->uasort(function($a, $b) use ($idPos, $identifier, $propertyAccessor) {
- return $idPos[$propertyAccessor->getValue($a, $identifier)] > $idPos[$propertyAccessor->getValue($b, $identifier)];
- });
+ $objects->uasort($sortCallback);
} else {
- usort($objects, function($a, $b) use ($idPos, $identifier, $propertyAccessor) {
- return $idPos[$propertyAccessor->getValue($a, $identifier)] > $idPos[$propertyAccessor->getValue($b, $identifier)];
- });
+ usort($objects, $sortCallback);
}
return $objects;
@@ -126,11 +128,14 @@ class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface
}
/**
- * Fetch objects for theses identifier values
+ * Fetch Propel entities for the given identifier values.
*
- * @param array $identifierValues ids values
- * @param boolean $hydrate whether or not to hydrate the objects, false returns arrays
- * @return array of objects or arrays
+ * If $hydrate is false, the returned array elements will be arrays.
+ * Otherwise, the results will be hydrated to instances of the model class.
+ *
+ * @param array $identifierValues Identifier values
+ * @param boolean $hydrate Whether or not to hydrate the results
+ * @return array
*/
protected function findByIdentifiers(array $identifierValues, $hydrate)
{
@@ -140,7 +145,7 @@ class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface
$query = $this->createQuery($this->objectClass, $this->options['identifier'], $identifierValues);
- if (!$hydrate) {
+ if ( ! $hydrate) {
return $query->toArray();
}
@@ -150,9 +155,9 @@ class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface
/**
* Create a query to use in the findByIdentifiers() method.
*
- * @param string $class the model class
- * @param string $identifierField like 'id'
- * @param array $identifierValues ids values
+ * @param string $class Propel model class
+ * @param string $identifierField Identifier field name (e.g. "id")
+ * @param array $identifierValues Identifier values
* @return \ModelCriteria
*/
protected function createQuery($class, $identifierField, array $identifierValues)
@@ -160,9 +165,7 @@ class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface
$queryClass = $class.'Query';
$filterMethod = 'filterBy'.$this->camelize($identifierField);
- return $queryClass::create()
- ->$filterMethod($identifierValues)
- ;
+ return $queryClass::create()->$filterMethod($identifierValues);
}
/**
From 41e132140e2c9164c8b831579793612fd2b743d5 Mon Sep 17 00:00:00 2001
From: Robert Plant
Date: Wed, 14 Aug 2013 10:20:45 +0100
Subject: [PATCH 071/447] Added ability to access facets with paginated results
---
Paginator/FantaPaginatorAdapter.php | 12 ++++++++++++
Paginator/PaginatorAdapterInterface.php | 7 +++++++
Paginator/RawPaginatorAdapter.php | 21 ++++++++++++++++++++-
README.md | 16 ++++++++++++++++
4 files changed, 55 insertions(+), 1 deletion(-)
diff --git a/Paginator/FantaPaginatorAdapter.php b/Paginator/FantaPaginatorAdapter.php
index 4307abc..a2f8c0e 100644
--- a/Paginator/FantaPaginatorAdapter.php
+++ b/Paginator/FantaPaginatorAdapter.php
@@ -29,6 +29,18 @@ class FantaPaginatorAdapter implements AdapterInterface
return $this->adapter->getTotalHits();
}
+ /**
+ * Returns Facets
+ *
+ * @return mixed
+ *
+ * @api
+ */
+ public function getFacets()
+ {
+ return $this->adapter->getFacets();
+ }
+
/**
* Returns an slice of the results.
*
diff --git a/Paginator/PaginatorAdapterInterface.php b/Paginator/PaginatorAdapterInterface.php
index 29eb66c..9182973 100644
--- a/Paginator/PaginatorAdapterInterface.php
+++ b/Paginator/PaginatorAdapterInterface.php
@@ -26,4 +26,11 @@ interface PaginatorAdapterInterface
* @api
*/
function getResults($offset, $length);
+
+ /**
+ * Returns Facets
+ *
+ * @return mixed
+ */
+ function getFacets();
}
diff --git a/Paginator/RawPaginatorAdapter.php b/Paginator/RawPaginatorAdapter.php
index ab92dd4..125cd35 100644
--- a/Paginator/RawPaginatorAdapter.php
+++ b/Paginator/RawPaginatorAdapter.php
@@ -30,6 +30,11 @@ class RawPaginatorAdapter implements PaginatorAdapterInterface
*/
private $totalHits;
+ /**
+ * @array for the facets
+ */
+ private $facets;
+
/**
* @see PaginatorAdapterInterface::__construct
*
@@ -71,7 +76,7 @@ class RawPaginatorAdapter implements PaginatorAdapterInterface
$resultSet = $this->searchable->search($query);
$this->totalHits = $resultSet->getTotalHits();
-
+ $this->facets = $resultSet->getFacets();
return $resultSet;
}
@@ -102,4 +107,18 @@ class RawPaginatorAdapter implements PaginatorAdapterInterface
? min($this->totalHits, (integer) $this->query->getParam('size'))
: $this->totalHits;
}
+
+ /**
+ * Returns Facets
+ *
+ * @return mixed
+ */
+ public function getFacets()
+ {
+ if ( ! isset($this->facets)) {
+ $this->facets = $this->searchable->search($this->query)->getFacets();
+ }
+
+ return $this->facets;
+ }
}
diff --git a/README.md b/README.md
index ccae8db..6b92ce3 100644
--- a/README.md
+++ b/README.md
@@ -409,6 +409,22 @@ still also getting the entity.
$result = $hybridResult->getResult();
}
+If you would like to access facets while using Pagerfanta they can be accessed through
+the Adapter seen in the example below.
+
+```php
+$query = new \Elastica\Query();
+$facet = new \Elastica\Facet\Terms('tags');
+$facet->setField('companyGroup');
+$query->addFacet($facet);
+
+$companies = $finder->findPaginated($query);
+$companies->setMaxPerPage($params['limit']);
+$companies->setCurrentPage($params['page']);
+
+$facets = $companies->getAdapter()->getFacets());
+```
+
##### Index wide finder
You can also define a finder that will work on the entire index. Adjust your index
From 655102875340d7a6e80aa406f7a9855daa388b8a Mon Sep 17 00:00:00 2001
From: Peter Kokot
Date: Sun, 15 Sep 2013 09:17:13 +0200
Subject: [PATCH 072/447] Update LICENSE
Updated license year range
---
Resources/meta/LICENSE | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Resources/meta/LICENSE b/Resources/meta/LICENSE
index 39afd28..314bd5b 100644
--- a/Resources/meta/LICENSE
+++ b/Resources/meta/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2011 Exercise.com, Inc
+Copyright (c) 2011-2013 Exercise.com, Inc
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
From 2b942a6edf49c22d02b38610817f7852b37c2a56 Mon Sep 17 00:00:00 2001
From: Peter Kokot
Date: Mon, 16 Sep 2013 19:47:05 +0200
Subject: [PATCH 073/447] LICENSE file removed in favor of
Resources/meta/LICENSE file
---
LICENSE | 18 ------------------
1 file changed, 18 deletions(-)
delete mode 100644 LICENSE
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index d0ba561..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,18 +0,0 @@
-Copyright (c) 2012 Exercise.com
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
From ac56775791ced221946ad07f2b1042fc47ea70dd Mon Sep 17 00:00:00 2001
From: David Buchmann
Date: Thu, 26 Sep 2013 10:02:48 +0200
Subject: [PATCH 074/447] add a note how to use the parent mapping
---
README.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/README.md b/README.md
index bad644e..30c6e18 100644
--- a/README.md
+++ b/README.md
@@ -188,6 +188,9 @@ The parent filed declaration has the following values:
* `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`.
+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`
fos_elastica:
From 85a10613bad047b4612a362e9ff1ae366d9b506e Mon Sep 17 00:00:00 2001
From: Thierry Marianne
Date: Thu, 17 Oct 2013 22:32:11 +0200
Subject: [PATCH 075/447] Fix type hinting in "Manual provider" example
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 30c6e18..22d4100 100644
--- a/README.md
+++ b/README.md
@@ -326,9 +326,9 @@ Its class must implement `FOS\ElasticaBundle\Provider\ProviderInterface`.
/**
* Insert the repository objects in the type index
*
- * @param Closure $loggerClosure
+ * @param \Closure $loggerClosure
*/
- public function populate(Closure $loggerClosure = null)
+ public function populate(\Closure $loggerClosure = null)
{
if ($loggerClosure) {
$loggerClosure('Indexing users');
From 9d1201099d591915d6d8f511f108570f6b296549 Mon Sep 17 00:00:00 2001
From: Karel Souffriau
Date: Mon, 28 Oct 2013 17:07:49 +0100
Subject: [PATCH 076/447] Add date format field
---
DependencyInjection/Configuration.php | 3 +-
README.md | 18 ++++++++++
.../DependencyInjection/ConfigurationTest.php | 34 +++++++++++++++++++
3 files changed, 54 insertions(+), 1 deletion(-)
create mode 100644 Tests/DependencyInjection/ConfigurationTest.php
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index df0fe19..d44e714 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -325,7 +325,8 @@ class Configuration implements ConfigurationInterface
->scalarNode('type')->end()
->scalarNode('identifier')->defaultValue('id')->end()
->end()
- ->end();
+ ->end()
+ ->scalarNode('format')->end();
if (isset($nestings['fields'])) {
$this->addNestedFieldConfig($node, $nestings, 'fields');
diff --git a/README.md b/README.md
index c289cd6..1c5c5f3 100644
--- a/README.md
+++ b/README.md
@@ -666,3 +666,21 @@ fos_elastica:
provider:
finder:
```
+
+#### Date format example
+
+If you want to specify a [date format](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-date-format.html):
+
+```yaml
+fos_elastica:
+ clients:
+ default: { host: localhost, port: 9200 }
+ indexes:
+ site:
+ types:
+ user:
+ mappings:
+ username: { type: string }
+ lastlogin: { type: date, format: basic_date_time }
+ birthday: { type: date, format: "yyyy-MM-dd" }
+```
diff --git a/Tests/DependencyInjection/ConfigurationTest.php b/Tests/DependencyInjection/ConfigurationTest.php
new file mode 100644
index 0000000..f410621
--- /dev/null
+++ b/Tests/DependencyInjection/ConfigurationTest.php
@@ -0,0 +1,34 @@
+configuration = new Configuration(array());
+ }
+
+ public function testEmptyConfigContainsFormatMappingOptionNode()
+ {
+ $tree = $this->configuration->getConfigTree();
+ $children = $tree->getChildren();
+ $children = $children['indexes']->getPrototype()->getChildren();
+ $typeNodes = $children['types']->getPrototype()->getChildren();
+ $mappings = $typeNodes['mappings']->getPrototype()->getChildren();
+
+ $this->assertArrayHasKey('format', $mappings);
+ $this->assertInstanceOf('Symfony\Component\Config\Definition\ScalarNode', $mappings['format']);
+ $this->assertNull($mappings['format']->getDefaultValue());
+ }
+}
From 43e026500cde3db4abaf2f0b145a5dc7b4787197 Mon Sep 17 00:00:00 2001
From: Matyas Somfai
Date: Tue, 8 Oct 2013 12:00:04 +0200
Subject: [PATCH 077/447] added new options to fos:elastica:populate command
and options array parameter to ProviderInterface
removed assume-yes option as the no-interaction option has the same purpose
---
Command/PopulateCommand.php | 36 ++++++++++++++++++++++++----------
Doctrine/AbstractProvider.php | 11 ++++++++---
Propel/Provider.php | 11 ++++++++---
Provider/ProviderInterface.php | 3 ++-
README.md | 3 ++-
5 files changed, 46 insertions(+), 18 deletions(-)
diff --git a/Command/PopulateCommand.php b/Command/PopulateCommand.php
index 3fa7cd2..58e5e9f 100755
--- a/Command/PopulateCommand.php
+++ b/Command/PopulateCommand.php
@@ -3,6 +3,7 @@
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;
@@ -43,6 +44,9 @@ class PopulateCommand extends ContainerAwareCommand
->addOption('index', null, InputOption::VALUE_OPTIONAL, 'The index to repopulate')
->addOption('type', null, InputOption::VALUE_OPTIONAL, 'The type to repopulate')
->addOption('no-reset', null, InputOption::VALUE_NONE, 'Do not reset index before populating')
+ ->addOption('offset', null, InputOption::VALUE_REQUIRED, 'Start indexing at offset', 0)
+ ->addOption('sleep', null, InputOption::VALUE_REQUIRED, 'Sleep time between persisting iterations (microseconds)', 0)
+ ->addOption('batch-size', null, InputOption::VALUE_REQUIRED, 'Index packet size (overrides provider config option)')
->setDescription('Populates search indexes from providers')
;
}
@@ -62,9 +66,19 @@ class PopulateCommand extends ContainerAwareCommand
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
- $index = $input->getOption('index');
- $type = $input->getOption('type');
- $reset = $input->getOption('no-reset') ? false : true;
+ $index = $input->getOption('index');
+ $type = $input->getOption('type');
+ $reset = $input->getOption('no-reset') ? false : true;
+ $noInteraction = $input->getOption('no-interaction');
+ $options = $input->getOptions();
+
+ if (!$noInteraction && $reset && $input->getOption('offset')) {
+ /** @var DialogHelper $dialog */
+ $dialog = $this->getHelperSet()->get('dialog');
+ if (!$dialog->askConfirmation($output, 'You chose to reset the index and start indexing with an offset. Do you really want to do that?', true)) {
+ return;
+ }
+ }
if (null === $index && null !== $type) {
throw new \InvalidArgumentException('Cannot specify type option without an index.');
@@ -72,15 +86,15 @@ class PopulateCommand extends ContainerAwareCommand
if (null !== $index) {
if (null !== $type) {
- $this->populateIndexType($output, $index, $type, $reset);
+ $this->populateIndexType($output, $index, $type, $reset, $options);
} else {
- $this->populateIndex($output, $index, $reset);
+ $this->populateIndex($output, $index, $reset, $options);
}
} else {
$indexes = array_keys($this->indexManager->getAllIndexes());
foreach ($indexes as $index) {
- $this->populateIndex($output, $index, $reset);
+ $this->populateIndex($output, $index, $reset, $options);
}
}
}
@@ -91,8 +105,9 @@ class PopulateCommand extends ContainerAwareCommand
* @param OutputInterface $output
* @param string $index
* @param boolean $reset
+ * @param array $options
*/
- private function populateIndex(OutputInterface $output, $index, $reset)
+ private function populateIndex(OutputInterface $output, $index, $reset, $options)
{
if ($reset) {
$output->writeln(sprintf('Resetting %s', $index));
@@ -107,7 +122,7 @@ class PopulateCommand extends ContainerAwareCommand
$output->writeln(sprintf('Populating %s/%s, %s', $index, $type, $message));
};
- $provider->populate($loggerClosure);
+ $provider->populate($loggerClosure, $options);
}
$output->writeln(sprintf('Refreshing %s', $index));
@@ -121,8 +136,9 @@ class PopulateCommand extends ContainerAwareCommand
* @param string $index
* @param string $type
* @param boolean $reset
+ * @param array $options
*/
- private function populateIndexType(OutputInterface $output, $index, $type, $reset)
+ private function populateIndexType(OutputInterface $output, $index, $type, $reset, $options)
{
if ($reset) {
$output->writeln(sprintf('Resetting %s/%s', $index, $type));
@@ -134,7 +150,7 @@ class PopulateCommand extends ContainerAwareCommand
};
$provider = $this->providerRegistry->getProvider($index, $type);
- $provider->populate($loggerClosure);
+ $provider->populate($loggerClosure, $options);
$output->writeln(sprintf('Refreshing %s', $index));
$this->indexManager->getIndex($index)->refresh();
diff --git a/Doctrine/AbstractProvider.php b/Doctrine/AbstractProvider.php
index 43e8c20..1fb41f5 100644
--- a/Doctrine/AbstractProvider.php
+++ b/Doctrine/AbstractProvider.php
@@ -31,16 +31,19 @@ abstract class AbstractProvider extends BaseAbstractProvider
/**
* @see FOS\ElasticaBundle\Provider\ProviderInterface::populate()
*/
- public function populate(\Closure $loggerClosure = null)
+ public function populate(\Closure $loggerClosure = null, array $options = array())
{
$queryBuilder = $this->createQueryBuilder();
$nbObjects = $this->countObjects($queryBuilder);
+ $offset = isset($options['offset']) ? intval($options['offset']) : 0;
+ $sleep = isset($options['sleep']) ? intval($options['sleep']) : 0;
+ $batchSize = isset($options['batch-size']) ? intval($options['batch-size']) : $this->options['batch_size'];
- for ($offset = 0; $offset < $nbObjects; $offset += $this->options['batch_size']) {
+ for (; $offset < $nbObjects; $offset += $batchSize) {
if ($loggerClosure) {
$stepStartTime = microtime(true);
}
- $objects = $this->fetchSlice($queryBuilder, $this->options['batch_size'], $offset);
+ $objects = $this->fetchSlice($queryBuilder, $batchSize, $offset);
$this->objectPersister->insertMany($objects);
@@ -48,6 +51,8 @@ abstract class AbstractProvider extends BaseAbstractProvider
$this->managerRegistry->getManagerForClass($this->objectClass)->clear();
}
+ usleep($sleep);
+
if ($loggerClosure) {
$stepNbObjects = count($objects);
$stepCount = $stepNbObjects + $offset;
diff --git a/Propel/Provider.php b/Propel/Provider.php
index f173e72..c319691 100644
--- a/Propel/Provider.php
+++ b/Propel/Provider.php
@@ -14,23 +14,28 @@ class Provider extends AbstractProvider
/**
* @see FOS\ElasticaBundle\Provider\ProviderInterface::populate()
*/
- public function populate(\Closure $loggerClosure = null)
+ public function populate(\Closure $loggerClosure = null, array $options = array())
{
$queryClass = $this->objectClass . 'Query';
$nbObjects = $queryClass::create()->count();
+ $offset = isset($options['offset']) ? intval($options['offset']) : 0;
+ $sleep = isset($options['sleep']) ? intval($options['sleep']) : 0;
+ $batchSize = isset($options['batch-size']) ? intval($options['batch-size']) : $this->options['batch_size'];
- for ($offset = 0; $offset < $nbObjects; $offset += $this->options['batch_size']) {
+ for (; $offset < $nbObjects; $offset += $batchSize) {
if ($loggerClosure) {
$stepStartTime = microtime(true);
}
$objects = $queryClass::create()
- ->limit($this->options['batch_size'])
+ ->limit($batchSize)
->offset($offset)
->find();
$this->objectPersister->insertMany($objects->getArrayCopy());
+ usleep($sleep);
+
if ($loggerClosure) {
$stepNbObjects = count($objects);
$stepCount = $stepNbObjects + $offset;
diff --git a/Provider/ProviderInterface.php b/Provider/ProviderInterface.php
index 710fd4b..e8d7ea4 100644
--- a/Provider/ProviderInterface.php
+++ b/Provider/ProviderInterface.php
@@ -13,7 +13,8 @@ interface ProviderInterface
* Persists all domain objects to ElasticSearch for this provider.
*
* @param \Closure $loggerClosure
+ * @param array $options
* @return
*/
- function populate(\Closure $loggerClosure = null);
+ function populate(\Closure $loggerClosure = null, array $options = array());
}
diff --git a/README.md b/README.md
index e132a15..1f6cf06 100644
--- a/README.md
+++ b/README.md
@@ -327,8 +327,9 @@ Its class must implement `FOS\ElasticaBundle\Provider\ProviderInterface`.
* Insert the repository objects in the type index
*
* @param \Closure $loggerClosure
+ * @param array $options
*/
- public function populate(\Closure $loggerClosure = null)
+ public function populate(\Closure $loggerClosure = null, array $options = array())
{
if ($loggerClosure) {
$loggerClosure('Indexing users');
From c68bb411aca4ab58edd9f1ba4cadd4007a3509fd Mon Sep 17 00:00:00 2001
From: Karel Souffriau
Date: Mon, 28 Oct 2013 16:15:30 +0100
Subject: [PATCH 078/447] Add support for dynamic templates
---
DependencyInjection/Configuration.php | 32 +++++++++++++++
DependencyInjection/FOSElasticaExtension.php | 6 +++
README.md | 30 ++++++++++++++
Resetter.php | 4 ++
.../DependencyInjection/ConfigurationTest.php | 41 +++++++++++++++++++
Tests/ResetterTest.php | 6 ++-
6 files changed, 118 insertions(+), 1 deletion(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index d44e714..eb6abd2 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -265,6 +265,7 @@ class Configuration implements ConfigurationInterface
->end()
->end()
->append($this->getMappingsNode())
+ ->append($this->getDynamicTemplateNode())
->append($this->getSourceNode())
->append($this->getBoostNode())
->append($this->getRoutingNode())
@@ -296,6 +297,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
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 6d38714..26cb209 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -205,6 +205,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);
+ }
+ }
}
}
diff --git a/README.md b/README.md
index 1c5c5f3..28359f6 100644
--- a/README.md
+++ b/README.md
@@ -684,3 +684,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 }
+```
diff --git a/Resetter.php b/Resetter.php
index 7614675..5929cc8 100644
--- a/Resetter.php
+++ b/Resetter.php
@@ -78,6 +78,10 @@ class Resetter
}
}
+ if (isset($indexConfig['dynamic_templates'])) {
+ $mapping->setParam('dynamic_templates', $indexConfig['dynamic_templates']);
+ }
+
return $mapping;
}
diff --git a/Tests/DependencyInjection/ConfigurationTest.php b/Tests/DependencyInjection/ConfigurationTest.php
index f410621..ead9977 100644
--- a/Tests/DependencyInjection/ConfigurationTest.php
+++ b/Tests/DependencyInjection/ConfigurationTest.php
@@ -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']);
+ }
}
diff --git a/Tests/ResetterTest.php b/Tests/ResetterTest.php
index 61a18a9..cc9154b 100644
--- a/Tests/ResetterTest.php
+++ b/Tests/ResetterTest.php
@@ -15,7 +15,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()),
),
),
@@ -92,6 +95,7 @@ class ResetterTest extends \PHPUnit_Framework_TestCase
->method('delete');
$mapping = \Elastica_Type_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);
From 604193396f332d9a96024b58c119cf0bd18bf7b7 Mon Sep 17 00:00:00 2001
From: Jeremy Mikola
Date: Fri, 12 Jul 2013 17:56:14 -0400
Subject: [PATCH 079/447] Remove "prototype" from abstract definition IDs; note
possible conflicts
Due to the naming of transformer, listener, and finder services, it's possible for index/type services to clobber the ID of another concrete or abstract service. This cannot be helped without breaking BC, but we should note it within the extension class.
---
DependencyInjection/FOSElasticaExtension.php | 29 ++++++++++++--------
Resources/config/config.xml | 8 +++---
2 files changed, 22 insertions(+), 15 deletions(-)
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 0cb5c27..4b90e91 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -144,14 +144,15 @@ class FOSElasticaExtension extends Extension
*/
protected function loadIndexFinder(ContainerBuilder $container, $name, $indexId)
{
- $abstractTransformerId = 'fos_elastica.elastica_to_model_transformer.collection.prototype';
+ /* Note: transformer services may conflict with "collection.index", if
+ * an index and type names were "collection" and an index, respectively.
+ */
$transformerId = sprintf('fos_elastica.elastica_to_model_transformer.collection.%s', $name);
- $transformerDef = new DefinitionDecorator($abstractTransformerId);
+ $transformerDef = new DefinitionDecorator('fos_elastica.elastica_to_model_transformer.collection');
$container->setDefinition($transformerId, $transformerDef);
- $abstractFinderId = 'fos_elastica.finder.prototype';
$finderId = sprintf('fos_elastica.finder.%s', $name);
- $finderDef = new DefinitionDecorator($abstractFinderId);
+ $finderDef = new DefinitionDecorator('fos_elastica.finder');
$finderDef->replaceArgument(0, new Reference($indexId));
$finderDef->replaceArgument(1, new Reference($transformerId));
@@ -262,6 +263,9 @@ class FOSElasticaExtension extends Extension
if (isset($typeConfig['elastica_to_model_transformer']['service'])) {
return $typeConfig['elastica_to_model_transformer']['service'];
}
+ /* Note: transformer services may conflict with "prototype.driver", if
+ * the index and type names were "prototype" and a driver, respectively.
+ */
$abstractId = sprintf('fos_elastica.elastica_to_model_transformer.prototype.%s', $typeConfig['driver']);
$serviceId = sprintf('fos_elastica.elastica_to_model_transformer.%s.%s', $indexName, $typeName);
$serviceDef = new DefinitionDecorator($abstractId);
@@ -285,9 +289,9 @@ class FOSElasticaExtension extends Extension
if (isset($typeConfig['model_to_elastica_transformer']['service'])) {
return $typeConfig['model_to_elastica_transformer']['service'];
}
- $abstractId = sprintf('fos_elastica.model_to_elastica_transformer.prototype.auto');
+
$serviceId = sprintf('fos_elastica.model_to_elastica_transformer.%s.%s', $indexName, $typeName);
- $serviceDef = new DefinitionDecorator($abstractId);
+ $serviceDef = new DefinitionDecorator('fos_elastica.model_to_elastica_transformer');
$serviceDef->replaceArgument(0, array(
'identifier' => $typeConfig['identifier']
));
@@ -298,9 +302,8 @@ class FOSElasticaExtension extends Extension
protected function loadObjectPersister(array $typeConfig, Definition $typeDef, ContainerBuilder $container, $indexName, $typeName, $transformerId)
{
- $abstractId = sprintf('fos_elastica.object_persister.prototype');
$serviceId = sprintf('fos_elastica.object_persister.%s.%s', $indexName, $typeName);
- $serviceDef = new DefinitionDecorator($abstractId);
+ $serviceDef = new DefinitionDecorator('fos_elastica.object_persister');
$serviceDef->replaceArgument(0, $typeDef);
$serviceDef->replaceArgument(1, new Reference($transformerId));
$serviceDef->replaceArgument(2, $typeConfig['model']);
@@ -315,7 +318,9 @@ class FOSElasticaExtension extends Extension
if (isset($typeConfig['provider']['service'])) {
return $typeConfig['provider']['service'];
}
-
+ /* Note: provider services may conflict with "prototype.driver", if the
+ * index and type names were "prototype" and a driver, respectively.
+ */
$providerId = sprintf('fos_elastica.provider.%s.%s', $indexName, $typeName);
$providerDef = new DefinitionDecorator('fos_elastica.provider.prototype.' . $typeConfig['driver']);
$providerDef->addTag('fos_elastica.provider', array('index' => $indexName, 'type' => $typeName));
@@ -333,6 +338,9 @@ class FOSElasticaExtension extends Extension
if (isset($typeConfig['listener']['service'])) {
return $typeConfig['listener']['service'];
}
+ /* Note: listener services may conflict with "prototype.driver", if the
+ * index and type names were "prototype" and a driver, respectively.
+ */
$abstractListenerId = sprintf('fos_elastica.listener.prototype.%s', $typeConfig['driver']);
$listenerId = sprintf('fos_elastica.listener.%s.%s', $indexName, $typeName);
$listenerDef = new DefinitionDecorator($abstractListenerId);
@@ -384,9 +392,8 @@ class FOSElasticaExtension extends Extension
if (isset($typeConfig['finder']['service'])) {
$finderId = $typeConfig['finder']['service'];
} else {
- $abstractFinderId = 'fos_elastica.finder.prototype';
$finderId = sprintf('fos_elastica.finder.%s.%s', $indexName, $typeName);
- $finderDef = new DefinitionDecorator($abstractFinderId);
+ $finderDef = new DefinitionDecorator('fos_elastica.finder');
$finderDef->replaceArgument(0, $typeDef);
$finderDef->replaceArgument(1, new Reference($elasticaToModelId));
$container->setDefinition($finderId, $finderDef);
diff --git a/Resources/config/config.xml b/Resources/config/config.xml
index a0819fb..1540269 100644
--- a/Resources/config/config.xml
+++ b/Resources/config/config.xml
@@ -43,26 +43,26 @@
-
+
-
+
-
+
-
+
From 74d993b64206e0e230d576928616c43fb7a3a94d Mon Sep 17 00:00:00 2001
From: Jeremy Mikola
Date: Fri, 12 Jul 2013 17:58:13 -0400
Subject: [PATCH 080/447] Do not clobber existing client definitions (closes
#336 and #324)
While we could have used an abstract definition, its ID would likely conflict with the alias we set for the default client. Remove the abstract definition altogether and simply construct new definitions for each client. This resolves the previous issue where multiple clients would overwrite the constructor arguments of the previous definition.
---
DependencyInjection/FOSElasticaExtension.php | 5 ++---
Resources/config/config.xml | 7 -------
2 files changed, 2 insertions(+), 10 deletions(-)
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 4b90e91..f264d7c 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -70,10 +70,9 @@ class FOSElasticaExtension extends Extension
{
$clientIds = array();
foreach ($clients as $name => $clientConfig) {
- $clientDef = $container->getDefinition('fos_elastica.client');
- $clientDef->replaceArgument(0, $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')));
$container->setDefinition($clientId, $clientDef);
diff --git a/Resources/config/config.xml b/Resources/config/config.xml
index 1540269..dfb417d 100644
--- a/Resources/config/config.xml
+++ b/Resources/config/config.xml
@@ -27,13 +27,6 @@
-
-
-
-
-
-
-
From 467ccbf753188e27bd5809a18f03e2399002ea6d Mon Sep 17 00:00:00 2001
From: Jeremy Mikola
Date: Wed, 30 Oct 2013 17:15:09 -0400
Subject: [PATCH 081/447] Tag client services in DI extension class
These tags were originally introduced in 16ecd7cca306063a0fff9ac27d38af3f416e98f5. #339 removed the fos_elastica.client definition from config.xml, so this tag needs to be added via the DI extension class now.
---
DependencyInjection/FOSElasticaExtension.php | 1 +
1 file changed, 1 insertion(+)
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 632031f..eb6dd4d 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -74,6 +74,7 @@ class FOSElasticaExtension extends Extension
$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')));
+ $clientDef->addTag('fos_elastica.client');
$container->setDefinition($clientId, $clientDef);
From 21ce3cf6ff543a0ee6255d14d8e07d3e8c2cf81f Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Fri, 1 Nov 2013 09:15:14 +1100
Subject: [PATCH 082/447] Fix definition decorators (closes #393)
---
DependencyInjection/Compiler/TransformerPass.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/DependencyInjection/Compiler/TransformerPass.php b/DependencyInjection/Compiler/TransformerPass.php
index f94b95f..4281d0b 100644
--- a/DependencyInjection/Compiler/TransformerPass.php
+++ b/DependencyInjection/Compiler/TransformerPass.php
@@ -19,7 +19,7 @@ class TransformerPass implements CompilerPassInterface
*/
public function process(ContainerBuilder $container)
{
- if (!$container->hasDefinition('fos_elastica.elastica_to_model_transformer.collection.prototype')) {
+ if (!$container->hasDefinition('fos_elastica.elastica_to_model_transformer.collection')) {
return;
}
@@ -44,4 +44,4 @@ class TransformerPass implements CompilerPassInterface
$index->replaceArgument(0, $indexTransformers);
}
}
-}
\ No newline at end of file
+}
From 97c98a02432fef3bd7f650a69de9eefd9bc1a1ec Mon Sep 17 00:00:00 2001
From: Pierre du Plessis
Date: Mon, 4 Nov 2013 00:09:21 +0200
Subject: [PATCH 083/447] Add Symfony ExpressionLanguage support for indexable
callback
---
Doctrine/AbstractListener.php | 59 ++++++++++++++++++++++++-
README.md | 7 +++
Tests/Doctrine/AbstractListenerTest.php | 2 +
composer.json | 6 ++-
4 files changed, 71 insertions(+), 3 deletions(-)
diff --git a/Doctrine/AbstractListener.php b/Doctrine/AbstractListener.php
index a7e8867..7a88e4b 100644
--- a/Doctrine/AbstractListener.php
+++ b/Doctrine/AbstractListener.php
@@ -6,6 +6,9 @@ use Doctrine\Common\EventSubscriber;
use Doctrine\Common\Persistence\ObjectManager;
use FOS\ElasticaBundle\Persister\ObjectPersisterInterface;
use FOS\ElasticaBundle\Persister\ObjectPersister;
+use Symfony\Component\ExpressionLanguage\Expression;
+use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
+use Symfony\Component\ExpressionLanguage\SyntaxError;
abstract class AbstractListener implements EventSubscriber
{
@@ -51,6 +54,13 @@ abstract class AbstractListener implements EventSubscriber
*/
private $scheduledForRemoval = array();
+ /**
+ * An instance of ExpressionLanguage
+ *
+ * @var ExpressionLanguage
+ */
+ protected $expressionLanguage;
+
/**
* Constructor.
*
@@ -89,8 +99,21 @@ abstract class AbstractListener implements EventSubscriber
public function setIsIndexableCallback($callback)
{
if (is_string($callback)) {
+
if (!is_callable(array($this->objectClass, $callback))) {
- throw new \RuntimeException(sprintf('Indexable callback %s::%s() is not callable.', $this->objectClass, $callback));
+
+ if(false !== ($expression = $this->getExpressionLanguage())) {
+
+ $callback = new Expression($callback);
+
+ try {
+ $expression->compile($callback, array($this->getExpressionVar()));
+ } catch(SyntaxError $e) {
+ throw new \RuntimeException(sprintf('Indexable callback %s::%s() is not callable or a valid expression.', $this->objectClass, $callback), 0, $e);
+ }
+ } else {
+ throw new \RuntimeException(sprintf('Indexable callback %s::%s() is not callable.', $this->objectClass, $callback));
+ }
}
} elseif (!is_callable($callback)) {
if (is_array($callback)) {
@@ -98,6 +121,7 @@ abstract class AbstractListener implements EventSubscriber
if (is_object($class)) {
$class = get_class($class);
}
+
if ($class && $method) {
throw new \RuntimeException(sprintf('Indexable callback %s::%s() is not callable.', $class, $method));
}
@@ -120,6 +144,10 @@ abstract class AbstractListener implements EventSubscriber
return true;
}
+ if($this->isIndexableCallback instanceof Expression) {
+ return $this->getExpressionLanguage()->evaluate($this->isIndexableCallback, array($this->getExpressionVar($object) => $object));
+ }
+
return is_string($this->isIndexableCallback)
? call_user_func(array($object, $this->isIndexableCallback))
: call_user_func($this->isIndexableCallback, $object);
@@ -155,4 +183,33 @@ abstract class AbstractListener implements EventSubscriber
unset($this->scheduledForRemoval[$objectHash]);
}
}
+
+ /**
+ * @param mixed $object
+ * @return string
+ */
+ private function getExpressionVar($object = null)
+ {
+ $class = $object ?: $this->objectClass;
+
+ $ref = new \ReflectionClass($class);
+
+ return strtolower($ref->getShortName());
+ }
+
+ /**
+ * @return bool|ExpressionLanguage
+ */
+ private function getExpressionLanguage()
+ {
+ if(null === $this->expressionLanguage) {
+ if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
+ return false;
+ }
+
+ $this->expressionLanguage = new ExpressionLanguage();
+ }
+
+ return $this->expressionLanguage;
+ }
}
diff --git a/README.md b/README.md
index 1f6cf06..6a9b899 100644
--- a/README.md
+++ b/README.md
@@ -630,6 +630,13 @@ In this case, the callback_class will be the `isIndexable()` method on the speci
service and the object being considered for indexing will be passed as the only
argument. This allows you to do more complex validation (e.g. ACL checks).
+If you have the [Symfony ExpressionLanguage](https://github.com/symfony/expression-language) component installed, you can use expressions
+to evaluate the callback:
+
+ persistence:
+ listener:
+ is_indexable_callback: "user.isActive() && user.hasRole('ROLE_USER')"
+
As you might expect, new entities will only be indexed if the callback_class returns
`true`. Additionally, modified entities will be updated or removed from the
index depending on whether the callback_class returns `true` or `false`, respectively.
diff --git a/Tests/Doctrine/AbstractListenerTest.php b/Tests/Doctrine/AbstractListenerTest.php
index e3af609..e99e26d 100644
--- a/Tests/Doctrine/AbstractListenerTest.php
+++ b/Tests/Doctrine/AbstractListenerTest.php
@@ -164,6 +164,7 @@ abstract class AbstractListenerTest extends \PHPUnit_Framework_TestCase
array('nonexistentEntityMethod'),
array(array(new Listener\IndexableDecider(), 'internalMethod')),
array(42),
+ array('entity.getIsIndexable() && nonexistentEntityFunction()'),
);
}
@@ -173,6 +174,7 @@ abstract class AbstractListenerTest extends \PHPUnit_Framework_TestCase
array('getIsIndexable'),
array(array(new Listener\IndexableDecider(), 'isIndexable')),
array(function(Listener\Entity $entity) { return $entity->getIsIndexable(); }),
+ array('entity.getIsIndexable()')
);
}
diff --git a/composer.json b/composer.json
index 099868b..094eba5 100644
--- a/composer.json
+++ b/composer.json
@@ -24,14 +24,16 @@
"doctrine/mongodb-odm": "1.0.*@dev",
"propel/propel1": "1.6.*",
"pagerfanta/pagerfanta": "1.0.*@dev",
- "knplabs/knp-components": "1.2.*"
+ "knplabs/knp-components": "1.2.*",
+ "symfony/expression-language" : "2.4.*@dev"
},
"suggest": {
"doctrine/orm": ">=2.2,<2.5-dev",
"doctrine/mongodb-odm": "1.0.*@dev",
"propel/propel1": "1.6.*",
"pagerfanta/pagerfanta": "1.0.*@dev",
- "knplabs/knp-components": "1.2.*"
+ "knplabs/knp-components": "1.2.*",
+ "symfony/expression-language" : "2.4.*@dev"
},
"autoload": {
"psr-0": { "FOS\\ElasticaBundle": "" }
From f972b4af5946cb370bc3b64eb7a3e1382dce9113 Mon Sep 17 00:00:00 2001
From: Pierre du Plessis
Date: Mon, 4 Nov 2013 08:50:41 +0200
Subject: [PATCH 084/447] Fixed CS
---
Doctrine/AbstractListener.php | 19 +++++++------------
1 file changed, 7 insertions(+), 12 deletions(-)
diff --git a/Doctrine/AbstractListener.php b/Doctrine/AbstractListener.php
index 7a88e4b..3b62444 100644
--- a/Doctrine/AbstractListener.php
+++ b/Doctrine/AbstractListener.php
@@ -93,22 +93,18 @@ abstract class AbstractListener implements EventSubscriber
* should expect the object for consideration as its only argument and
* return a boolean.
*
- * @param callback $callback
+ * @param callback $callback
* @throws \RuntimeException if the callback is not callable
*/
public function setIsIndexableCallback($callback)
{
if (is_string($callback)) {
-
if (!is_callable(array($this->objectClass, $callback))) {
-
- if(false !== ($expression = $this->getExpressionLanguage())) {
-
+ if (false !== ($expression = $this->getExpressionLanguage())) {
$callback = new Expression($callback);
-
try {
$expression->compile($callback, array($this->getExpressionVar()));
- } catch(SyntaxError $e) {
+ } catch (SyntaxError $e) {
throw new \RuntimeException(sprintf('Indexable callback %s::%s() is not callable or a valid expression.', $this->objectClass, $callback), 0, $e);
}
} else {
@@ -135,7 +131,7 @@ abstract class AbstractListener implements EventSubscriber
/**
* Return whether the object is indexable with respect to the callback.
*
- * @param object $object
+ * @param object $object
* @return boolean
*/
protected function isObjectIndexable($object)
@@ -144,7 +140,7 @@ abstract class AbstractListener implements EventSubscriber
return true;
}
- if($this->isIndexableCallback instanceof Expression) {
+ if ($this->isIndexableCallback instanceof Expression) {
return $this->getExpressionLanguage()->evaluate($this->isIndexableCallback, array($this->getExpressionVar($object) => $object));
}
@@ -185,13 +181,12 @@ abstract class AbstractListener implements EventSubscriber
}
/**
- * @param mixed $object
+ * @param mixed $object
* @return string
*/
private function getExpressionVar($object = null)
{
$class = $object ?: $this->objectClass;
-
$ref = new \ReflectionClass($class);
return strtolower($ref->getShortName());
@@ -202,7 +197,7 @@ abstract class AbstractListener implements EventSubscriber
*/
private function getExpressionLanguage()
{
- if(null === $this->expressionLanguage) {
+ if (null === $this->expressionLanguage) {
if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
return false;
}
From be4c99a0d3f9f8967983773dbe785ddc802ae404 Mon Sep 17 00:00:00 2001
From: igorRovenki
Date: Wed, 6 Nov 2013 11:01:53 +0200
Subject: [PATCH 085/447] Update README.md
Should be "listener: ~" on the line 595, otherwise listener does not working
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 6a9b899..13d2024 100644
--- a/README.md
+++ b/README.md
@@ -592,7 +592,7 @@ Declare that you want to update the index in real time:
persistence:
driver: orm
model: Application\UserBundle\Entity\User
- listener: # by default, listens to "insert", "update" and "delete"
+ listener: ~ # by default, listens to "insert", "update" and "delete"
Now the index is automatically updated each time the state of the bound Doctrine repository changes.
No need to repopulate the whole "user" index when a new `User` is created.
From 9b6b0b01482325eeea80c098b37852f60ce25127 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Mon, 23 Sep 2013 09:57:58 +1000
Subject: [PATCH 086/447] Add query_builder_method option to the transformers
---
DependencyInjection/Configuration.php | 2 +
DependencyInjection/FOSElasticaExtension.php | 3 +-
.../AbstractElasticaToModelTransformer.php | 1 +
.../MongoDB/ElasticaToModelTransformer.php | 2 +-
Doctrine/ORM/ElasticaToModelTransformer.php | 25 +++-
.../ORM/ElasticaToModelTransformerTest.php | 130 ++++++++++++++++++
6 files changed, 155 insertions(+), 8 deletions(-)
create mode 100644 Tests/Doctrine/ORM/ElasticaToModelTransformerTest.php
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index eb6abd2..0fea69a 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -171,6 +171,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()
@@ -252,6 +253,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()
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 7005779..7fbbe7f 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -283,7 +283,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);
diff --git a/Doctrine/AbstractElasticaToModelTransformer.php b/Doctrine/AbstractElasticaToModelTransformer.php
index e8f9472..147067d 100755
--- a/Doctrine/AbstractElasticaToModelTransformer.php
+++ b/Doctrine/AbstractElasticaToModelTransformer.php
@@ -35,6 +35,7 @@ abstract class AbstractElasticaToModelTransformer implements ElasticaToModelTran
'hydrate' => true,
'identifier' => 'id',
'ignore_missing' => false,
+ 'query_builder_method' => 'createQueryBuilder',
);
/**
diff --git a/Doctrine/MongoDB/ElasticaToModelTransformer.php b/Doctrine/MongoDB/ElasticaToModelTransformer.php
index 4c35a0c..855a093 100644
--- a/Doctrine/MongoDB/ElasticaToModelTransformer.php
+++ b/Doctrine/MongoDB/ElasticaToModelTransformer.php
@@ -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()
diff --git a/Doctrine/ORM/ElasticaToModelTransformer.php b/Doctrine/ORM/ElasticaToModelTransformer.php
index 0a889a3..20ec6e8 100644
--- a/Doctrine/ORM/ElasticaToModelTransformer.php
+++ b/Doctrine/ORM/ElasticaToModelTransformer.php
@@ -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);
+ }
}
diff --git a/Tests/Doctrine/ORM/ElasticaToModelTransformerTest.php b/Tests/Doctrine/ORM/ElasticaToModelTransformerTest.php
new file mode 100644
index 0000000..c35b9fc
--- /dev/null
+++ b/Tests/Doctrine/ORM/ElasticaToModelTransformerTest.php
@@ -0,0 +1,130 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace FOS\ElasticaBundle\Tests\Doctrine\ORM;
+
+use Doctrine\ORM\QueryBuilder;
+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));
+ }
+}
From 52d5d0d55f6f979e66f1df045b825e8ae263aca4 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Mon, 11 Nov 2013 13:21:36 +1100
Subject: [PATCH 087/447] Remove incorrect copyright header
---
Tests/Doctrine/ORM/ElasticaToModelTransformerTest.php | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/Tests/Doctrine/ORM/ElasticaToModelTransformerTest.php b/Tests/Doctrine/ORM/ElasticaToModelTransformerTest.php
index c35b9fc..14f3ffb 100644
--- a/Tests/Doctrine/ORM/ElasticaToModelTransformerTest.php
+++ b/Tests/Doctrine/ORM/ElasticaToModelTransformerTest.php
@@ -1,17 +1,7 @@
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
namespace FOS\ElasticaBundle\Tests\Doctrine\ORM;
-use Doctrine\ORM\QueryBuilder;
use FOS\ElasticaBundle\Doctrine\ORM\ElasticaToModelTransformer;
class ElasticaToModelTransformerTest extends \PHPUnit_Framework_TestCase
From 3f784b0a5b889f160b2c884bac4e29e1edebef94 Mon Sep 17 00:00:00 2001
From: Matyas Somfai
Date: Tue, 8 Oct 2013 12:00:04 +0200
Subject: [PATCH 088/447] added new options to fos:elastica:populate command
and options array parameter to ProviderInterface
removed assume-yes option as the no-interaction option has the same purpose
---
Command/PopulateCommand.php | 36 ++++++++++++++++++++++++----------
Doctrine/AbstractProvider.php | 11 ++++++++---
Propel/Provider.php | 11 ++++++++---
Provider/ProviderInterface.php | 3 ++-
README.md | 15 +++++++-------
5 files changed, 52 insertions(+), 24 deletions(-)
diff --git a/Command/PopulateCommand.php b/Command/PopulateCommand.php
index 4f88b75..237b223 100755
--- a/Command/PopulateCommand.php
+++ b/Command/PopulateCommand.php
@@ -3,6 +3,7 @@
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;
@@ -43,6 +44,9 @@ class PopulateCommand extends ContainerAwareCommand
->addOption('index', null, InputOption::VALUE_OPTIONAL, 'The index to repopulate')
->addOption('type', null, InputOption::VALUE_OPTIONAL, 'The type to repopulate')
->addOption('no-reset', null, InputOption::VALUE_NONE, 'Do not reset index before populating')
+ ->addOption('offset', null, InputOption::VALUE_REQUIRED, 'Start indexing at offset', 0)
+ ->addOption('sleep', null, InputOption::VALUE_REQUIRED, 'Sleep time between persisting iterations (microseconds)', 0)
+ ->addOption('batch-size', null, InputOption::VALUE_REQUIRED, 'Index packet size (overrides provider config option)')
->setDescription('Populates search indexes from providers')
;
}
@@ -62,9 +66,19 @@ class PopulateCommand extends ContainerAwareCommand
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
- $index = $input->getOption('index');
- $type = $input->getOption('type');
- $reset = $input->getOption('no-reset') ? false : true;
+ $index = $input->getOption('index');
+ $type = $input->getOption('type');
+ $reset = $input->getOption('no-reset') ? false : true;
+ $noInteraction = $input->getOption('no-interaction');
+ $options = $input->getOptions();
+
+ if (!$noInteraction && $reset && $input->getOption('offset')) {
+ /** @var DialogHelper $dialog */
+ $dialog = $this->getHelperSet()->get('dialog');
+ if (!$dialog->askConfirmation($output, 'You chose to reset the index and start indexing with an offset. Do you really want to do that?', true)) {
+ return;
+ }
+ }
if (null === $index && null !== $type) {
throw new \InvalidArgumentException('Cannot specify type option without an index.');
@@ -72,15 +86,15 @@ class PopulateCommand extends ContainerAwareCommand
if (null !== $index) {
if (null !== $type) {
- $this->populateIndexType($output, $index, $type, $reset);
+ $this->populateIndexType($output, $index, $type, $reset, $options);
} else {
- $this->populateIndex($output, $index, $reset);
+ $this->populateIndex($output, $index, $reset, $options);
}
} else {
$indexes = array_keys($this->indexManager->getAllIndexes());
foreach ($indexes as $index) {
- $this->populateIndex($output, $index, $reset);
+ $this->populateIndex($output, $index, $reset, $options);
}
}
}
@@ -91,8 +105,9 @@ class PopulateCommand extends ContainerAwareCommand
* @param OutputInterface $output
* @param string $index
* @param boolean $reset
+ * @param array $options
*/
- private function populateIndex(OutputInterface $output, $index, $reset)
+ private function populateIndex(OutputInterface $output, $index, $reset, $options)
{
if ($reset) {
$output->writeln(sprintf('Resetting %s', $index));
@@ -107,7 +122,7 @@ class PopulateCommand extends ContainerAwareCommand
$output->writeln(sprintf('Populating %s/%s, %s', $index, $type, $message));
};
- $provider->populate($loggerClosure);
+ $provider->populate($loggerClosure, $options);
}
$output->writeln(sprintf('Refreshing %s', $index));
@@ -121,8 +136,9 @@ class PopulateCommand extends ContainerAwareCommand
* @param string $index
* @param string $type
* @param boolean $reset
+ * @param array $options
*/
- private function populateIndexType(OutputInterface $output, $index, $type, $reset)
+ private function populateIndexType(OutputInterface $output, $index, $type, $reset, $options)
{
if ($reset) {
$output->writeln(sprintf('Resetting: %s/%s', $index, $type));
@@ -134,7 +150,7 @@ class PopulateCommand extends ContainerAwareCommand
};
$provider = $this->providerRegistry->getProvider($index, $type);
- $provider->populate($loggerClosure);
+ $provider->populate($loggerClosure, $options);
$output->writeln(sprintf('Refreshing: %s', $index));
$this->indexManager->getIndex($index)->refresh();
diff --git a/Doctrine/AbstractProvider.php b/Doctrine/AbstractProvider.php
index 43e8c20..1fb41f5 100644
--- a/Doctrine/AbstractProvider.php
+++ b/Doctrine/AbstractProvider.php
@@ -31,16 +31,19 @@ abstract class AbstractProvider extends BaseAbstractProvider
/**
* @see FOS\ElasticaBundle\Provider\ProviderInterface::populate()
*/
- public function populate(\Closure $loggerClosure = null)
+ public function populate(\Closure $loggerClosure = null, array $options = array())
{
$queryBuilder = $this->createQueryBuilder();
$nbObjects = $this->countObjects($queryBuilder);
+ $offset = isset($options['offset']) ? intval($options['offset']) : 0;
+ $sleep = isset($options['sleep']) ? intval($options['sleep']) : 0;
+ $batchSize = isset($options['batch-size']) ? intval($options['batch-size']) : $this->options['batch_size'];
- for ($offset = 0; $offset < $nbObjects; $offset += $this->options['batch_size']) {
+ for (; $offset < $nbObjects; $offset += $batchSize) {
if ($loggerClosure) {
$stepStartTime = microtime(true);
}
- $objects = $this->fetchSlice($queryBuilder, $this->options['batch_size'], $offset);
+ $objects = $this->fetchSlice($queryBuilder, $batchSize, $offset);
$this->objectPersister->insertMany($objects);
@@ -48,6 +51,8 @@ abstract class AbstractProvider extends BaseAbstractProvider
$this->managerRegistry->getManagerForClass($this->objectClass)->clear();
}
+ usleep($sleep);
+
if ($loggerClosure) {
$stepNbObjects = count($objects);
$stepCount = $stepNbObjects + $offset;
diff --git a/Propel/Provider.php b/Propel/Provider.php
index f173e72..c319691 100644
--- a/Propel/Provider.php
+++ b/Propel/Provider.php
@@ -14,23 +14,28 @@ class Provider extends AbstractProvider
/**
* @see FOS\ElasticaBundle\Provider\ProviderInterface::populate()
*/
- public function populate(\Closure $loggerClosure = null)
+ public function populate(\Closure $loggerClosure = null, array $options = array())
{
$queryClass = $this->objectClass . 'Query';
$nbObjects = $queryClass::create()->count();
+ $offset = isset($options['offset']) ? intval($options['offset']) : 0;
+ $sleep = isset($options['sleep']) ? intval($options['sleep']) : 0;
+ $batchSize = isset($options['batch-size']) ? intval($options['batch-size']) : $this->options['batch_size'];
- for ($offset = 0; $offset < $nbObjects; $offset += $this->options['batch_size']) {
+ for (; $offset < $nbObjects; $offset += $batchSize) {
if ($loggerClosure) {
$stepStartTime = microtime(true);
}
$objects = $queryClass::create()
- ->limit($this->options['batch_size'])
+ ->limit($batchSize)
->offset($offset)
->find();
$this->objectPersister->insertMany($objects->getArrayCopy());
+ usleep($sleep);
+
if ($loggerClosure) {
$stepNbObjects = count($objects);
$stepCount = $stepNbObjects + $offset;
diff --git a/Provider/ProviderInterface.php b/Provider/ProviderInterface.php
index 710fd4b..e8d7ea4 100644
--- a/Provider/ProviderInterface.php
+++ b/Provider/ProviderInterface.php
@@ -13,7 +13,8 @@ interface ProviderInterface
* Persists all domain objects to ElasticSearch for this provider.
*
* @param \Closure $loggerClosure
+ * @param array $options
* @return
*/
- function populate(\Closure $loggerClosure = null);
+ function populate(\Closure $loggerClosure = null, array $options = array());
}
diff --git a/README.md b/README.md
index 28359f6..914150a 100644
--- a/README.md
+++ b/README.md
@@ -74,9 +74,9 @@ Here we created a "website" index, that uses our "default" client.
Our index is now available as a service: `fos_elastica.index.website`. It is an instance of `Elastica_Index`.
-If you need to have different index name from the service name, for example,
-in order to have different indexes for different environments then you can
-use the ```index_name``` key to change the index name. The service name will
+If you need to have different index name from the service name, for example,
+in order to have different indexes for different environments then you can
+use the ```index_name``` key to change the index name. The service name will
remain the same across the environments:
fos_elastica:
@@ -86,8 +86,8 @@ remain the same across the environments:
website:
client: default
index_name: website_qa
-
-The service id will be `fos_elastica.index.website` but the underlying index name is website_qa.
+
+The service id will be `fos_elastica.index.website` but the underlying index name is website_qa.
#### Declare a type
@@ -246,9 +246,10 @@ Its class must implement `FOS\ElasticaBundle\Provider\ProviderInterface`.
/**
* Insert the repository objects in the type index
*
- * @param Closure $loggerClosure
+ * @param \Closure $loggerClosure
+ * @param array $options
*/
- public function populate(Closure $loggerClosure = null)
+ public function populate(\Closure $loggerClosure = null, array $options = array())
{
if ($loggerClosure) {
$loggerClosure('Indexing users');
From 97aadf48971895b5944edb6a4348220d1ff3106f Mon Sep 17 00:00:00 2001
From: Karel Souffriau
Date: Fri, 15 Nov 2013 17:39:02 +0100
Subject: [PATCH 089/447] TransformedFinder::moreLikeThis: use
\Elastica_Document instead of \Document
---
Finder/TransformedFinder.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Finder/TransformedFinder.php b/Finder/TransformedFinder.php
index c520f08..9e624fd 100644
--- a/Finder/TransformedFinder.php
+++ b/Finder/TransformedFinder.php
@@ -7,6 +7,7 @@ use FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerInterface;
use FOS\ElasticaBundle\Paginator\TransformedPaginatorAdapter;
use FOS\ElasticaBundle\Paginator\FantaPaginatorAdapter;
use Pagerfanta\Pagerfanta;
+use Elastica_Document;
use Elastica_Searchable;
use Elastica_Query;
@@ -55,7 +56,7 @@ class TransformedFinder implements PaginatedFinderInterface
**/
public function moreLikeThis($id, $params = array(), $query = array())
{
- $doc = new Document($id);
+ $doc = new Elastica_Document($id);
$results = $this->searchable->moreLikeThis($doc, $params, $query)->getResults();
return $this->transformer->transform($results);
@@ -77,7 +78,6 @@ class TransformedFinder implements PaginatedFinderInterface
return $results;
}
-
/**
* Gets a paginator wrapping the result of a search
*
From c82006e8aceaf030bef9afa16629fbacca7964b6 Mon Sep 17 00:00:00 2001
From: Luis Cordova
Date: Fri, 15 Nov 2013 15:41:10 -0500
Subject: [PATCH 090/447] fix typos
---
README.md | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index 9792139..c777a91 100644
--- a/README.md
+++ b/README.md
@@ -182,11 +182,11 @@ 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.
@@ -230,7 +230,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 +495,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 }
#--
From cacb40286c6dd1da6d53d141f453ade237344fa5 Mon Sep 17 00:00:00 2001
From: Luis Cordova
Date: Thu, 14 Nov 2013 10:04:08 -0500
Subject: [PATCH 091/447] clean ups
---
Command/PopulateCommand.php | 2 --
Command/ResetCommand.php | 2 --
Command/SearchCommand.php | 1 -
Configuration/Search.php | 2 --
DependencyInjection/FOSElasticaExtension.php | 2 ++
Doctrine/RepositoryManager.php | 1 -
Finder/TransformedFinder.php | 1 +
Manager/RepositoryManager.php | 6 +++---
Manager/RepositoryManagerInterface.php | 1 -
Paginator/FantaPaginatorAdapter.php | 5 ++---
Paginator/PaginatorAdapterInterface.php | 2 --
Paginator/RawPaginatorAdapter.php | 4 +---
Paginator/RawPartialResults.php | 1 -
Paginator/TransformedPaginatorAdapter.php | 1 -
Paginator/TransformedPartialResults.php | 1 -
Provider/AbstractProvider.php | 1 -
Provider/ProviderRegistry.php | 2 --
Resources/views/Collector/elastica.html.twig | 12 ++++++------
Serializer/Callback.php | 2 --
Tests/DataCollector/ElasticaDataCollectorTest.php | 2 --
Tests/Doctrine/RepositoryManagerTest.php | 1 -
Tests/Logger/ElasticaLoggerTest.php | 1 -
Tests/Manager/RepositoryManagerTest.php | 1 -
Tests/RepositoryTest.php | 2 --
.../ElasticaToModelTransformerCollectionTest.php | 1 -
Transformer/ModelToElasticaAutoTransformer.php | 1 -
26 files changed, 15 insertions(+), 43 deletions(-)
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..280f9aa 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;
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/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 9bf732e..50621a5 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -91,6 +91,7 @@ class FOSElasticaExtension extends Extension
* @param ContainerBuilder $container A ContainerBuilder instance
* @param array $clientIdsByName
* @param $defaultClientName
+ * @param $serializerConfig
* @throws \InvalidArgumentException
* @return array
*/
@@ -170,6 +171,7 @@ 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)
{
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/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/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/Resources/views/Collector/elastica.html.twig b/Resources/views/Collector/elastica.html.twig
index a665e2d..4a4c3e8 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 %}
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/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/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/Logger/ElasticaLoggerTest.php b/Tests/Logger/ElasticaLoggerTest.php
index 3cf6d2d..9f68baf 100644
--- a/Tests/Logger/ElasticaLoggerTest.php
+++ b/Tests/Logger/ElasticaLoggerTest.php
@@ -86,5 +86,4 @@ class ElasticaLoggerTest extends \PHPUnit_Framework_TestCase
$elasticaLogger->logQuery($path, $method, $data, $time);
}
-
}
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/RepositoryTest.php b/Tests/RepositoryTest.php
index ded8009..6eabe7b 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';
@@ -75,5 +74,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..d33708e 100644
--- a/Tests/Transformer/ElasticaToModelTransformerCollectionTest.php
+++ b/Tests/Transformer/ElasticaToModelTransformerCollectionTest.php
@@ -119,5 +119,4 @@ class POPO
class POPO2 extends POPO
{
-
}
diff --git a/Transformer/ModelToElasticaAutoTransformer.php b/Transformer/ModelToElasticaAutoTransformer.php
index 6e01907..0ebcc47 100644
--- a/Transformer/ModelToElasticaAutoTransformer.php
+++ b/Transformer/ModelToElasticaAutoTransformer.php
@@ -149,5 +149,4 @@ class ModelToElasticaAutoTransformer implements ModelToElasticaTransformerInterf
return $value;
}
-
}
From b149ac235b6bd8b61aa2c7db9e3e0a8585107067 Mon Sep 17 00:00:00 2001
From: Damien Alexandre
Date: Fri, 29 Nov 2013 13:53:25 +0100
Subject: [PATCH 092/447] Replace deprecated calls `Document::add` to
`Document::set`
---
Transformer/ModelToElasticaAutoTransformer.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Transformer/ModelToElasticaAutoTransformer.php b/Transformer/ModelToElasticaAutoTransformer.php
index e960dc5..ecddacf 100644
--- a/Transformer/ModelToElasticaAutoTransformer.php
+++ b/Transformer/ModelToElasticaAutoTransformer.php
@@ -75,7 +75,7 @@ class ModelToElasticaAutoTransformer implements ModelToElasticaTransformerInterf
/* $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;
From 2862259d8e810e852e4872f6e1d57835ab2708c3 Mon Sep 17 00:00:00 2001
From: Damien Alexandre
Date: Fri, 29 Nov 2013 14:59:56 +0100
Subject: [PATCH 093/447] Allow empty or null or no `mappings:` key under type
configuration
refs #300. This commit allow to define types without having to
set any mapping as Elasticsearch build his own.
The minimal config become:
indexes:
toto:
client: default
types:
Article:
mappings: ~
...
---
DependencyInjection/Configuration.php | 4 ++++
DependencyInjection/FOSElasticaExtension.php | 7 ++++++-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index fe7e9a4..e9e2dbb 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -432,6 +432,10 @@ class Configuration implements ConfigurationInterface
}
foreach ($index['types'] as $type) {
+ if (empty($type['mappings'])) {
+ continue;
+ }
+
$nestings = array_merge_recursive($nestings, $this->getNestingsForType($type['mappings'], $nestings));
}
}
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 7a72d96..12d81ee 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -199,6 +199,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'];
}
@@ -211,7 +216,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'];
From 3027c687e227e6c1d7bacf6793adf03839fc7355 Mon Sep 17 00:00:00 2001
From: Damien Alexandre
Date: Fri, 29 Nov 2013 15:35:59 +0100
Subject: [PATCH 094/447] Ref #341, fix the insertMany method to use Bulk
indexing
To make it works, I inject the serializer defined for the Type
into the fos_elastica.object_serializer_persister service.
This is the SAME service injected in the setSerializer of Type.
We deport the handling of serialization outside Elastica,
this is not so good but we need to build our own Documents to
get the ID's correctly.
---
DependencyInjection/FOSElasticaExtension.php | 2 ++
Persister/ObjectSerializerPersister.php | 19 ++++++++----
Resources/config/config.xml | 1 +
.../ObjectSerializerPersisterTest.php | 30 ++++++++++++++-----
4 files changed, 39 insertions(+), 13 deletions(-)
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 12d81ee..5b533aa 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -356,6 +356,8 @@ class FOSElasticaExtension extends Extension
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)];
diff --git a/Persister/ObjectSerializerPersister.php b/Persister/ObjectSerializerPersister.php
index 269515b..40305c4 100644
--- a/Persister/ObjectSerializerPersister.php
+++ b/Persister/ObjectSerializerPersister.php
@@ -2,6 +2,7 @@
namespace FOS\ElasticaBundle\Persister;
+use Elastica\Document;
use Elastica\Type;
use FOS\ElasticaBundle\Transformer\ModelToElasticaTransformerInterface;
@@ -14,11 +15,12 @@ use FOS\ElasticaBundle\Transformer\ModelToElasticaTransformerInterface;
*/
class ObjectSerializerPersister extends ObjectPersister
{
- public function __construct(Type $type, ModelToElasticaTransformerInterface $transformer, $objectClass)
+ public function __construct(Type $type, ModelToElasticaTransformerInterface $transformer, $objectClass, $serializer)
{
$this->type = $type;
$this->transformer = $transformer;
$this->objectClass = $objectClass;
+ $this->serializer = $serializer;
}
/**
@@ -30,7 +32,7 @@ class ObjectSerializerPersister extends ObjectPersister
public function insertOne($object)
{
$document = $this->transformToElasticaDocument($object);
- $this->type->addObject($object, $document);
+ $this->type->addDocument($document);
}
/**
@@ -43,7 +45,7 @@ class ObjectSerializerPersister extends ObjectPersister
{
$document = $this->transformToElasticaDocument($object);
$this->type->deleteById($document->getId());
- $this->type->addObject($object, $document);
+ $this->type->addDocument($document);
}
/**
@@ -78,9 +80,11 @@ class ObjectSerializerPersister extends ObjectPersister
**/
public function insertMany(array $objects)
{
+ $docs = array();
foreach ($objects as $object) {
- $this->insertOne($object);
+ $docs[] = $this->transformToElasticaDocument($object);
}
+ $this->type->addDocuments($docs);
}
/**
@@ -92,6 +96,11 @@ class ObjectSerializerPersister extends ObjectPersister
*/
public function transformToElasticaDocument($object)
{
- return $this->transformer->transform($object, array());
+ $document = $this->transformer->transform($object, array());
+
+ $data = call_user_func($this->serializer, $object);
+ $document->setData($data);
+
+ return $document;
}
}
diff --git a/Resources/config/config.xml b/Resources/config/config.xml
index 77c280d..1fb2c1d 100644
--- a/Resources/config/config.xml
+++ b/Resources/config/config.xml
@@ -53,6 +53,7 @@
+
diff --git a/Tests/Persister/ObjectSerializerPersisterTest.php b/Tests/Persister/ObjectSerializerPersisterTest.php
index 10c63ab..aae3a64 100644
--- a/Tests/Persister/ObjectSerializerPersisterTest.php
+++ b/Tests/Persister/ObjectSerializerPersisterTest.php
@@ -45,9 +45,12 @@ class ObjectSerializerPersisterTest extends \PHPUnit_Framework_TestCase
->method('deleteById')
->with($this->equalTo(123));
$typeMock->expects($this->once())
- ->method('addObject');
+ ->method('addDocument');
- $objectPersister = new ObjectSerializerPersister($typeMock, $transformer, 'SomeClass');
+ $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());
}
@@ -62,9 +65,12 @@ class ObjectSerializerPersisterTest extends \PHPUnit_Framework_TestCase
$typeMock->expects($this->never())
->method('deleteById');
$typeMock->expects($this->once())
- ->method('addObject');
+ ->method('addDocument');
- $objectPersister = new ObjectSerializerPersister($typeMock, $transformer, 'SomeClass');
+ $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());
}
@@ -79,9 +85,12 @@ class ObjectSerializerPersisterTest extends \PHPUnit_Framework_TestCase
$typeMock->expects($this->once())
->method('deleteById');
$typeMock->expects($this->never())
- ->method('addObject');
+ ->method('addDocument');
- $objectPersister = new ObjectSerializerPersister($typeMock, $transformer, 'SomeClass');
+ $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());
}
@@ -95,12 +104,17 @@ class ObjectSerializerPersisterTest extends \PHPUnit_Framework_TestCase
->getMock();
$typeMock->expects($this->never())
->method('deleteById');
- $typeMock->expects($this->exactly(2))
+ $typeMock->expects($this->never())
->method('addObject');
$typeMock->expects($this->never())
->method('addObjects');
+ $typeMock->expects($this->once())
+ ->method('addDocuments');
- $objectPersister = new ObjectSerializerPersister($typeMock, $transformer, 'SomeClass');
+ $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()));
}
From f258c9ddc0f1adf3a61fb2e5b3b2a267794a4f6f Mon Sep 17 00:00:00 2001
From: nurikabe
Date: Sun, 1 Dec 2013 21:17:55 +0000
Subject: [PATCH 095/447] Exploratory development for
https://github.com/FriendsOfSymfony/FOSElasticaBundle/issues/410
---
DependencyInjection/FOSElasticaExtension.php | 4 +
Doctrine/AbstractListener.php | 94 ++++++++++++--------
Doctrine/MongoDB/Listener.php | 40 ++-------
Doctrine/ORM/Listener.php | 39 ++------
4 files changed, 78 insertions(+), 99 deletions(-)
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 9bf732e..3caaf57 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -405,11 +405,15 @@ class FOSElasticaExtension extends Extension
private function getDoctrineEvents(array $typeConfig)
{
+ // Flush event always fires; not configurable
+ $typeConfig['listener']['flush'] = true;
+
$events = array();
$eventMapping = array(
'insert' => array('postPersist'),
'update' => array('postUpdate'),
'delete' => array('postRemove', 'preRemove')
+ 'flush' => array('postFlush')
);
foreach ($eventMapping as $event => $doctrineEvents) {
diff --git a/Doctrine/AbstractListener.php b/Doctrine/AbstractListener.php
index 3b62444..9a4385a 100644
--- a/Doctrine/AbstractListener.php
+++ b/Doctrine/AbstractListener.php
@@ -2,8 +2,8 @@
namespace FOS\ElasticaBundle\Doctrine;
+use Doctrine\Common\EventArgs;
use Doctrine\Common\EventSubscriber;
-use Doctrine\Common\Persistence\ObjectManager;
use FOS\ElasticaBundle\Persister\ObjectPersisterInterface;
use FOS\ElasticaBundle\Persister\ObjectPersister;
use Symfony\Component\ExpressionLanguage\Expression;
@@ -48,11 +48,11 @@ abstract class AbstractListener implements EventSubscriber
protected $isIndexableCallback;
/**
- * Objects scheduled for removal
- *
- * @var array
+ * Objects scheduled for insertion, replacement, or removal
*/
- private $scheduledForRemoval = array();
+ protected $scheduledForInsertion = array();
+ protected $scheduledForUpdate = array();
+ protected $scheduledForDeletion = array();
/**
* An instance of ExpressionLanguage
@@ -149,37 +149,6 @@ abstract class AbstractListener implements EventSubscriber
: call_user_func($this->isIndexableCallback, $object);
}
- /**
- * Schedules the object for removal.
- *
- * This is usually called during the pre-remove event.
- *
- * @param object $object
- * @param ObjectManager $objectManager
- */
- protected function scheduleForRemoval($object, ObjectManager $objectManager)
- {
- $metadata = $objectManager->getClassMetadata($this->objectClass);
- $esId = $metadata->getFieldValue($object, $this->esIdentifierField);
- $this->scheduledForRemoval[spl_object_hash($object)] = $esId;
- }
-
- /**
- * Removes the object if it was scheduled for removal.
- *
- * This is usually called during the post-remove event.
- *
- * @param object $object
- */
- protected function removeIfScheduled($object)
- {
- $objectHash = spl_object_hash($object);
- if (isset($this->scheduledForRemoval[$objectHash])) {
- $this->objectPersister->deleteById($this->scheduledForRemoval[$objectHash]);
- unset($this->scheduledForRemoval[$objectHash]);
- }
- }
-
/**
* @param mixed $object
* @return string
@@ -207,4 +176,57 @@ abstract class AbstractListener implements EventSubscriber
return $this->expressionLanguage;
}
+
+ public function postPersist(EventArgs $eventArgs)
+ {
+ $entity = $eventArgs->getEntity();
+
+ if ($entity instanceof $this->objectClass && $this->isObjectIndexable($entity)) {
+ $this->scheduledForInsertion[] = $entity;
+ }
+ }
+
+ public function postUpdate(EventArgs $eventArgs)
+ {
+ $entity = $eventArgs->getEntity();
+
+ if ($entity instanceof $this->objectClass) {
+ if ($this->isObjectIndexable($entity)) {
+ $this->scheduledForUpdate[] = $entity;
+ } else {
+ // Delete if no longer indexable
+ $this->scheduledForDeletion[] = $entity;
+ }
+ }
+ }
+
+ public function preRemove(EventArgs $eventArgs)
+ {
+ $entity = $eventArgs->getEntity();
+
+ if ($entity instanceof $this->objectClass) {
+ $this->scheduledForDeletion[] = $entity;
+ }
+ }
+
+ public function postRemove(EventArgs $eventArgs)
+ {
+ }
+
+ /**
+ * Iterate through scheduled actions *after* flushing to ensure that the ElasticSearch index will only be affected
+ * only if the query is successful
+ */
+ public function postFlush(EventArgs $eventArgs)
+ {
+ foreach ($this->scheduledForInsertion as $entity) {
+ $this->objectPersister->insertOne($entity);
+ }
+ foreach ($this->scheduledForUpdate as $entity) {
+ $this->objectPersister->replaceOne($entity);
+ }
+ foreach ($this->scheduledForDeletion as $entity) {
+ $this->objectPersister->deleteOne($entity);
+ }
+ }
}
diff --git a/Doctrine/MongoDB/Listener.php b/Doctrine/MongoDB/Listener.php
index 9fa3536..13e1d25 100644
--- a/Doctrine/MongoDB/Listener.php
+++ b/Doctrine/MongoDB/Listener.php
@@ -2,49 +2,23 @@
namespace FOS\ElasticaBundle\Doctrine\MongoDB;
-use Doctrine\ODM\MongoDB\Event\LifecycleEventArgs;
+use Doctrine\Common\EventArgs;
use FOS\ElasticaBundle\Doctrine\AbstractListener;
class Listener extends AbstractListener
{
- public function postPersist(LifecycleEventArgs $eventArgs)
+ public function postPersist(EventArgs $eventArgs)
{
- $document = $eventArgs->getDocument();
-
- if ($document instanceof $this->objectClass && $this->isObjectIndexable($document)) {
- $this->objectPersister->insertOne($document);
- }
+ parent::postPersist($eventArgs);
}
- public function postUpdate(LifecycleEventArgs $eventArgs)
+ public function postUpdate(EventArgs $eventArgs)
{
- $document = $eventArgs->getDocument();
-
- if ($document instanceof $this->objectClass) {
- if ($this->isObjectIndexable($document)) {
- $this->objectPersister->replaceOne($document);
- } else {
- $this->scheduleForRemoval($document, $eventArgs->getDocumentManager());
- $this->removeIfScheduled($document);
- }
- }
+ parent::postUpdate($eventArgs);
}
- public function preRemove(LifecycleEventArgs $eventArgs)
+ public function postRemove(EventArgs $eventArgs)
{
- $document = $eventArgs->getDocument();
-
- if ($document instanceof $this->objectClass) {
- $this->scheduleForRemoval($document, $eventArgs->getDocumentManager());
- }
- }
-
- public function postRemove(LifecycleEventArgs $eventArgs)
- {
- $document = $eventArgs->getDocument();
-
- if ($document instanceof $this->objectClass) {
- $this->removeIfScheduled($document);
- }
+ parent::postRemove($eventArgs);
}
}
diff --git a/Doctrine/ORM/Listener.php b/Doctrine/ORM/Listener.php
index 790ddb8..97f8792 100644
--- a/Doctrine/ORM/Listener.php
+++ b/Doctrine/ORM/Listener.php
@@ -2,49 +2,28 @@
namespace FOS\ElasticaBundle\Doctrine\ORM;
-use Doctrine\ORM\Event\LifecycleEventArgs;
+use Doctrine\Common\EventArgs;
use FOS\ElasticaBundle\Doctrine\AbstractListener;
class Listener extends AbstractListener
{
- public function postPersist(LifecycleEventArgs $eventArgs)
+ public function postPersist(EventArgs $eventArgs)
{
- $entity = $eventArgs->getEntity();
-
- if ($entity instanceof $this->objectClass && $this->isObjectIndexable($entity)) {
- $this->objectPersister->insertOne($entity);
- }
+ parent::postPersist($eventArgs);
}
- public function postUpdate(LifecycleEventArgs $eventArgs)
+ public function postUpdate(EventArgs $eventArgs)
{
- $entity = $eventArgs->getEntity();
-
- if ($entity instanceof $this->objectClass) {
- if ($this->isObjectIndexable($entity)) {
- $this->objectPersister->replaceOne($entity);
- } else {
- $this->scheduleForRemoval($entity, $eventArgs->getEntityManager());
- $this->removeIfScheduled($entity);
- }
- }
+ parent::postUpdate($eventArgs);
}
- public function preRemove(LifecycleEventArgs $eventArgs)
+ public function preRemove(EventArgs $eventArgs)
{
- $entity = $eventArgs->getEntity();
-
- if ($entity instanceof $this->objectClass) {
- $this->scheduleForRemoval($entity, $eventArgs->getEntityManager());
- }
+ parent::preRemove($eventArgs);
}
- public function postRemove(LifecycleEventArgs $eventArgs)
+ public function postRemove(EventArgs $eventArgs)
{
- $entity = $eventArgs->getEntity();
-
- if ($entity instanceof $this->objectClass) {
- $this->removeIfScheduled($entity);
- }
+ parent::postRemove($eventArgs);
}
}
From 5ec652063de1c381400488f5607870ba490b21ba Mon Sep 17 00:00:00 2001
From: nurikabe
Date: Sun, 1 Dec 2013 21:48:41 +0000
Subject: [PATCH 096/447] Don't need postRemove.
---
DependencyInjection/FOSElasticaExtension.php | 2 +-
Doctrine/AbstractListener.php | 4 ----
Doctrine/ORM/Listener.php | 5 -----
3 files changed, 1 insertion(+), 10 deletions(-)
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 3caaf57..30ad07a 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -412,7 +412,7 @@ class FOSElasticaExtension extends Extension
$eventMapping = array(
'insert' => array('postPersist'),
'update' => array('postUpdate'),
- 'delete' => array('postRemove', 'preRemove')
+ 'delete' => array('preRemove'),
'flush' => array('postFlush')
);
diff --git a/Doctrine/AbstractListener.php b/Doctrine/AbstractListener.php
index 9a4385a..0fa15df 100644
--- a/Doctrine/AbstractListener.php
+++ b/Doctrine/AbstractListener.php
@@ -209,10 +209,6 @@ abstract class AbstractListener implements EventSubscriber
}
}
- public function postRemove(EventArgs $eventArgs)
- {
- }
-
/**
* Iterate through scheduled actions *after* flushing to ensure that the ElasticSearch index will only be affected
* only if the query is successful
diff --git a/Doctrine/ORM/Listener.php b/Doctrine/ORM/Listener.php
index 97f8792..722b89d 100644
--- a/Doctrine/ORM/Listener.php
+++ b/Doctrine/ORM/Listener.php
@@ -21,9 +21,4 @@ class Listener extends AbstractListener
{
parent::preRemove($eventArgs);
}
-
- public function postRemove(EventArgs $eventArgs)
- {
- parent::postRemove($eventArgs);
- }
}
From 1d700261abb7b7f39c56550cac0732e807240b35 Mon Sep 17 00:00:00 2001
From: nurikabe
Date: Mon, 2 Dec 2013 12:42:04 +0000
Subject: [PATCH 097/447] Refactor to a single Listener class. Update tests.
---
Doctrine/AbstractListener.php | 228 ------------------------
Doctrine/MongoDB/Listener.php | 24 ---
Doctrine/ORM/Listener.php | 24 ---
Resources/config/mongodb.xml | 2 +-
Resources/config/orm.xml | 2 +-
Tests/Doctrine/AbstractListenerTest.php | 75 +++++---
Tests/Doctrine/MongoDB/ListenerTest.php | 6 +-
Tests/Doctrine/ORM/ListenerTest.php | 6 +-
8 files changed, 57 insertions(+), 310 deletions(-)
delete mode 100644 Doctrine/AbstractListener.php
delete mode 100644 Doctrine/MongoDB/Listener.php
delete mode 100644 Doctrine/ORM/Listener.php
diff --git a/Doctrine/AbstractListener.php b/Doctrine/AbstractListener.php
deleted file mode 100644
index 0fa15df..0000000
--- a/Doctrine/AbstractListener.php
+++ /dev/null
@@ -1,228 +0,0 @@
-objectPersister = $objectPersister;
- $this->objectClass = $objectClass;
- $this->events = $events;
- $this->esIdentifierField = $esIdentifierField;
- }
-
- /**
- * @see Doctrine\Common\EventSubscriber::getSubscribedEvents()
- */
- public function getSubscribedEvents()
- {
- return $this->events;
- }
-
- /**
- * Set the callback for determining object index eligibility.
- *
- * If callback is a string, it must be public method on the object class
- * that expects no arguments and returns a boolean. Otherwise, the callback
- * should expect the object for consideration as its only argument and
- * return a boolean.
- *
- * @param callback $callback
- * @throws \RuntimeException if the callback is not callable
- */
- public function setIsIndexableCallback($callback)
- {
- if (is_string($callback)) {
- if (!is_callable(array($this->objectClass, $callback))) {
- if (false !== ($expression = $this->getExpressionLanguage())) {
- $callback = new Expression($callback);
- try {
- $expression->compile($callback, array($this->getExpressionVar()));
- } catch (SyntaxError $e) {
- throw new \RuntimeException(sprintf('Indexable callback %s::%s() is not callable or a valid expression.', $this->objectClass, $callback), 0, $e);
- }
- } else {
- throw new \RuntimeException(sprintf('Indexable callback %s::%s() is not callable.', $this->objectClass, $callback));
- }
- }
- } elseif (!is_callable($callback)) {
- if (is_array($callback)) {
- list($class, $method) = $callback + array(null, null);
- if (is_object($class)) {
- $class = get_class($class);
- }
-
- if ($class && $method) {
- throw new \RuntimeException(sprintf('Indexable callback %s::%s() is not callable.', $class, $method));
- }
- }
- throw new \RuntimeException('Indexable callback is not callable.');
- }
-
- $this->isIndexableCallback = $callback;
- }
-
- /**
- * Return whether the object is indexable with respect to the callback.
- *
- * @param object $object
- * @return boolean
- */
- protected function isObjectIndexable($object)
- {
- if (!$this->isIndexableCallback) {
- return true;
- }
-
- if ($this->isIndexableCallback instanceof Expression) {
- return $this->getExpressionLanguage()->evaluate($this->isIndexableCallback, array($this->getExpressionVar($object) => $object));
- }
-
- return is_string($this->isIndexableCallback)
- ? call_user_func(array($object, $this->isIndexableCallback))
- : call_user_func($this->isIndexableCallback, $object);
- }
-
- /**
- * @param mixed $object
- * @return string
- */
- private function getExpressionVar($object = null)
- {
- $class = $object ?: $this->objectClass;
- $ref = new \ReflectionClass($class);
-
- return strtolower($ref->getShortName());
- }
-
- /**
- * @return bool|ExpressionLanguage
- */
- private function getExpressionLanguage()
- {
- if (null === $this->expressionLanguage) {
- if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
- return false;
- }
-
- $this->expressionLanguage = new ExpressionLanguage();
- }
-
- return $this->expressionLanguage;
- }
-
- public function postPersist(EventArgs $eventArgs)
- {
- $entity = $eventArgs->getEntity();
-
- if ($entity instanceof $this->objectClass && $this->isObjectIndexable($entity)) {
- $this->scheduledForInsertion[] = $entity;
- }
- }
-
- public function postUpdate(EventArgs $eventArgs)
- {
- $entity = $eventArgs->getEntity();
-
- if ($entity instanceof $this->objectClass) {
- if ($this->isObjectIndexable($entity)) {
- $this->scheduledForUpdate[] = $entity;
- } else {
- // Delete if no longer indexable
- $this->scheduledForDeletion[] = $entity;
- }
- }
- }
-
- public function preRemove(EventArgs $eventArgs)
- {
- $entity = $eventArgs->getEntity();
-
- if ($entity instanceof $this->objectClass) {
- $this->scheduledForDeletion[] = $entity;
- }
- }
-
- /**
- * Iterate through scheduled actions *after* flushing to ensure that the ElasticSearch index will only be affected
- * only if the query is successful
- */
- public function postFlush(EventArgs $eventArgs)
- {
- foreach ($this->scheduledForInsertion as $entity) {
- $this->objectPersister->insertOne($entity);
- }
- foreach ($this->scheduledForUpdate as $entity) {
- $this->objectPersister->replaceOne($entity);
- }
- foreach ($this->scheduledForDeletion as $entity) {
- $this->objectPersister->deleteOne($entity);
- }
- }
-}
diff --git a/Doctrine/MongoDB/Listener.php b/Doctrine/MongoDB/Listener.php
deleted file mode 100644
index 13e1d25..0000000
--- a/Doctrine/MongoDB/Listener.php
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
+
diff --git a/Resources/config/orm.xml b/Resources/config/orm.xml
index 4fd6ae7..5bd16e5 100644
--- a/Resources/config/orm.xml
+++ b/Resources/config/orm.xml
@@ -13,7 +13,7 @@
-
+
diff --git a/Tests/Doctrine/AbstractListenerTest.php b/Tests/Doctrine/AbstractListenerTest.php
index e99e26d..a6ad2aa 100644
--- a/Tests/Doctrine/AbstractListenerTest.php
+++ b/Tests/Doctrine/AbstractListenerTest.php
@@ -3,9 +3,11 @@
namespace FOS\ElasticaBundle\Tests\Doctrine;
/**
+ * See concrete MongoDB/ORM instances of this abstract test
+ *
* @author Richard Miller
*/
-abstract class AbstractListenerTest extends \PHPUnit_Framework_TestCase
+abstract class ListenerTest extends \PHPUnit_Framework_TestCase
{
public function testObjectInsertedOnPersist()
{
@@ -14,12 +16,16 @@ abstract class AbstractListenerTest extends \PHPUnit_Framework_TestCase
$entity = new Listener\Entity(1);
$eventArgs = $this->createLifecycleEventArgs($entity, $this->getMockObjectManager());
+ $listener = $this->createListener($persister, get_class($entity), array());
+ $listener->postPersist($eventArgs);
+
+ $this->assertEquals($entity, current($listener->scheduledForInsertion));
+
$persister->expects($this->once())
->method('insertOne')
->with($entity);
- $listener = $this->createListener($persister, get_class($entity), array());
- $listener->postPersist($eventArgs);
+ $listener->postFlush($eventArgs);
}
/**
@@ -32,12 +38,16 @@ abstract class AbstractListenerTest extends \PHPUnit_Framework_TestCase
$entity = new Listener\Entity(1, false);
$eventArgs = $this->createLifecycleEventArgs($entity, $this->getMockObjectManager());
- $persister->expects($this->never())
- ->method('insertOne');
-
$listener = $this->createListener($persister, get_class($entity), array());
$listener->setIsIndexableCallback($isIndexableCallback);
$listener->postPersist($eventArgs);
+
+ $this->assertEmpty($listener->scheduledForInsertion);
+
+ $persister->expects($this->never())
+ ->method('insertOne');
+
+ $listener->postFlush($eventArgs);
}
public function testObjectReplacedOnUpdate()
@@ -47,15 +57,18 @@ abstract class AbstractListenerTest extends \PHPUnit_Framework_TestCase
$entity = new Listener\Entity(1);
$eventArgs = $this->createLifecycleEventArgs($entity, $this->getMockObjectManager());
+ $listener = $this->createListener($persister, get_class($entity), array());
+ $listener->postUpdate($eventArgs);
+
+ $this->assertEquals($entity, current($listener->scheduledForUpdate));
+
$persister->expects($this->once())
->method('replaceOne')
->with($entity);
-
$persister->expects($this->never())
->method('deleteById');
- $listener = $this->createListener($persister, get_class($entity), array());
- $listener->postUpdate($eventArgs);
+ $listener->postFlush($eventArgs);
}
/**
@@ -80,16 +93,20 @@ abstract class AbstractListenerTest extends \PHPUnit_Framework_TestCase
->with($entity, 'id')
->will($this->returnValue($entity->getId()));
- $persister->expects($this->never())
- ->method('replaceOne');
-
- $persister->expects($this->once())
- ->method('deleteById')
- ->with($entity->getId());
-
$listener = $this->createListener($persister, get_class($entity), array());
$listener->setIsIndexableCallback($isIndexableCallback);
$listener->postUpdate($eventArgs);
+
+ $this->assertEmpty($listener->scheduledForUpdate);
+ $this->assertEquals($entity, current($listener->scheduledForDeletion));
+
+ $persister->expects($this->never())
+ ->method('replaceOne');
+ $persister->expects($this->once())
+ ->method('deleteOne')
+ ->with($entity);
+
+ $listener->postFlush($eventArgs);
}
public function testObjectDeletedOnRemove()
@@ -111,13 +128,16 @@ abstract class AbstractListenerTest extends \PHPUnit_Framework_TestCase
->with($entity, 'id')
->will($this->returnValue($entity->getId()));
- $persister->expects($this->once())
- ->method('deleteById')
- ->with($entity->getId());
-
$listener = $this->createListener($persister, get_class($entity), array());
$listener->preRemove($eventArgs);
- $listener->postRemove($eventArgs);
+
+ $this->assertEquals($entity, current($listener->scheduledForDeletion));
+
+ $persister->expects($this->once())
+ ->method('deleteOne')
+ ->with($entity);
+
+ $listener->postFlush($eventArgs);
}
public function testObjectWithNonStandardIdentifierDeletedOnRemove()
@@ -139,13 +159,16 @@ abstract class AbstractListenerTest extends \PHPUnit_Framework_TestCase
->with($entity, 'identifier')
->will($this->returnValue($entity->getId()));
- $persister->expects($this->once())
- ->method('deleteById')
- ->with($entity->getId());
-
$listener = $this->createListener($persister, get_class($entity), array(), 'identifier');
$listener->preRemove($eventArgs);
- $listener->postRemove($eventArgs);
+
+ $this->assertEquals($entity, current($listener->scheduledForDeletion));
+
+ $persister->expects($this->once())
+ ->method('deleteOne')
+ ->with($entity);
+
+ $listener->postFlush($eventArgs);
}
/**
diff --git a/Tests/Doctrine/MongoDB/ListenerTest.php b/Tests/Doctrine/MongoDB/ListenerTest.php
index 7f1a9ab..37a0203 100644
--- a/Tests/Doctrine/MongoDB/ListenerTest.php
+++ b/Tests/Doctrine/MongoDB/ListenerTest.php
@@ -2,9 +2,9 @@
namespace FOS\ElasticaBundle\Tests\Doctrine\MongoDB;
-use FOS\ElasticaBundle\Tests\Doctrine\AbstractListenerTest;
+use FOS\ElasticaBundle\Tests\Doctrine\ListenerTest as BaseListenerTest;
-class ListenerTest extends AbstractListenerTest
+class ListenerTest extends BaseListenerTest
{
public function setUp()
{
@@ -25,7 +25,7 @@ class ListenerTest extends AbstractListenerTest
protected function getListenerClass()
{
- return 'FOS\ElasticaBundle\Doctrine\MongoDB\Listener';
+ return 'FOS\ElasticaBundle\Doctrine\Listener';
}
protected function getObjectManagerClass()
diff --git a/Tests/Doctrine/ORM/ListenerTest.php b/Tests/Doctrine/ORM/ListenerTest.php
index 48702c0..12a89b2 100644
--- a/Tests/Doctrine/ORM/ListenerTest.php
+++ b/Tests/Doctrine/ORM/ListenerTest.php
@@ -2,9 +2,9 @@
namespace FOS\ElasticaBundle\Tests\Doctrine\ORM;
-use FOS\ElasticaBundle\Tests\Doctrine\AbstractListenerTest;
+use FOS\ElasticaBundle\Tests\Doctrine\ListenerTest as BaseListenerTest;
-class ListenerTest extends AbstractListenerTest
+class ListenerTest extends BaseListenerTest
{
public function setUp()
{
@@ -25,7 +25,7 @@ class ListenerTest extends AbstractListenerTest
protected function getListenerClass()
{
- return 'FOS\ElasticaBundle\Doctrine\ORM\Listener';
+ return 'FOS\ElasticaBundle\Doctrine\Listener';
}
protected function getObjectManagerClass()
From cf3e35e892f8dcc40727b8d048819f00119ee87b Mon Sep 17 00:00:00 2001
From: Damien Alexandre
Date: Mon, 2 Dec 2013 22:15:11 +0100
Subject: [PATCH 098/447] Remove extra line-break
---
Persister/ObjectSerializerPersister.php | 1 -
1 file changed, 1 deletion(-)
diff --git a/Persister/ObjectSerializerPersister.php b/Persister/ObjectSerializerPersister.php
index 40305c4..c0d2d28 100644
--- a/Persister/ObjectSerializerPersister.php
+++ b/Persister/ObjectSerializerPersister.php
@@ -72,7 +72,6 @@ class ObjectSerializerPersister extends ObjectPersister
$this->type->deleteById($id);
}
-
/**
* Inserts an array of objects in the type
*
From 25e59a311badec60ceccbabbe4b53e40d18acb38 Mon Sep 17 00:00:00 2001
From: Damien Alexandre
Date: Mon, 2 Dec 2013 22:26:30 +0100
Subject: [PATCH 099/447] Fix Persister constructor and undefined property
---
Persister/ObjectSerializerPersister.php | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Persister/ObjectSerializerPersister.php b/Persister/ObjectSerializerPersister.php
index c0d2d28..8938a2f 100644
--- a/Persister/ObjectSerializerPersister.php
+++ b/Persister/ObjectSerializerPersister.php
@@ -15,11 +15,11 @@ use FOS\ElasticaBundle\Transformer\ModelToElasticaTransformerInterface;
*/
class ObjectSerializerPersister extends ObjectPersister
{
+ protected $serializer;
+
public function __construct(Type $type, ModelToElasticaTransformerInterface $transformer, $objectClass, $serializer)
{
- $this->type = $type;
- $this->transformer = $transformer;
- $this->objectClass = $objectClass;
+ parent::__construct($type, $transformer, $objectClass, array());
$this->serializer = $serializer;
}
From 8a4848a16dc916afda6ebd3632e4d3894a571755 Mon Sep 17 00:00:00 2001
From: Damien Alexandre
Date: Mon, 2 Dec 2013 22:35:50 +0100
Subject: [PATCH 100/447] Add UPGRADE-3.0.md file with descriptions of new
features / changes
---
UPGRADE-3.0.md | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
create mode 100644 UPGRADE-3.0.md
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: ~
+ ```
From af2827df016feea3463ba911454f12ab3b1e6b00 Mon Sep 17 00:00:00 2001
From: nurikabe
Date: Tue, 3 Dec 2013 14:01:21 +0000
Subject: [PATCH 101/447] Re-add renamed Listener.
---
Doctrine/Listener.php | 228 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 228 insertions(+)
create mode 100644 Doctrine/Listener.php
diff --git a/Doctrine/Listener.php b/Doctrine/Listener.php
new file mode 100644
index 0000000..6584207
--- /dev/null
+++ b/Doctrine/Listener.php
@@ -0,0 +1,228 @@
+objectPersister = $objectPersister;
+ $this->objectClass = $objectClass;
+ $this->events = $events;
+ $this->esIdentifierField = $esIdentifierField;
+ }
+
+ /**
+ * @see Doctrine\Common\EventSubscriber::getSubscribedEvents()
+ */
+ public function getSubscribedEvents()
+ {
+ return $this->events;
+ }
+
+ /**
+ * Set the callback for determining object index eligibility.
+ *
+ * If callback is a string, it must be public method on the object class
+ * that expects no arguments and returns a boolean. Otherwise, the callback
+ * should expect the object for consideration as its only argument and
+ * return a boolean.
+ *
+ * @param callback $callback
+ * @throws \RuntimeException if the callback is not callable
+ */
+ public function setIsIndexableCallback($callback)
+ {
+ if (is_string($callback)) {
+ if (!is_callable(array($this->objectClass, $callback))) {
+ if (false !== ($expression = $this->getExpressionLanguage())) {
+ $callback = new Expression($callback);
+ try {
+ $expression->compile($callback, array($this->getExpressionVar()));
+ } catch (SyntaxError $e) {
+ throw new \RuntimeException(sprintf('Indexable callback %s::%s() is not callable or a valid expression.', $this->objectClass, $callback), 0, $e);
+ }
+ } else {
+ throw new \RuntimeException(sprintf('Indexable callback %s::%s() is not callable.', $this->objectClass, $callback));
+ }
+ }
+ } elseif (!is_callable($callback)) {
+ if (is_array($callback)) {
+ list($class, $method) = $callback + array(null, null);
+ if (is_object($class)) {
+ $class = get_class($class);
+ }
+
+ if ($class && $method) {
+ throw new \RuntimeException(sprintf('Indexable callback %s::%s() is not callable.', $class, $method));
+ }
+ }
+ throw new \RuntimeException('Indexable callback is not callable.');
+ }
+
+ $this->isIndexableCallback = $callback;
+ }
+
+ /**
+ * Return whether the object is indexable with respect to the callback.
+ *
+ * @param object $object
+ * @return boolean
+ */
+ protected function isObjectIndexable($object)
+ {
+ if (!$this->isIndexableCallback) {
+ return true;
+ }
+
+ if ($this->isIndexableCallback instanceof Expression) {
+ return $this->getExpressionLanguage()->evaluate($this->isIndexableCallback, array($this->getExpressionVar($object) => $object));
+ }
+
+ return is_string($this->isIndexableCallback)
+ ? call_user_func(array($object, $this->isIndexableCallback))
+ : call_user_func($this->isIndexableCallback, $object);
+ }
+
+ /**
+ * @param mixed $object
+ * @return string
+ */
+ private function getExpressionVar($object = null)
+ {
+ $class = $object ?: $this->objectClass;
+ $ref = new \ReflectionClass($class);
+
+ return strtolower($ref->getShortName());
+ }
+
+ /**
+ * @return bool|ExpressionLanguage
+ */
+ private function getExpressionLanguage()
+ {
+ if (null === $this->expressionLanguage) {
+ if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
+ return false;
+ }
+
+ $this->expressionLanguage = new ExpressionLanguage();
+ }
+
+ return $this->expressionLanguage;
+ }
+
+ public function postPersist(EventArgs $eventArgs)
+ {
+ $entity = $eventArgs->getEntity();
+
+ if ($entity instanceof $this->objectClass && $this->isObjectIndexable($entity)) {
+ $this->scheduledForInsertion[] = $entity;
+ }
+ }
+
+ public function postUpdate(EventArgs $eventArgs)
+ {
+ $entity = $eventArgs->getEntity();
+
+ if ($entity instanceof $this->objectClass) {
+ if ($this->isObjectIndexable($entity)) {
+ $this->scheduledForUpdate[] = $entity;
+ } else {
+ // Delete if no longer indexable
+ $this->scheduledForDeletion[] = $entity;
+ }
+ }
+ }
+
+ public function preRemove(EventArgs $eventArgs)
+ {
+ $entity = $eventArgs->getEntity();
+
+ if ($entity instanceof $this->objectClass) {
+ $this->scheduledForDeletion[] = $entity;
+ }
+ }
+
+ /**
+ * Iterate through scheduled actions *after* flushing to ensure that the ElasticSearch index will only be affected
+ * only if the query is successful
+ */
+ public function postFlush(EventArgs $eventArgs)
+ {
+ foreach ($this->scheduledForInsertion as $entity) {
+ $this->objectPersister->insertOne($entity);
+ }
+ foreach ($this->scheduledForUpdate as $entity) {
+ $this->objectPersister->replaceOne($entity);
+ }
+ foreach ($this->scheduledForDeletion as $entity) {
+ $this->objectPersister->deleteOne($entity);
+ }
+ }
+}
From 22a5d67d05d2df4fe46ca6e80f4b21198f2d3b19 Mon Sep 17 00:00:00 2001
From: nurikabe
Date: Tue, 3 Dec 2013 20:41:26 +0000
Subject: [PATCH 102/447] pre/postFlush configuration. Update documentation.
---
DependencyInjection/Configuration.php | 2 ++
DependencyInjection/FOSElasticaExtension.php | 6 +++--
Doctrine/Listener.php | 23 +++++++++++++++++---
README.md | 22 ++++++++++++++++---
UPGRADE-3.0.md | 11 ++++++++++
5 files changed, 56 insertions(+), 8 deletions(-)
create mode 100644 UPGRADE-3.0.md
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index fe7e9a4..50d4b89 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -165,6 +165,7 @@ class Configuration implements ConfigurationInterface
->scalarNode('insert')->defaultTrue()->end()
->scalarNode('update')->defaultTrue()->end()
->scalarNode('delete')->defaultTrue()->end()
+ ->scalarNode('persist')->defaultValue('postFlush')->end()
->scalarNode('service')->end()
->variableNode('is_indexable_callback')->defaultNull()->end()
->end()
@@ -257,6 +258,7 @@ class Configuration implements ConfigurationInterface
->scalarNode('insert')->defaultTrue()->end()
->scalarNode('update')->defaultTrue()->end()
->scalarNode('delete')->defaultTrue()->end()
+ ->booleanNode('immediate')->defaultFalse()->end()
->scalarNode('service')->end()
->variableNode('is_indexable_callback')->defaultNull()->end()
->end()
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 30ad07a..4a7ebbc 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -405,7 +405,7 @@ class FOSElasticaExtension extends Extension
private function getDoctrineEvents(array $typeConfig)
{
- // Flush event always fires; not configurable
+ // Flush always calls depending on actions scheduled in lifecycle listeners
$typeConfig['listener']['flush'] = true;
$events = array();
@@ -413,9 +413,11 @@ class FOSElasticaExtension extends Extension
'insert' => array('postPersist'),
'update' => array('postUpdate'),
'delete' => array('preRemove'),
- 'flush' => array('postFlush')
+ 'flush' => array($typeConfig['listener']['immediate'] ? 'preFlush' : 'postFlush')
);
+ var_dump($eventMapping);
+
foreach ($eventMapping as $event => $doctrineEvents) {
if (isset($typeConfig['listener'][$event]) && $typeConfig['listener'][$event]) {
$events = array_merge($events, $doctrineEvents);
diff --git a/Doctrine/Listener.php b/Doctrine/Listener.php
index 6584207..683070e 100644
--- a/Doctrine/Listener.php
+++ b/Doctrine/Listener.php
@@ -210,10 +210,9 @@ class Listener implements EventSubscriber
}
/**
- * Iterate through scheduled actions *after* flushing to ensure that the ElasticSearch index will only be affected
- * only if the query is successful
+ * Persist scheduled action to ElasticSearch
*/
- public function postFlush(EventArgs $eventArgs)
+ private function persistScheduled()
{
foreach ($this->scheduledForInsertion as $entity) {
$this->objectPersister->insertOne($entity);
@@ -225,4 +224,22 @@ class Listener implements EventSubscriber
$this->objectPersister->deleteOne($entity);
}
}
+
+ /**
+ * Iterate through scheduled actions before flushing to emulate 2.x behavior. Note that the ElasticSearch index
+ * will fall out of sync with the data source in event of a crash on flush.
+ */
+ public function preFlush(EventArgs $eventArgs)
+ {
+ $this->persistScheduled();
+ }
+
+ /**
+ * Iterating through scheduled actions *after* flushing ensures that the ElasticSearch index will be affected
+ * only if the query is successful
+ */
+ public function postFlush(EventArgs $eventArgs)
+ {
+ $this->persistScheduled();
+ }
}
diff --git a/README.md b/README.md
index 9792139..9f77a1b 100644
--- a/README.md
+++ b/README.md
@@ -576,7 +576,11 @@ class User
### Realtime, selective index update
If you use the Doctrine integration, you can let ElasticaBundle update the indexes automatically
-when an object is added, updated or removed. It uses Doctrine lifecycle events.
+when an object is added, updated or removed. It uses Doctrine lifecycle events to schedule updates
+and then synchronizes changes either before or after flush.
+
+> **Propel** doesn't support this feature yet.
+
Declare that you want to update the index in real time:
fos_elastica:
@@ -592,7 +596,7 @@ Declare that you want to update the index in real time:
persistence:
driver: orm
model: Application\UserBundle\Entity\User
- listener: ~ # by default, listens to "insert", "update" and "delete"
+ listener: ~ # by default, listens to "insert", "update" and "delete" and updates `postFlush`
Now the index is automatically updated each time the state of the bound Doctrine repository changes.
No need to repopulate the whole "user" index when a new `User` is created.
@@ -605,7 +609,19 @@ You can also choose to only listen for some of the events:
update: false
delete: true
-> **Propel** doesn't support this feature yet.
+By default, the ElasticSearch index will be updated after flush. To update before flushing, set `immediate`
+to `true`:
+
+ persistence:
+ listener:
+ insert: true
+ update: false
+ delete: true
+ immediate: true
+
+> Updating ElasticSearch before flushing may cause the ElasticSearch index to fall out of sync with the
+> original data in the event of a crash.
+
### Checking an entity method for listener
diff --git a/UPGRADE-3.0.md b/UPGRADE-3.0.md
new file mode 100644
index 0000000..0b0d370
--- /dev/null
+++ b/UPGRADE-3.0.md
@@ -0,0 +1,11 @@
+UPGRADE FROM 2.x to 3.0
+=======================
+
+### ElasticSearch Synchronization Event
+
+ * Prior to 3.0, the ElasticSearch index was synchronized in the `postInsert`,
+ `postUpdate`, and `pre/postRemove` events which fire before flush. Because
+ of this, exceptions thrown when flushing would cause the data source and
+ ElasticSearch index to fall out of sync.
+
+ As of 3.0, ElasticSearch is updated `postFlush` by default.
From ed21e60869e86a5372f3d1a69ee97c4f61c65829 Mon Sep 17 00:00:00 2001
From: nurikabe
Date: Tue, 3 Dec 2013 23:40:00 +0000
Subject: [PATCH 103/447] Remove upgrade doc. Merk will add manually.
---
UPGRADE-3.0.md | 11 -----------
1 file changed, 11 deletions(-)
delete mode 100644 UPGRADE-3.0.md
diff --git a/UPGRADE-3.0.md b/UPGRADE-3.0.md
deleted file mode 100644
index 0b0d370..0000000
--- a/UPGRADE-3.0.md
+++ /dev/null
@@ -1,11 +0,0 @@
-UPGRADE FROM 2.x to 3.0
-=======================
-
-### ElasticSearch Synchronization Event
-
- * Prior to 3.0, the ElasticSearch index was synchronized in the `postInsert`,
- `postUpdate`, and `pre/postRemove` events which fire before flush. Because
- of this, exceptions thrown when flushing would cause the data source and
- ElasticSearch index to fall out of sync.
-
- As of 3.0, ElasticSearch is updated `postFlush` by default.
From 8b6dffbc141d07bdbd446680e1f854a20617686f Mon Sep 17 00:00:00 2001
From: Ben Longden
Date: Tue, 3 Dec 2013 15:45:43 +0000
Subject: [PATCH 104/447] Adds enabled mapping option (default true)
---
DependencyInjection/Configuration.php | 1 +
1 file changed, 1 insertion(+)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 4482a4c..af27f09 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -311,6 +311,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()
From 3a279f8edbff1eed66c224516904917725ccfc6b Mon Sep 17 00:00:00 2001
From: nurikabe
Date: Wed, 4 Dec 2013 10:46:05 +0000
Subject: [PATCH 105/447] Remove debug.
---
DependencyInjection/FOSElasticaExtension.php | 2 --
1 file changed, 2 deletions(-)
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 4a7ebbc..6380873 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -416,8 +416,6 @@ class FOSElasticaExtension extends Extension
'flush' => array($typeConfig['listener']['immediate'] ? 'preFlush' : 'postFlush')
);
- var_dump($eventMapping);
-
foreach ($eventMapping as $event => $doctrineEvents) {
if (isset($typeConfig['listener'][$event]) && $typeConfig['listener'][$event]) {
$events = array_merge($events, $doctrineEvents);
From 759950aff66092489a5d40f79d2c5c2aea1a9194 Mon Sep 17 00:00:00 2001
From: Pierre du Plessis
Date: Mon, 4 Nov 2013 17:24:35 +0200
Subject: [PATCH 106/447] Add option to disable logger or specify different
logger service
---
DependencyInjection/Configuration.php | 13 ++++++++++---
DependencyInjection/FOSElasticaExtension.php | 5 ++++-
2 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 8a067b5..e05dd2e 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' => $v['logger']
)
)
);
@@ -89,7 +90,8 @@ class Configuration implements ConfigurationInterface
return array(
'servers' => array(
array(
- 'url' => $v['url'],
+ 'url' => $v['url'],
+ 'logger' => $v['logger']
)
)
);
@@ -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()
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index eb6dd4d..bcf8e84 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -73,7 +73,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);
From 08193ec2fd9b0e47961cbe9c64289bff91500729 Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Thu, 5 Dec 2013 16:35:30 +0100
Subject: [PATCH 107/447] Add support to disable the _all field for a type
---
DependencyInjection/Configuration.php | 18 ++++++++++++++++++
DependencyInjection/FOSElasticaExtension.php | 3 +++
2 files changed, 21 insertions(+)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index f9f633f..3c3ea9e 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -288,6 +288,7 @@ class Configuration implements ConfigurationInterface
->append($this->getBoostNode())
->append($this->getRoutingNode())
->append($this->getParentNode())
+ ->append($this->getAllNode())
->end()
;
@@ -530,4 +531,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 d83b604..cba715c 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -231,6 +231,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'];
+ }
}
}
From c97a4abceb3fe0b42c660b30c63e721ee888c6d7 Mon Sep 17 00:00:00 2001
From: Damien Alexandre
Date: Mon, 9 Dec 2013 10:09:36 +0100
Subject: [PATCH 108/447] Add display cURL on the web debug queries shower
---
Resources/views/Collector/elastica.html.twig | 35 +++++++++++++++++++-
1 file changed, 34 insertions(+), 1 deletion(-)
diff --git a/Resources/views/Collector/elastica.html.twig b/Resources/views/Collector/elastica.html.twig
index a665e2d..bfbd31a 100644
--- a/Resources/views/Collector/elastica.html.twig
+++ b/Resources/views/Collector/elastica.html.twig
@@ -41,7 +41,7 @@
{% else %}
+
+
{% endif %}
{% endblock %}
From ca507a5e347d376729f6496030c40ff1eac35b7f Mon Sep 17 00:00:00 2001
From: Damien Alexandre
Date: Mon, 9 Dec 2013 10:40:47 +0100
Subject: [PATCH 109/447] Add full_host in logger for HTTP(s) queries
---
Client.php | 13 ++++++++++++-
Logger/ElasticaLogger.php | 6 ++++--
Resources/views/Collector/elastica.html.twig | 19 ++++++++++---------
Tests/Logger/ElasticaLoggerTest.php | 7 ++++---
4 files changed, 30 insertions(+), 15 deletions(-)
diff --git a/Client.php b/Client.php
index 8430b36..8c9be1a 100644
--- a/Client.php
+++ b/Client.php
@@ -4,6 +4,8 @@ namespace FOS\ElasticaBundle;
use Elastica\Client as ElasticaClient;
use Elastica\Request;
+use Elastica\Transport\Http;
+use Elastica\Transport\Https;
/**
* @author Gordon Franke
@@ -17,7 +19,16 @@ class Client extends ElasticaClient
if (null !== $this->_logger) {
$time = microtime(true) - $start;
- $this->_logger->logQuery($path, $method, $data, $time);
+
+ $connection = $this->getLastRequest()->getConnection();
+ $transport = $connection->getTransportObject();
+ $full_host = null;
+
+ if ($transport instanceof Http || $transport instanceof Https) {
+ $full_host = $connection->getTransport().'://'.$connection->getHost().':'.$connection->getPort();
+ }
+
+ $this->_logger->logQuery($path, $method, $data, $time, $full_host);
}
return $response;
diff --git a/Logger/ElasticaLogger.php b/Logger/ElasticaLogger.php
index 1705d06..2d8d0ae 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 string $full_host host and port of the query
*/
- public function logQuery($path, $method, $data, $time)
+ public function logQuery($path, $method, $data, $time, $full_host = null)
{
if ($this->debug) {
$this->queries[] = array(
'path' => $path,
'method' => $method,
'data' => $data,
- 'executionMS' => $time
+ 'executionMS' => $time,
+ 'full_host' => $full_host
);
}
diff --git a/Resources/views/Collector/elastica.html.twig b/Resources/views/Collector/elastica.html.twig
index bfbd31a..8b27376 100644
--- a/Resources/views/Collector/elastica.html.twig
+++ b/Resources/views/Collector/elastica.html.twig
@@ -52,15 +52,17 @@
Time: {{ '%0.2f'|format(query.executionMS * 1000) }} ms
-
-
-
- Display cURL query
-
+ {% if query.full_host %}
+
+
+
+ Display cURL query
+
-
- curl -X{{ query.method }} 'http://localhost:9200/{{ query.path }}' -d '{{ query.data|json_encode }}'
-
+
+ curl -X{{ query.method }} '{{ query.full_host }}/{{ query.path }}' -d '{{ query.data|json_encode }}'
+
+ {% endif %}
{% endfor %}
@@ -79,7 +81,6 @@
} else {
sections[0].style.display = 'inline';
sections[1].style.display = 'none';
- //sections[3].style.display = 'none';
document.getElementById(link.hash.replace("#", "")).style.display = 'none';
}
diff --git a/Tests/Logger/ElasticaLoggerTest.php b/Tests/Logger/ElasticaLoggerTest.php
index 3cf6d2d..73ba4ac 100644
--- a/Tests/Logger/ElasticaLoggerTest.php
+++ b/Tests/Logger/ElasticaLoggerTest.php
@@ -9,7 +9,6 @@ use FOS\ElasticaBundle\Logger\ElasticaLogger;
*/
class ElasticaLoggerTest extends \PHPUnit_Framework_TestCase
{
-
public function testGetZeroIfNoQueriesAdded()
{
$elasticaLogger = new ElasticaLogger;
@@ -36,15 +35,17 @@ class ElasticaLoggerTest extends \PHPUnit_Framework_TestCase
$method = 'testMethod';
$data = array('data');
$time = 12;
+ $full_host = 'http://example.com:9200';
$expected = array(
'path' => $path,
'method' => $method,
'data' => $data,
- 'executionMS' => $time
+ 'executionMS' => $time,
+ 'full_host' => $full_host,
);
- $elasticaLogger->logQuery($path, $method, $data, $time);
+ $elasticaLogger->logQuery($path, $method, $data, $time, $full_host);
$returnedQueries = $elasticaLogger->getQueries();
$this->assertEquals($expected, $returnedQueries[0]);
}
From 1ddd7c0e0cb054e7438a3c07fbd6e633267dc503 Mon Sep 17 00:00:00 2001
From: Damien Alexandre
Date: Mon, 9 Dec 2013 14:46:06 +0100
Subject: [PATCH 110/447] Store connection infos for all transports, display
infos in debug
---
Client.php | 14 ++++++--------
Logger/ElasticaLogger.php | 6 +++---
Resources/views/Collector/elastica.html.twig | 6 +++---
Tests/Logger/ElasticaLoggerTest.php | 6 +++---
4 files changed, 15 insertions(+), 17 deletions(-)
diff --git a/Client.php b/Client.php
index 8c9be1a..119f420 100644
--- a/Client.php
+++ b/Client.php
@@ -4,8 +4,6 @@ namespace FOS\ElasticaBundle;
use Elastica\Client as ElasticaClient;
use Elastica\Request;
-use Elastica\Transport\Http;
-use Elastica\Transport\Https;
/**
* @author Gordon Franke
@@ -21,14 +19,14 @@ class Client extends ElasticaClient
$time = microtime(true) - $start;
$connection = $this->getLastRequest()->getConnection();
- $transport = $connection->getTransportObject();
- $full_host = null;
- if ($transport instanceof Http || $transport instanceof Https) {
- $full_host = $connection->getTransport().'://'.$connection->getHost().':'.$connection->getPort();
- }
+ $connection_array = array(
+ 'host' => $connection->getHost(),
+ 'port' => $connection->getPort(),
+ 'transport' => $connection->getTransport(),
+ );
- $this->_logger->logQuery($path, $method, $data, $time, $full_host);
+ $this->_logger->logQuery($path, $method, $data, $time, $connection_array);
}
return $response;
diff --git a/Logger/ElasticaLogger.php b/Logger/ElasticaLogger.php
index 2d8d0ae..bf7694e 100644
--- a/Logger/ElasticaLogger.php
+++ b/Logger/ElasticaLogger.php
@@ -38,9 +38,9 @@ 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 string $full_host host and port of the query
+ * @param array $connection host, port and transport of the query
*/
- public function logQuery($path, $method, $data, $time, $full_host = null)
+ public function logQuery($path, $method, $data, $time, $connection = array())
{
if ($this->debug) {
$this->queries[] = array(
@@ -48,7 +48,7 @@ class ElasticaLogger implements LoggerInterface
'method' => $method,
'data' => $data,
'executionMS' => $time,
- 'full_host' => $full_host
+ 'connection' => $connection
);
}
diff --git a/Resources/views/Collector/elastica.html.twig b/Resources/views/Collector/elastica.html.twig
index 8b27376..5da6048 100644
--- a/Resources/views/Collector/elastica.html.twig
+++ b/Resources/views/Collector/elastica.html.twig
@@ -44,7 +44,7 @@
{% 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 }}
@@ -52,7 +52,7 @@
Time: {{ '%0.2f'|format(query.executionMS * 1000) }} ms
- {% if query.full_host %}
+ {% if query.connection.transport in ['Http', 'Https'] %}{# cURL support only HTTP #}
@@ -60,7 +60,7 @@
- curl -X{{ query.method }} '{{ query.full_host }}/{{ query.path }}' -d '{{ query.data|json_encode }}'
+ curl -X{{ query.method }} '{{ query.connection.transport|lower }}://{{ query.connection.host }}:{{ query.connection.port }}/{{ query.path }}' -d '{{ query.data|json_encode }}'
{% endif %}
diff --git a/Tests/Logger/ElasticaLoggerTest.php b/Tests/Logger/ElasticaLoggerTest.php
index 73ba4ac..18eb44b 100644
--- a/Tests/Logger/ElasticaLoggerTest.php
+++ b/Tests/Logger/ElasticaLoggerTest.php
@@ -35,17 +35,17 @@ class ElasticaLoggerTest extends \PHPUnit_Framework_TestCase
$method = 'testMethod';
$data = array('data');
$time = 12;
- $full_host = 'http://example.com:9200';
+ $connection = array('host' => 'localhost', 'port' => '8999', 'transport' => 'https');
$expected = array(
'path' => $path,
'method' => $method,
'data' => $data,
'executionMS' => $time,
- 'full_host' => $full_host,
+ 'connection' => $connection,
);
- $elasticaLogger->logQuery($path, $method, $data, $time, $full_host);
+ $elasticaLogger->logQuery($path, $method, $data, $time, $connection);
$returnedQueries = $elasticaLogger->getQueries();
$this->assertEquals($expected, $returnedQueries[0]);
}
From 70e6cb2e7ea3459ab2f8040f87d1a41e17fa13b3 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Tue, 10 Dec 2013 21:25:38 +1100
Subject: [PATCH 111/447] Fix issue with logger not having logQuery method
---
Client.php | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Client.php b/Client.php
index 119f420..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,7 +16,7 @@ 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;
$connection = $this->getLastRequest()->getConnection();
From e16ece821d662429ceaf3cf7724874bbfe54335a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cs=C3=A1sz=C3=A1r=20D=C3=A1niel?=
Date: Tue, 10 Dec 2013 13:54:50 +0100
Subject: [PATCH 112/447] Fix client configuration missing logger
---
DependencyInjection/Configuration.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index a9c9898..8d913f0 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -78,7 +78,7 @@ class Configuration implements ConfigurationInterface
array(
'host' => $v['host'],
'port' => $v['port'],
- 'logger' => $v['logger']
+ 'logger' => isset($v['logger']) ? $v['logger'] : null
)
)
);
@@ -91,7 +91,7 @@ class Configuration implements ConfigurationInterface
'servers' => array(
array(
'url' => $v['url'],
- 'logger' => $v['logger']
+ 'logger' => isset($v['logger']) ? $v['logger'] : null
)
)
);
From eaf52fa9072c5905b035e69d9c2585218b53838e Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Tue, 10 Dec 2013 08:42:56 +0100
Subject: [PATCH 113/447] Allow a more dynamic mapping for dynamic templates
---
DependencyInjection/Configuration.php | 61 ++++++++++++++++++++++-----
1 file changed, 51 insertions(+), 10 deletions(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 8d913f0..70718ef 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -341,16 +341,7 @@ class Configuration implements ConfigurationInterface
->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()
+ ->append($this->getDynamicTemplateMapping())
->end()
->end()
;
@@ -358,6 +349,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
@@ -451,6 +457,41 @@ class Configuration implements ConfigurationInterface
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
From bad1769c844207f9d64247eb30811f1fcdca1eaf Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Tue, 10 Dec 2013 08:49:20 +0100
Subject: [PATCH 114/447] Fixing tests
---
Tests/DependencyInjection/ConfigurationTest.php | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/Tests/DependencyInjection/ConfigurationTest.php b/Tests/DependencyInjection/ConfigurationTest.php
index ead9977..84285fb 100644
--- a/Tests/DependencyInjection/ConfigurationTest.php
+++ b/Tests/DependencyInjection/ConfigurationTest.php
@@ -63,13 +63,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']);
}
}
From 09031457cd5159044127e4f5c2a404062ab5912d Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Tue, 10 Dec 2013 09:02:17 +0100
Subject: [PATCH 115/447] Allow more matching methods
---
DependencyInjection/Configuration.php | 6 +++++-
Tests/DependencyInjection/ConfigurationTest.php | 16 ++++++++++++++++
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 70718ef..e9088e8 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -339,8 +339,12 @@ class Configuration implements ConfigurationInterface
->useAttributeAsKey('name')
->prototype('array')
->children()
- ->scalarNode('match')->isRequired()->end()
+ ->scalarNode('match')->end()
+ ->scalarNode('unmatch')->end()
->scalarNode('match_mapping_type')->end()
+ ->scalarNode('path_match')->end()
+ ->scalarNode('path_unmatch')->end()
+ ->scalarNode('match_pattern')->end()
->append($this->getDynamicTemplateMapping())
->end()
->end()
diff --git a/Tests/DependencyInjection/ConfigurationTest.php b/Tests/DependencyInjection/ConfigurationTest.php
index 84285fb..53d060d 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['v']);
+ $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']);
}
From e55c7e8632556bce7d58fbf9cfa3f0936a32b1d2 Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Tue, 10 Dec 2013 09:03:27 +0100
Subject: [PATCH 116/447] Set match to '*' by default
---
DependencyInjection/Configuration.php | 2 +-
Tests/DependencyInjection/ConfigurationTest.php | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index e9088e8..c790f66 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -339,7 +339,7 @@ class Configuration implements ConfigurationInterface
->useAttributeAsKey('name')
->prototype('array')
->children()
- ->scalarNode('match')->end()
+ ->scalarNode('match')->defaultValue('*')->end()
->scalarNode('unmatch')->end()
->scalarNode('match_mapping_type')->end()
->scalarNode('path_match')->end()
diff --git a/Tests/DependencyInjection/ConfigurationTest.php b/Tests/DependencyInjection/ConfigurationTest.php
index 53d060d..f3ff4a6 100644
--- a/Tests/DependencyInjection/ConfigurationTest.php
+++ b/Tests/DependencyInjection/ConfigurationTest.php
@@ -42,7 +42,7 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
$this->assertArrayHasKey('match', $dynamicTemplates);
$this->assertInstanceOf('Symfony\Component\Config\Definition\ScalarNode', $dynamicTemplates['match']);
- $this->assertNull($dynamicTemplates['match']->getDefaultValue());
+ $this->assertSame('*', $dynamicTemplates['match']->getDefaultValue());
$this->assertArrayHasKey('match_mapping_type', $dynamicTemplates);
$this->assertInstanceOf('Symfony\Component\Config\Definition\ScalarNode', $dynamicTemplates['match_mapping_type']);
From 0aa98d2295d536a4b4f0373e1efee33e0f1ca201 Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Tue, 10 Dec 2013 12:58:34 +0100
Subject: [PATCH 117/447] Fixing copy&paste error
---
Tests/DependencyInjection/ConfigurationTest.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Tests/DependencyInjection/ConfigurationTest.php b/Tests/DependencyInjection/ConfigurationTest.php
index f3ff4a6..4ea5657 100644
--- a/Tests/DependencyInjection/ConfigurationTest.php
+++ b/Tests/DependencyInjection/ConfigurationTest.php
@@ -57,7 +57,7 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
$this->assertNull($dynamicTemplates['path_match']->getDefaultValue());
$this->assertArrayHasKey('path_unmatch', $dynamicTemplates);
- $this->assertInstanceOf('Symfony\Component\Config\Definition\ScalarNode', $dynamicTemplates['v']);
+ $this->assertInstanceOf('Symfony\Component\Config\Definition\ScalarNode', $dynamicTemplates['path_unmatch']);
$this->assertNull($dynamicTemplates['path_unmatch']->getDefaultValue());
$this->assertArrayHasKey('match_pattern', $dynamicTemplates);
From a59385af7b08439c02271904ea3b96c6000f36fd Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Tue, 10 Dec 2013 15:37:41 +0100
Subject: [PATCH 118/447] Do not set default value to *, might conflict when
using e.g. path_match and match_pattern regex together
---
DependencyInjection/Configuration.php | 2 +-
Tests/DependencyInjection/ConfigurationTest.php | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index c790f66..e9088e8 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -339,7 +339,7 @@ class Configuration implements ConfigurationInterface
->useAttributeAsKey('name')
->prototype('array')
->children()
- ->scalarNode('match')->defaultValue('*')->end()
+ ->scalarNode('match')->end()
->scalarNode('unmatch')->end()
->scalarNode('match_mapping_type')->end()
->scalarNode('path_match')->end()
diff --git a/Tests/DependencyInjection/ConfigurationTest.php b/Tests/DependencyInjection/ConfigurationTest.php
index 4ea5657..35b2af3 100644
--- a/Tests/DependencyInjection/ConfigurationTest.php
+++ b/Tests/DependencyInjection/ConfigurationTest.php
@@ -42,7 +42,7 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
$this->assertArrayHasKey('match', $dynamicTemplates);
$this->assertInstanceOf('Symfony\Component\Config\Definition\ScalarNode', $dynamicTemplates['match']);
- $this->assertSame('*', $dynamicTemplates['match']->getDefaultValue());
+ $this->assertNull($dynamicTemplates['match']->getDefaultValue());
$this->assertArrayHasKey('match_mapping_type', $dynamicTemplates);
$this->assertInstanceOf('Symfony\Component\Config\Definition\ScalarNode', $dynamicTemplates['match_mapping_type']);
From 090f02b05d827b0f242d70434f17b46138564f6b Mon Sep 17 00:00:00 2001
From: Craig Marvelley
Date: Wed, 11 Dec 2013 22:52:25 +0000
Subject: [PATCH 119/447] Improve test coverage
---
Logger/ElasticaLogger.php | 2 +-
Tests/ClientTest.php | 42 ++++++++++++++
Tests/FOSElasticaBundleTest.php | 39 +++++++++++++
Tests/HybridResultTest.php | 19 ++++++
Tests/Logger/ElasticaLoggerTest.php | 90 +++++++++++++++++++++++++++--
Tests/RepositoryTest.php | 16 +++++
6 files changed, 203 insertions(+), 5 deletions(-)
create mode 100644 Tests/ClientTest.php
create mode 100644 Tests/FOSElasticaBundleTest.php
create mode 100644 Tests/HybridResultTest.php
diff --git a/Logger/ElasticaLogger.php b/Logger/ElasticaLogger.php
index bf7694e..7aacac5 100644
--- a/Logger/ElasticaLogger.php
+++ b/Logger/ElasticaLogger.php
@@ -147,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/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/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 05624cc..30ce30c 100644
--- a/Tests/Logger/ElasticaLoggerTest.php
+++ b/Tests/Logger/ElasticaLoggerTest.php
@@ -9,6 +9,40 @@ 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()
{
$elasticaLogger = new ElasticaLogger;
@@ -64,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 +118,55 @@ 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/RepositoryTest.php b/Tests/RepositoryTest.php
index 6eabe7b..c4d4efc 100644
--- a/Tests/RepositoryTest.php
+++ b/Tests/RepositoryTest.php
@@ -58,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';
From 11a87c5ce3fbe1b7a4e240b494d2be12f4973000 Mon Sep 17 00:00:00 2001
From: Craig Marvelley
Date: Thu, 12 Dec 2013 20:48:15 +0000
Subject: [PATCH 120/447] Add test for
ElasticaToModelTransformerCollection::hybridTransform
---
...asticaToModelTransformerCollectionTest.php | 52 +++++++++++++++++++
1 file changed, 52 insertions(+)
diff --git a/Tests/Transformer/ElasticaToModelTransformerCollectionTest.php b/Tests/Transformer/ElasticaToModelTransformerCollectionTest.php
index d33708e..bb5f6a3 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()
+ {
+ $document = new Result(array('_id' => 123, '_type' => 'type1'));
+ $result = new POPO(123, array());
+
+ return array(
+ array(
+ $document, $result
+ )
+ );
+ }
+
+ /**
+ * @dataProvider elasticaResults
+ */
+ public function testHybridTransformDecoratesResultsWithHybridResultObjects($document, $result)
+ {
+ $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($result)));
+
+ $collection = new ElasticaToModelTransformerCollection(array('type1' => $transformer));
+
+ $hybridResults = $collection->hybridTransform(array($document));
+
+ $this->assertInternalType('array', $hybridResults);
+ $this->assertNotEmpty($hybridResults);
+ $this->assertContainsOnlyInstancesOf('FOS\ElasticaBundle\HybridResult', $hybridResults);
+
+ $hybridResult = array_pop($hybridResults);
+ $this->assertEquals($document, $hybridResult->getResult());
+ $this->assertEquals($result, $hybridResult->getTransformed());
+ }
}
class POPO
From 5d16ffb1bf31c01d0748e2f6b6950af3989d2b2c Mon Sep 17 00:00:00 2001
From: Craig Marvelley
Date: Thu, 12 Dec 2013 20:50:15 +0000
Subject: [PATCH 121/447] Remove unused method
---
Transformer/ElasticaToModelTransformerCollection.php | 7 -------
1 file changed, 7 deletions(-)
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);
- }
}
From e0ef8dff23dd7d100905bb8a8a28ee07ef89a660 Mon Sep 17 00:00:00 2001
From: Burkhard Reffeling
Date: Thu, 12 Dec 2013 22:41:20 +0000
Subject: [PATCH 122/447] removed duplicate methods
---
Persister/ObjectSerializerPersister.php | 63 -------------------------
1 file changed, 63 deletions(-)
diff --git a/Persister/ObjectSerializerPersister.php b/Persister/ObjectSerializerPersister.php
index 8938a2f..1a15656 100644
--- a/Persister/ObjectSerializerPersister.php
+++ b/Persister/ObjectSerializerPersister.php
@@ -23,69 +23,6 @@ class ObjectSerializerPersister extends ObjectPersister
$this->serializer = $serializer;
}
- /**
- * Insert one object into the type
- * The object will be transformed to an elastica document
- *
- * @param object $object
- */
- public function insertOne($object)
- {
- $document = $this->transformToElasticaDocument($object);
- $this->type->addDocument($document);
- }
-
- /**
- * Replaces one object in the type
- *
- * @param object $object
- * @return null
- */
- public function replaceOne($object)
- {
- $document = $this->transformToElasticaDocument($object);
- $this->type->deleteById($document->getId());
- $this->type->addDocument($document);
- }
-
- /**
- * Deletes one object in the type
- *
- * @param object $object
- * @return null
- **/
- public function deleteOne($object)
- {
- $document = $this->transformToElasticaDocument($object);
- $this->type->deleteById($document->getId());
- }
-
- /**
- * Deletes one object in the type by id
- *
- * @param mixed $id
- *
- * @return null
- **/
- public function deleteById($id)
- {
- $this->type->deleteById($id);
- }
-
- /**
- * Inserts an array of objects in the type
- *
- * @param array $objects array of domain model objects
- **/
- public function insertMany(array $objects)
- {
- $docs = array();
- foreach ($objects as $object) {
- $docs[] = $this->transformToElasticaDocument($object);
- }
- $this->type->addDocuments($docs);
- }
-
/**
* Transforms an object to an elastica document
* with just the identifier set
From 292af9f039e2c52b4d02fb9c0f2f916b068f67f9 Mon Sep 17 00:00:00 2001
From: Craig Marvelley
Date: Thu, 12 Dec 2013 22:55:37 +0000
Subject: [PATCH 123/447] Better variable names
---
.../ElasticaToModelTransformerCollectionTest.php | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/Tests/Transformer/ElasticaToModelTransformerCollectionTest.php b/Tests/Transformer/ElasticaToModelTransformerCollectionTest.php
index bb5f6a3..eb4d8e4 100644
--- a/Tests/Transformer/ElasticaToModelTransformerCollectionTest.php
+++ b/Tests/Transformer/ElasticaToModelTransformerCollectionTest.php
@@ -115,12 +115,12 @@ class ElasticaToModelTransformerCollectionTest extends \PHPUnit_Framework_TestCa
public function elasticaResults()
{
- $document = new Result(array('_id' => 123, '_type' => 'type1'));
- $result = new POPO(123, array());
+ $result = new Result(array('_id' => 123, '_type' => 'type1'));
+ $transformedObject = new POPO(123, array());
return array(
array(
- $document, $result
+ $result, $transformedObject
)
);
}
@@ -128,7 +128,7 @@ class ElasticaToModelTransformerCollectionTest extends \PHPUnit_Framework_TestCa
/**
* @dataProvider elasticaResults
*/
- public function testHybridTransformDecoratesResultsWithHybridResultObjects($document, $result)
+ public function testHybridTransformDecoratesResultsWithHybridResultObjects($result, $transformedObject)
{
$transformer = $this->getMock('FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerInterface');
$transformer->expects($this->any())->method('getIdentifierField')->will($this->returnValue('id'));
@@ -136,19 +136,19 @@ class ElasticaToModelTransformerCollectionTest extends \PHPUnit_Framework_TestCa
$transformer
->expects($this->any())
->method('transform')
- ->will($this->returnValue(array($result)));
+ ->will($this->returnValue(array($transformedObject)));
$collection = new ElasticaToModelTransformerCollection(array('type1' => $transformer));
- $hybridResults = $collection->hybridTransform(array($document));
+ $hybridResults = $collection->hybridTransform(array($result));
$this->assertInternalType('array', $hybridResults);
$this->assertNotEmpty($hybridResults);
$this->assertContainsOnlyInstancesOf('FOS\ElasticaBundle\HybridResult', $hybridResults);
$hybridResult = array_pop($hybridResults);
- $this->assertEquals($document, $hybridResult->getResult());
- $this->assertEquals($result, $hybridResult->getTransformed());
+ $this->assertEquals($result, $hybridResult->getResult());
+ $this->assertEquals($transformedObject, $hybridResult->getTransformed());
}
}
From 3bd9155f467b6d46896d88d29050ddc593c53324 Mon Sep 17 00:00:00 2001
From: nurikabe
Date: Fri, 13 Dec 2013 17:51:15 +0000
Subject: [PATCH 124/447] Use constants of corresponding events classes rather
than making assumption about string values.
---
DependencyInjection/FOSElasticaExtension.php | 23 ++++++++++++++++----
Doctrine/Listener.php | 2 +-
2 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 6380873..733a039 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -403,17 +403,32 @@ class FOSElasticaExtension extends Extension
return $listenerId;
}
+ /**
+ * Map Elastica to Doctrine events for the current driver
+ */
private function getDoctrineEvents(array $typeConfig)
{
// Flush always calls depending on actions scheduled in lifecycle listeners
$typeConfig['listener']['flush'] = true;
+ switch ($typeConfig['driver']) {
+ case 'orm':
+ $eventsClass = '\Doctrine\ORM\Events';
+ break;
+ case 'mongodb':
+ $eventsClass = '\Doctrine\ODM\MongoDB\Events';
+ break;
+ default:
+ throw new InvalidArgumentException(sprintf('Cannot determine events for driver "%s"', $typeConfig['driver']));
+ break;
+ }
+
$events = array();
$eventMapping = array(
- 'insert' => array('postPersist'),
- 'update' => array('postUpdate'),
- 'delete' => array('preRemove'),
- 'flush' => array($typeConfig['listener']['immediate'] ? 'preFlush' : 'postFlush')
+ 'insert' => array(constant($eventsClass.'::postPersist')),
+ 'update' => array(constant($eventsClass.'::postUpdate')),
+ 'delete' => array(constant($eventsClass.'::preRemove')),
+ 'flush' => array($typeConfig['listener']['immediate'] ? constant($eventsClass.'::preFlush') : constant($eventsClass.'::postFlush'))
);
foreach ($eventMapping as $event => $doctrineEvents) {
diff --git a/Doctrine/Listener.php b/Doctrine/Listener.php
index 683070e..383e02f 100644
--- a/Doctrine/Listener.php
+++ b/Doctrine/Listener.php
@@ -27,7 +27,7 @@ class Listener implements EventSubscriber
protected $objectClass;
/**
- * List of su]bscribed events
+ * List of subscribed events
*
* @var array
*/
From e2e21b1e0ceb9745404f459b8a1b9a393233b100 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Sun, 15 Dec 2013 18:33:31 +1100
Subject: [PATCH 125/447] Allow bundle to be used without clients or indexes
defined.
---
DependencyInjection/FOSElasticaExtension.php | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 8b85629..cb2f706 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -24,12 +24,14 @@ class FOSElasticaExtension extends Extension
$config = $this->processConfiguration($configuration, $configs);
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
- $loader->load('config.xml');
if (empty($config['clients']) || empty($config['indexes'])) {
- throw new InvalidArgumentException('You must define at least one client and one index');
+ // No Clients or indexes are defined
+ return;
}
+ $loader->load('config.xml');
+
if (empty($config['default_client'])) {
$keys = array_keys($config['clients']);
$config['default_client'] = reset($keys);
From 90022b0d0a540e8bf5fc44cde6c8b996c072aefd Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Sun, 15 Dec 2013 18:33:45 +1100
Subject: [PATCH 126/447] Move type configuration into independent method
---
DependencyInjection/Configuration.php | 228 +++++++++++---------------
1 file changed, 95 insertions(+), 133 deletions(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index e9088e8..11c1cf4 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -138,68 +138,9 @@ class Configuration implements ConfigurationInterface
->scalarNode('client')->end()
->scalarNode('finder')
->treatNullLike(true)
- ->defaultFalse()
- ->end()
- ->arrayNode('type_prototype')
- ->children()
- ->scalarNode('index_analyzer')->end()
- ->scalarNode('search_analyzer')->end()
- ->arrayNode('persistence')
- ->validate()
- ->ifTrue(function($v) { return isset($v['driver']) && 'propel' === $v['driver'] && isset($v['listener']); })
- ->thenInvalid('Propel doesn\'t support listeners')
- ->ifTrue(function($v) { return isset($v['driver']) && 'propel' === $v['driver'] && isset($v['repository']); })
- ->thenInvalid('Propel doesn\'t support the "repository" parameter')
- ->end()
- ->children()
- ->scalarNode('driver')
- ->validate()
- ->ifNotInArray($this->supportedDrivers)
- ->thenInvalid('The driver %s is not supported. Please choose one of '.json_encode($this->supportedDrivers))
- ->end()
- ->end()
- ->scalarNode('identifier')->defaultValue('id')->end()
- ->arrayNode('provider')
- ->children()
- ->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
- ->scalarNode('batch_size')->defaultValue(100)->end()
- ->scalarNode('clear_object_manager')->defaultTrue()->end()
- ->scalarNode('service')->end()
- ->end()
- ->end()
- ->arrayNode('listener')
- ->children()
- ->scalarNode('insert')->defaultTrue()->end()
- ->scalarNode('update')->defaultTrue()->end()
- ->scalarNode('delete')->defaultTrue()->end()
- ->scalarNode('service')->end()
- ->variableNode('is_indexable_callback')->defaultNull()->end()
- ->end()
- ->end()
- ->arrayNode('finder')
- ->children()
- ->scalarNode('service')->end()
- ->end()
- ->end()
- ->arrayNode('elastica_to_model_transformer')
- ->addDefaultsIfNotSet()
- ->children()
- ->scalarNode('hydrate')->defaultTrue()->end()
- ->scalarNode('ignore_missing')->defaultFalse()->end()
- ->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
- ->scalarNode('service')->end()
- ->end()
- ->end()
- ->arrayNode('model_to_elastica_transformer')
- ->addDefaultsIfNotSet()
- ->children()
- ->scalarNode('service')->end()
- ->end()
- ->end()
- ->end()
- ->end()
- ->end()
+ ->defaultTrue()
->end()
+ ->append($this->getTypePrototypeNode())
->variableNode('settings')->defaultValue(array())->end()
->end()
->append($this->getTypesNode())
@@ -209,6 +150,19 @@ class Configuration implements ConfigurationInterface
;
}
+ /**
+ * Builds a type prototype node for the index configuration.
+ */
+ protected function getTypePrototypeNode()
+ {
+ $builder = new TreeBuilder();
+ $node = $builder->root('type_prototype');
+
+ $this->applyTypeConfiguration($node);
+
+ return $node;
+ }
+
/**
* Returns the array node used for "types".
*/
@@ -217,92 +171,100 @@ class Configuration implements ConfigurationInterface
$builder = new TreeBuilder();
$node = $builder->root('types');
- $node
+ $childrenNode = $node
->useAttributeAsKey('name')
->prototype('array')
- ->treatNullLike(array())
- ->children()
- ->arrayNode('serializer')
- ->addDefaultsIfNotSet()
- ->children()
- ->arrayNode('groups')
- ->treatNullLike(array())
- ->prototype('scalar')->end()
- ->end()
- ->scalarNode('version')->end()
+ ->treatNullLike(array());
+
+ $this->applyTypeConfiguration($childrenNode);
+
+ return $node;
+ }
+
+ /**
+ * Applies all type configuration fields to a node.
+ */
+ protected function applyTypeConfiguration($node)
+ {
+ $node
+ ->children()
+ ->arrayNode('serializer')
+ ->addDefaultsIfNotSet()
+ ->children()
+ ->arrayNode('groups')
+ ->treatNullLike(array())
+ ->prototype('scalar')->end()
->end()
+ ->scalarNode('version')->end()
->end()
- ->scalarNode('index_analyzer')->end()
- ->scalarNode('search_analyzer')->end()
- ->arrayNode('persistence')
- ->validate()
- ->ifTrue(function($v) { return isset($v['driver']) && 'propel' === $v['driver'] && isset($v['listener']); })
- ->thenInvalid('Propel doesn\'t support listeners')
- ->ifTrue(function($v) { return isset($v['driver']) && 'propel' === $v['driver'] && isset($v['repository']); })
- ->thenInvalid('Propel doesn\'t support the "repository" parameter')
+ ->end()
+ ->scalarNode('index_analyzer')->end()
+ ->scalarNode('search_analyzer')->end()
+ ->arrayNode('persistence')
+ ->validate()
+ ->ifTrue(function($v) { return isset($v['driver']) && 'propel' === $v['driver'] && isset($v['listener']); })
+ ->thenInvalid('Propel doesn\'t support listeners')
+ ->ifTrue(function($v) { return isset($v['driver']) && 'propel' === $v['driver'] && isset($v['repository']); })
+ ->thenInvalid('Propel doesn\'t support the "repository" parameter')
+ ->end()
+ ->children()
+ ->scalarNode('driver')
+ ->validate()
+ ->ifNotInArray($this->supportedDrivers)
+ ->thenInvalid('The driver %s is not supported. Please choose one of '.json_encode($this->supportedDrivers))
+ ->end()
->end()
- ->children()
- ->scalarNode('driver')
- ->validate()
- ->ifNotInArray($this->supportedDrivers)
- ->thenInvalid('The driver %s is not supported. Please choose one of '.json_encode($this->supportedDrivers))
- ->end()
+ ->scalarNode('model')->end()
+ ->scalarNode('repository')->end()
+ ->scalarNode('identifier')->defaultValue('id')->end()
+ ->arrayNode('provider')
+ ->children()
+ ->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
+ ->scalarNode('batch_size')->defaultValue(100)->end()
+ ->scalarNode('clear_object_manager')->defaultTrue()->end()
+ ->scalarNode('service')->end()
->end()
- ->scalarNode('model')->end()
- ->scalarNode('repository')->end()
- ->scalarNode('identifier')->defaultValue('id')->end()
- ->arrayNode('provider')
- ->children()
- ->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
- ->scalarNode('batch_size')->defaultValue(100)->end()
- ->scalarNode('clear_object_manager')->defaultTrue()->end()
- ->scalarNode('service')->end()
- ->end()
+ ->end()
+ ->arrayNode('listener')
+ ->children()
+ ->scalarNode('insert')->defaultTrue()->end()
+ ->scalarNode('update')->defaultTrue()->end()
+ ->scalarNode('delete')->defaultTrue()->end()
+ ->scalarNode('service')->end()
+ ->variableNode('is_indexable_callback')->defaultNull()->end()
->end()
- ->arrayNode('listener')
- ->children()
- ->scalarNode('insert')->defaultTrue()->end()
- ->scalarNode('update')->defaultTrue()->end()
- ->scalarNode('delete')->defaultTrue()->end()
- ->scalarNode('service')->end()
- ->variableNode('is_indexable_callback')->defaultNull()->end()
- ->end()
+ ->end()
+ ->arrayNode('finder')
+ ->children()
+ ->scalarNode('service')->end()
->end()
- ->arrayNode('finder')
- ->children()
- ->scalarNode('service')->end()
- ->end()
+ ->end()
+ ->arrayNode('elastica_to_model_transformer')
+ ->addDefaultsIfNotSet()
+ ->children()
+ ->scalarNode('hydrate')->defaultTrue()->end()
+ ->scalarNode('ignore_missing')->defaultFalse()->end()
+ ->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
+ ->scalarNode('service')->end()
->end()
- ->arrayNode('elastica_to_model_transformer')
- ->addDefaultsIfNotSet()
- ->children()
- ->scalarNode('hydrate')->defaultTrue()->end()
- ->scalarNode('ignore_missing')->defaultFalse()->end()
- ->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
- ->scalarNode('service')->end()
- ->end()
- ->end()
- ->arrayNode('model_to_elastica_transformer')
- ->addDefaultsIfNotSet()
- ->children()
- ->scalarNode('service')->end()
- ->end()
+ ->end()
+ ->arrayNode('model_to_elastica_transformer')
+ ->addDefaultsIfNotSet()
+ ->children()
+ ->scalarNode('service')->end()
->end()
->end()
->end()
->end()
- ->append($this->getIdNode())
- ->append($this->getMappingsNode())
- ->append($this->getDynamicTemplateNode())
- ->append($this->getSourceNode())
- ->append($this->getBoostNode())
- ->append($this->getRoutingNode())
- ->append($this->getParentNode())
- ->append($this->getAllNode())
->end()
- ;
-
- return $node;
+ ->append($this->getIdNode())
+ ->append($this->getMappingsNode())
+ ->append($this->getDynamicTemplateNode())
+ ->append($this->getSourceNode())
+ ->append($this->getBoostNode())
+ ->append($this->getRoutingNode())
+ ->append($this->getParentNode())
+ ->append($this->getAllNode());
}
/**
From 05ee300ddb2c1d13ec44c8f65b79808e06fbfe2a Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Mon, 16 Dec 2013 11:58:58 +0100
Subject: [PATCH 127/447] Fixing reset command to allow resetting of just one
type, starting to write test
---
Command/ResetCommand.php | 2 +-
Tests/Command/ResetCommandTest.php | 53 ++++++++++++++++++++++++++++++
2 files changed, 54 insertions(+), 1 deletion(-)
create mode 100644 Tests/Command/ResetCommandTest.php
diff --git a/Command/ResetCommand.php b/Command/ResetCommand.php
index 280f9aa..06cfe48 100755
--- a/Command/ResetCommand.php
+++ b/Command/ResetCommand.php
@@ -60,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/Tests/Command/ResetCommandTest.php b/Tests/Command/ResetCommandTest.php
new file mode 100644
index 0000000..44d493e
--- /dev/null
+++ b/Tests/Command/ResetCommandTest.php
@@ -0,0 +1,53 @@
+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();
+
+ $this->command = new ResetCommand();
+ $this->command->setContainer($container);
+ }
+
+ public function testResetAllIndexes()
+ {
+ $this->indexManager->expects($this->any())
+ ->method('getAllIndexes')
+ ->will($this->returnValue(array('index1', 'index2')));
+
+ $this->resetter->expects($this->at(1))
+ ->method('resetIndex')
+ ->with($this->equalTo('index1'));
+
+ $this->resetter->expects($this->at(2))
+ ->method('resetIndex')
+ ->with($this->equalTo('index2'));
+
+ $this->command->run(
+ new ArrayInput(array()),
+ new NullOutput()
+ );
+ }
+}
\ No newline at end of file
From e906d780ad019d4196b4e0817337f5a5a31eba17 Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Mon, 16 Dec 2013 12:06:53 +0100
Subject: [PATCH 128/447] Adding tests
---
Tests/Command/ResetCommandTest.php | 44 ++++++++++++++++++++++++++++--
1 file changed, 41 insertions(+), 3 deletions(-)
diff --git a/Tests/Command/ResetCommandTest.php b/Tests/Command/ResetCommandTest.php
index 44d493e..b6548aa 100644
--- a/Tests/Command/ResetCommandTest.php
+++ b/Tests/Command/ResetCommandTest.php
@@ -4,6 +4,9 @@ namespace FOS\ElasticaBundle\Tests\Command;
use FOS\ElasticaBundle\Command\ResetCommand;
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Output\NullOutput;
+use Symfony\Component\DependencyInjection\Container;
class ResetCommandTest extends \PHPUnit_Framework_TestCase
{
@@ -27,6 +30,8 @@ class ResetCommandTest extends \PHPUnit_Framework_TestCase
->setMethods(array('getAllIndexes'))
->getMock();
+ $container->set('fos_elastica.index_manager', $this->indexManager);
+
$this->command = new ResetCommand();
$this->command->setContainer($container);
}
@@ -35,13 +40,13 @@ class ResetCommandTest extends \PHPUnit_Framework_TestCase
{
$this->indexManager->expects($this->any())
->method('getAllIndexes')
- ->will($this->returnValue(array('index1', 'index2')));
+ ->will($this->returnValue(array('index1' => true, 'index2' => true)));
- $this->resetter->expects($this->at(1))
+ $this->resetter->expects($this->at(0))
->method('resetIndex')
->with($this->equalTo('index1'));
- $this->resetter->expects($this->at(2))
+ $this->resetter->expects($this->at(1))
->method('resetIndex')
->with($this->equalTo('index2'));
@@ -50,4 +55,37 @@ class ResetCommandTest extends \PHPUnit_Framework_TestCase
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
From 5f8b8003d1f10173094c8dec58db8fb486432a66 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Tue, 17 Dec 2013 21:09:58 +1100
Subject: [PATCH 129/447] Refactor documentation
---
DependencyInjection/Configuration.php | 22 +-
README.md | 868 +-----------------
Resources/doc/cookbook/custom-repositories.md | 72 ++
Resources/doc/cookbook/manual-provider.md | 56 ++
.../doc/cookbook/suppress-server-errors.md | 36 +
Resources/doc/index.md | 14 +
Resources/doc/serializer.md | 39 +
Resources/doc/setup.md | 144 +++
Resources/doc/types.md | 264 ++++++
Resources/doc/usage.md | 177 ++++
10 files changed, 838 insertions(+), 854 deletions(-)
create mode 100644 Resources/doc/cookbook/custom-repositories.md
create mode 100644 Resources/doc/cookbook/manual-provider.md
create mode 100644 Resources/doc/cookbook/suppress-server-errors.md
create mode 100644 Resources/doc/index.md
create mode 100644 Resources/doc/serializer.md
create mode 100644 Resources/doc/setup.md
create mode 100644 Resources/doc/types.md
create mode 100644 Resources/doc/usage.md
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 11c1cf4..b05bd54 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -8,6 +8,11 @@ use Symfony\Component\Config\Definition\ConfigurationInterface;
class Configuration implements ConfigurationInterface
{
+ /**
+ * Stores supported database drivers.
+ *
+ * @var array
+ */
private $supportedDrivers = array('orm', 'mongodb', 'propel');
private $configArray = array();
@@ -32,8 +37,12 @@ class Configuration implements ConfigurationInterface
$rootNode
->children()
- ->scalarNode('default_client')->end()
- ->scalarNode('default_index')->end()
+ ->scalarNode('default_client')
+ ->info('Defaults to the first client defined')
+ ->end()
+ ->scalarNode('default_index')
+ ->info('Defaults to the first index defined')
+ ->end()
->scalarNode('default_manager')->defaultValue('orm')->end()
->arrayNode('serializer')
->treatNullLike(array())
@@ -105,6 +114,7 @@ class Configuration implements ConfigurationInterface
->scalarNode('host')->end()
->scalarNode('port')->end()
->scalarNode('logger')
+ ->info('Set your own logger service for this client or disable the logger with false.')
->defaultValue('fos_elastica.logger')
->treatNullLike('fos_elastica.logger')
->treatTrueLike('fos_elastica.logger')
@@ -134,11 +144,14 @@ class Configuration implements ConfigurationInterface
->prototype('array')
->performNoDeepMerging()
->children()
- ->scalarNode('index_name')->end()
+ ->scalarNode('index_name')
+ ->info('Defaults to the name of the index, but can be modified if the index name is different in ElasticSearch')
+ ->end()
->scalarNode('client')->end()
->scalarNode('finder')
+ ->info('Defines an index wide finder that will search all types.')
->treatNullLike(true)
- ->defaultTrue()
+ ->defaultFalse()
->end()
->append($this->getTypePrototypeNode())
->variableNode('settings')->defaultValue(array())->end()
@@ -157,6 +170,7 @@ class Configuration implements ConfigurationInterface
{
$builder = new TreeBuilder();
$node = $builder->root('type_prototype');
+ $node->info('Allows a prototype type definition that can be applied to all types.');
$this->applyTypeConfiguration($node);
diff --git a/README.md b/README.md
index 3006bd1..ce5afab 100644
--- a/README.md
+++ b/README.md
@@ -1,862 +1,30 @@
-[Elastica](https://github.com/ruflin/Elastica) integration in Symfony2
+FOSElasticaBundle
+=================
-### Installation
+This bundle provides integration with [ElasticSearch](http://www.elasticsearch.org) and [Elastica](https://github.com/ruflin/Elastica) with
+Symfony2. Features include:
-#### Bundle and Dependencies
+- Features...
-For Symfony 2.0.x projects, you must use a 1.x release of this bundle. Please
-check the bundle
-[tags](https://github.com/FriendsOfSymfony/FOSElasticaBundle/tags) or the
-[Packagist](https://packagist.org/packages/friendsofsymfony/elastica-bundle)
-page for information on Symfony and Elastica compatibility.
+[](http://travis-ci.org/FriendsOfSymfony/FOSElasticaBundle) [](https://packagist.org/packages/FriendsOfSymfony/elastica-bundle) [](https://packagist.org/packages/FriendsOfSymfony/elastica-bundle)
-Add FOSElasticaBundle to your application's `composer.json` file:
+Documentation
+-------------
-```json
-{
- "require": {
- "friendsofsymfony/elastica-bundle": "3.0.*@dev"
- }
-}
-```
+Documentation for FOSElasticaBundle is in `Resources/doc/index.md`
-Install the bundle and its dependencies with the following command:
+[Read the documentation for 3.0.x (master))](https://github.com/FriendsOfSymfony/FOSElasticaBundle/blob/master/Resources/doc/index.md)
-```bash
-$ php composer.phar update friendsofsymfony/elastica-bundle
-```
+[Read the documentation for 2.1.x](https://github.com/FriendsOfSymfony/FOSElasticaBundle/blob/2.1.x/README.md)
-You may rely on Composer to fetch the appropriate version of Elastica. Lastly,
-enable the bundle in your application kernel:
+Installation
+------------
-```php
-// app/AppKernel.php
+Installation instructions can be found in the [documentation](https://github.com/FriendsOfSymfony/FOSElasticaBundle/blob/master/Resources/doc/setup.md)
-public function registerBundles()
-{
- $bundles = array(
- // ...
- new FOS\ElasticaBundle\FOSElasticaBundle(),
- );
-}
-```
+License
+-------
-#### Elasticsearch
+This bundle is under the MIT license. See the complete license in the bundle:
-Instructions for installing and deploying Elasticsearch may be found
-[here](http://www.elasticsearch.org/guide/reference/setup/installation/).
-
-### Basic configuration
-
-#### Declare a client
-
-Elasticsearch client is comparable to a database connection.
-Most of the time, you will need only one.
-
- #app/config/config.yml
- fos_elastica:
- clients:
- default: { host: localhost, port: 9200 }
-
-
-#### Declare a serializer
-
-Elastica can handle objects instead of data arrays if a serializer callable is configured
-
- #app/config/config.yml
- fos_elastica:
- clients:
- default: { host: localhost, port: 9200 }
- serializer:
- callback_class: callback_class
- serializer: serializer
-
-``callback_class`` is the name of a class having a public method serialize($object) and should
-extends from ``FOS\ElasticaBundle\Serializer\Callback``.
-
-``serializer`` is the service id for the actual serializer, e.g. ``serializer`` if you're using
-JMSSerializerBundle. If this is configured you can use ``\Elastica\Type::addObject`` instead of
-``\Elastica\Type::addDocument`` to add data to the index. The bundle provides a default implementation
-with a serializer service id 'serializer' that can be turned on by adding the following line to your config.
-
- #app/config/config.yml
- fos_elastica:
- serializer: ~
-
-#### Declare an index
-
-Elasticsearch index is comparable to Doctrine entity manager.
-Most of the time, you will need only one.
-
- fos_elastica:
- clients:
- default: { host: localhost, port: 9200 }
- serializer:
- callback_class: FOS\ElasticaBundle\Serializer\Callback
- serializer: serializer
- indexes:
- website:
- client: default
-
-Here we created a "website" index, that uses our "default" client.
-
-Our index is now available as a service: `fos_elastica.index.website`. It is an instance of `\Elastica\Index`.
-
-If you need to have different index name from the service name, for example,
-in order to have different indexes for different environments then you can
-use the ```index_name``` key to change the index name. The service name will
-remain the same across the environments:
-
- fos_elastica:
- clients:
- default: { host: localhost, port: 9200 }
- indexes:
- website:
- client: default
- index_name: website_qa
-
-The service id will be `fos_elastica.index.website` but the underlying index name is website_qa.
-
-#### Declare a type
-
-Elasticsearch type is comparable to Doctrine entity repository.
-
- fos_elastica:
- clients:
- default: { host: localhost, port: 9200 }
- serializer:
- callback_class: FOS\ElasticaBundle\Serializer\Callback
- serializer: serializer
- indexes:
- website:
- client: default
- types:
- user:
- mappings:
- username: { boost: 5 }
- firstName: { boost: 3 }
- lastName: { boost: 3 }
- aboutMe: ~
-
-Our type is now available as a service: `fos_elastica.index.website.user`. It is an instance of `\Elastica\Type`.
-
-### Declaring serializer groups
-
-If you are using the JMSSerializerBundle for serializing objects passed to elastica you can define serializer groups
-per type.
-
- fos_elastica:
- clients:
- default: { host: localhost, port: 9200 }
- serializer:
- callback_class: %classname%
- serializer: serializer
- indexes:
- website:
- client: default
- types:
- user:
- mappings:
- username: { boost: 5 }
- firstName: { boost: 3 }
- lastName: { boost: 3 }
- aboutMe:
- serializer:
- groups: [elastica, Default]
-
-### Declaring parent field
-
- fos_elastica:
- clients:
- default: { host: localhost, port: 9200 }
- serializer:
- callback_class: FOS\ElasticaBundle\Serializer\Callback
- serializer: serializer
- indexes:
- website:
- client: default
- types:
- comment:
- mappings:
- date: { boost: 5 }
- content: ~
- _parent: { type: "post", property: "post", identifier: "id" }
-
-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 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 }
- serializer:
- callback_class: FOS\ElasticaBundle\Serializer\Callback
- serializer: serializer
- indexes:
- website:
- client: default
- types:
- post:
- mappings:
- date: { boost: 5 }
- title: { boost: 3 }
- content: ~
- comments:
- type: "nested"
- properties:
- date: { boost: 5 }
- content: ~
- user:
- type: "object"
- approver:
- type: "object"
- properties:
- date: { boost: 5 }
-
-#### Doctrine ORM and `object` mappings
-
-Objects operate in the same way as the nested results but they need to have associations set up in Doctrine ORM so that they can be referenced correctly when indexing.
-
-If an "Entity was not found" error occurs while indexing, a null association has been discovered in the database. A custom Doctrine query must be used to utilize left joins instead of the default inner join.
-
-### Populate the types
-
- php app/console fos:elastica:populate
-
-This command deletes and creates the declared indexes and types.
-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 a manual provider.
-
-#### Persistence automatic provider
-
-If we want to index the entities from a Doctrine repository or a Propel query,
-some configuration will let ElasticaBundle do it for us.
-
- fos_elastica:
- clients:
- default: { host: localhost, port: 9200 }
- serializer:
- callback_class: FOS\ElasticaBundle\Serializer\Callback
- serializer: serializer
- indexes:
- website:
- client: default
- types:
- user:
- mappings:
- username: { boost: 5 }
- firstName: { boost: 3 }
- # more mappings...
- persistence:
- driver: orm # orm, mongodb, propel are available
- model: Application\UserBundle\Entity\User
- provider: ~
-
-Three drivers are actually supported: orm, mongodb, and propel.
-
-##### Use a custom Doctrine query builder
-
-You can control which entities will be indexed by specifying a custom query builder method.
-
- persistence:
- driver: orm
- model: Application\UserBundle\Entity\User
- provider:
- query_builder_method: createIsActiveQueryBuilder
-
-Your repository must implement this method and return a Doctrine query builder.
-
-> **Propel** doesn't support this feature yet.
-
-##### Change the batch size
-
-By default, ElasticaBundle will index documents by packets of 100.
-You can change this value in the provider configuration.
-
- persistence:
- driver: orm
- model: Application\UserBundle\Entity\User
- provider:
- batch_size: 100
-
-##### Change the document identifier field
-
-By default, ElasticaBundle will use the `id` field of your entities as the elasticsearch document identifier.
-You can change this value in the persistence configuration.
-
- persistence:
- driver: orm
- model: Application\UserBundle\Entity\User
- identifier: id
-
-#### Manual provider
-
-Create a service with the tag "fos_elastica.provider" and attributes for the
-index and type for which the service will provide.
-
-
-
-
-
-
-Its class must implement `FOS\ElasticaBundle\Provider\ProviderInterface`.
-
- userType = $userType;
- }
-
- /**
- * Insert the repository objects in the type index
- *
- * @param \Closure $loggerClosure
- * @param array $options
- */
- public function populate(\Closure $loggerClosure = null, array $options = array())
- {
- if ($loggerClosure) {
- $loggerClosure('Indexing users');
- }
-
- $document = new Document();
- $document->setData(array('username' => 'Bob'));
- $this->userType->addDocuments(array($document));
- }
- }
-
-You will find a more complete implementation example in `src/FOS/ElasticaBundle/Doctrine/AbstractProvider.php`.
-
-### Search
-
-You can just use the index and type Elastica objects, provided as services, to perform searches.
-
- /** var Elastica\Type */
- $userType = $this->container->get('fos_elastica.index.website.user');
-
- /** var Elastica\ResultSet */
- $resultSet = $userType->search('bob');
-
-#### Doctrine/Propel finder
-
-If your elasticsearch type is bound to a Doctrine entity repository or a Propel query,
-you can get your entities instead of Elastica results when you perform a search.
-Declare that you want a Doctrine/Propel finder in your configuration:
-
- fos_elastica:
- clients:
- default: { host: localhost, port: 9200 }
- serializer:
- callback_class: FOS\ElasticaBundle\Serializer\Callback
- serializer: serializer
- indexes:
- website:
- client: default
- types:
- user:
- mappings:
- # your mappings
- persistence:
- driver: orm
- model: Application\UserBundle\Entity\User
- provider: ~
- finder: ~
-
-You can now use the `fos_elastica.finder.website.user` service:
-
- /** var FOS\ElasticaBundle\Finder\TransformedFinder */
- $finder = $container->get('fos_elastica.finder.website.user');
-
- /** var array of Acme\UserBundle\Entity\User */
- $users = $finder->find('bob');
-
- /** var array of Acme\UserBundle\Entity\User limited to 10 results */
- $users = $finder->find('bob', 10);
-
-You can even get paginated results!
-
-Pagerfanta:
-
- /** var Pagerfanta\Pagerfanta */
- $userPaginator = $finder->findPaginated('bob');
-
- /** Number of results to be used for paging the results */
- $countOfResults = $userPaginator->getNbResults();
-
-Knp paginator:
-
- $paginator = $this->get('knp_paginator');
- $userPaginator = $paginator->paginate($finder->createPaginatorAdapter('bob'));
-
-You can also get both the Elastica results and the entities together from the finder.
-You can then access the score, highlights etc. from the Elastica\Result whilst
-still also getting the entity.
-
- /** var array of FOS\ElasticaBundle\HybridResult */
- $hybridResults = $finder->findHybrid('bob');
- foreach ($hybridResults as $hybridResult) {
-
- /** var Acme\UserBundle\Entity\User */
- $user = $hybridResult->getTransformed();
-
- /** var Elastica\Result */
- $result = $hybridResult->getResult();
- }
-
-If you would like to access facets while using Pagerfanta they can be accessed through
-the Adapter seen in the example below.
-
-```php
-$query = new \Elastica\Query();
-$facet = new \Elastica\Facet\Terms('tags');
-$facet->setField('companyGroup');
-$query->addFacet($facet);
-
-$companies = $finder->findPaginated($query);
-$companies->setMaxPerPage($params['limit']);
-$companies->setCurrentPage($params['page']);
-
-$facets = $companies->getAdapter()->getFacets());
-```
-
-##### Index wide finder
-
-You can also define a finder that will work on the entire index. Adjust your index
-configuration as per below:
-
- fos_elastica:
- indexes:
- website:
- client: default
- finder: ~
-
-You can now use the index wide finder service `fos_elastica.finder.website`:
-
- /** var FOS\ElasticaBundle\Finder\MappedFinder */
- $finder = $container->get('fos_elastica.finder.website');
-
- // Returns a mixed array of any objects mapped
- $results = $finder->find('bob');
-
-#### Repositories
-
-As well as using the finder service for a particular Doctrine/Propel entity you
-can use a manager service for each driver and get a repository for an entity to search
-against. This allows you to use the same service rather than the particular finder. For
-example:
-
- /** var FOS\ElasticaBundle\Manager\RepositoryManager */
- $repositoryManager = $container->get('fos_elastica.manager.orm');
-
- /** var FOS\ElasticaBundle\Repository */
- $repository = $repositoryManager->getRepository('UserBundle:User');
-
- /** var array of Acme\UserBundle\Entity\User */
- $users = $repository->find('bob');
-
-You can also specify the full name of the entity instead of the shortcut syntax:
-
- /** var FOS\ElasticaBundle\Repository */
- $repository = $repositoryManager->getRepository('Application\UserBundle\Entity\User');
-
-> The **2.0** branch doesn't support using `UserBundle:User` style syntax and you must use the full name of the entity. .
-
-##### Default Manager
-
-If you are only using one driver then its manager service is automatically aliased
-to `fos_elastica.manager`. So the above example could be simplified to:
-
- /** var FOS\ElasticaBundle\Manager\RepositoryManager */
- $repositoryManager = $container->get('fos_elastica.manager');
-
- /** var FOS\ElasticaBundle\Repository */
- $repository = $repositoryManager->getRepository('UserBundle:User');
-
- /** var array of Acme\UserBundle\Entity\User */
- $users = $repository->find('bob');
-
-If you use multiple drivers then you can choose which one is aliased to `fos_elastica.manager`
-using the `default_manager` parameter:
-
- fos_elastica:
- default_manager: mongodb #defaults to orm
- clients:
- default: { host: localhost, port: 9200 }
- #--
-
-##### Custom Repositories
-
-As well as the default repository you can create a custom repository for an entity and add
-methods for particular searches. These need to extend `FOS\ElasticaBundle\Repository` to have
-access to the finder:
-
-```
-find($query);
- }
-}
-```
-
-To use the custom repository specify it in the mapping for the entity:
-
- fos_elastica:
- clients:
- default: { host: localhost, port: 9200 }
- indexes:
- website:
- client: default
- types:
- user:
- mappings:
- # your mappings
- persistence:
- driver: orm
- model: Application\UserBundle\Entity\User
- provider: ~
- finder: ~
- repository: Acme\ElasticaBundle\SearchRepository\UserRepository
-
-Then the custom queries will be available when using the repository returned from the manager:
-
- /** var FOS\ElasticaBundle\Manager\RepositoryManager */
- $repositoryManager = $container->get('fos_elastica.manager');
-
- /** var FOS\ElasticaBundle\Repository */
- $repository = $repositoryManager->getRepository('UserBundle:User');
-
- /** var array of Acme\UserBundle\Entity\User */
- $users = $repository->findWithCustomQuery('bob');
-
-Alternatively you can specify the custom repository using an annotation in the entity:
-
-```
- **Propel** doesn't support this feature yet.
-
-### Checking an entity method for listener
-
-If you use listeners to update your index, you may need to validate your
-entities before you index them (e.g. only index "public" entities). Typically,
-you'll want the listener to be consistent with the provider's query criteria.
-This may be achieved by using the `is_indexable_callback` config parameter:
-
- persistence:
- listener:
- is_indexable_callback: "isPublic"
-
-If `is_indexable_callback` is a string and the entity has a method with the
-specified name, the listener will only index entities for which the method
-returns `true`. Additionally, you may provide a service and method name pair:
-
- persistence:
- listener:
- is_indexable_callback: [ "%custom_service_id%", "isIndexable" ]
-
-In this case, the callback_class will be the `isIndexable()` method on the specified
-service and the object being considered for indexing will be passed as the only
-argument. This allows you to do more complex validation (e.g. ACL checks).
-
-If you have the [Symfony ExpressionLanguage](https://github.com/symfony/expression-language) component installed, you can use expressions
-to evaluate the callback:
-
- persistence:
- listener:
- is_indexable_callback: "user.isActive() && user.hasRole('ROLE_USER')"
-
-As you might expect, new entities will only be indexed if the callback_class returns
-`true`. Additionally, modified entities will be updated or removed from the
-index depending on whether the callback_class returns `true` or `false`, respectively.
-The delete listener disregards the callback_class.
-
-> **Propel** doesn't support this feature yet.
-
-### Ignoring missing index results
-
-By default, FOSElasticaBundle will throw an exception if the results returned from
-Elasticsearch are different from the results it finds from the chosen persistence
-provider. This may pose problems for a large index where updates do not occur instantly
-or another process has removed the results from your persistence provider without
-updating Elasticsearch.
-
-The error you're likely to see is something like:
-'Cannot find corresponding Doctrine objects for all Elastica results.'
-
-To solve this issue, each mapped object can be configured to ignore the missing results:
-
- persistence:
- elastica_to_model_transformer:
- ignore_missing: true
-
-### Advanced elasticsearch configuration
-
-Any setting can be specified when declaring a type. For example, to enable a custom analyzer, you could write:
-
- fos_elastica:
- indexes:
- doc:
- settings:
- index:
- analysis:
- analyzer:
- my_analyzer:
- type: custom
- tokenizer: lowercase
- filter : [my_ngram]
- filter:
- my_ngram:
- type: "nGram"
- min_gram: 3
- max_gram: 5
- types:
- blog:
- mappings:
- title: { boost: 8, analyzer: my_analyzer }
-
-### Overriding the Client class to suppress exceptions
-
-By default, exceptions from the Elastica client library will propagate through
-the bundle's Client class. For instance, if the elasticsearch server is offline,
-issuing a request will result in an `Elastica\Exception\Connection` being thrown.
-Depending on your needs, it may be desirable to suppress these exceptions and
-allow searches to fail silently.
-
-One way to achieve this is to override the `fos_elastica.client.class` service
-container parameter with a custom class. In the following example, we override
-the `Client::request()` method and return the equivalent of an empty search
-response if an exception occurred.
-
-```
-container->get('fos_elastica.finder.website.article');
-$boolQuery = new \Elastica\Query\Bool();
-
-$fieldQuery = new \Elastica\Query\Text();
-$fieldQuery->setFieldQuery('title', 'I am a title string');
-$fieldQuery->setFieldParam('title', 'analyzer', 'my_analyzer');
-$boolQuery->addShould($fieldQuery);
-
-$tagsQuery = new \Elastica\Query\Terms();
-$tagsQuery->setTerms('tags', array('tag1', 'tag2'));
-$boolQuery->addShould($tagsQuery);
-
-$categoryQuery = new \Elastica\Query\Terms();
-$categoryQuery->setTerms('categoryIds', array('1', '2', '3'));
-$boolQuery->addMust($categoryQuery);
-
-$data = $finder->find($boolQuery);
-```
-
-Configuration:
-
-```yaml
-fos_elastica:
- clients:
- default: { host: localhost, port: 9200 }
- indexes:
- site:
- settings:
- index:
- analysis:
- analyzer:
- my_analyzer:
- type: snowball
- language: English
- types:
- article:
- mappings:
- title: { boost: 10, analyzer: my_analyzer }
- tags:
- categoryIds:
- persistence:
- driver: orm
- model: Acme\DemoBundle\Entity\Article
- provider:
- finder:
-```
-
-### Filtering Results and Executing a Default Query
-
-If may want to omit certain results from a query, filtering can be more
-performant than a basic query because the filter results can be cached. In turn,
-the query is run against only a subset of the results. A common use case for
-filtering would be if your data has fields that indicate whether records are
-"active" or "inactive". The following example illustrates how to issue such a
-query with Elastica:
-
-```php
-$query = new \Elastica\Query\QueryString($queryString);
-$term = new \Elastica\Filter\Term(array('active' => true));
-
-$filteredQuery = new \Elastica\Query\Filtered($query, $term);
-$results = $this->container->get('fos_elastica.finder.index.type')->find($filteredQuery);
-```
-
-### Date format example
-
-If you want to specify a [date format](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-date-format.html):
-
-```yaml
-fos_elastica:
- clients:
- default: { host: localhost, port: 9200 }
- indexes:
- site:
- types:
- user:
- mappings:
- username: { type: string }
- 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 }
-```
+ Resources/meta/LICENSE
diff --git a/Resources/doc/cookbook/custom-repositories.md b/Resources/doc/cookbook/custom-repositories.md
new file mode 100644
index 0000000..47dc3fe
--- /dev/null
+++ b/Resources/doc/cookbook/custom-repositories.md
@@ -0,0 +1,72 @@
+##### Custom Repositories
+
+As well as the default repository you can create a custom repository for an entity and add
+methods for particular searches. These need to extend `FOS\ElasticaBundle\Repository` to have
+access to the finder:
+
+```
+find($query);
+ }
+}
+```
+
+To use the custom repository specify it in the mapping for the entity:
+
+ fos_elastica:
+ clients:
+ default: { host: localhost, port: 9200 }
+ indexes:
+ website:
+ client: default
+ types:
+ user:
+ mappings:
+ # your mappings
+ persistence:
+ driver: orm
+ model: Application\UserBundle\Entity\User
+ provider: ~
+ finder: ~
+ repository: Acme\ElasticaBundle\SearchRepository\UserRepository
+
+Then the custom queries will be available when using the repository returned from the manager:
+
+ /** var FOS\ElasticaBundle\Manager\RepositoryManager */
+ $repositoryManager = $container->get('fos_elastica.manager');
+
+ /** var FOS\ElasticaBundle\Repository */
+ $repository = $repositoryManager->getRepository('UserBundle:User');
+
+ /** var array of Acme\UserBundle\Entity\User */
+ $users = $repository->findWithCustomQuery('bob');
+
+Alternatively you can specify the custom repository using an annotation in the entity:
+
+```
+userType = $userType;
+ }
+
+ /**
+ * Insert the repository objects in the type index
+ *
+ * @param \Closure $loggerClosure
+ * @param array $options
+ */
+ public function populate(\Closure $loggerClosure = null, array $options = array())
+ {
+ if ($loggerClosure) {
+ $loggerClosure('Indexing users');
+ }
+
+ $document = new Document();
+ $document->setData(array('username' => 'Bob'));
+ $this->userType->addDocuments(array($document));
+ }
+}
+```
+
+You will find a more complete implementation example in `src/FOS/ElasticaBundle/Doctrine/AbstractProvider.php`.
diff --git a/Resources/doc/cookbook/suppress-server-errors.md b/Resources/doc/cookbook/suppress-server-errors.md
new file mode 100644
index 0000000..aa74276
--- /dev/null
+++ b/Resources/doc/cookbook/suppress-server-errors.md
@@ -0,0 +1,36 @@
+Suppressing Server Errors
+========================
+
+By default, exceptions from the Elastica client library will propagate through
+the bundle's Client class. For instance, if the Elasticsearch server is offline,
+issuing a request will result in an `Elastica\Exception\Connection` being thrown.
+Depending on your needs, it may be desirable to suppress these exceptions and
+allow searches to fail silently.
+
+One way to achieve this is to override the `fos_elastica.client.class` service
+container parameter with a custom class. In the following example, we override
+the `Client::request()` method and return the equivalent of an empty search
+response if an exception occurred.
+
+```
+ **Propel** doesn't support this feature yet.
+
+### Checking an entity method for listener
+
+If you use listeners to update your index, you may need to validate your
+entities before you index them (e.g. only index "public" entities). Typically,
+you'll want the listener to be consistent with the provider's query criteria.
+This may be achieved by using the `is_indexable_callback` config parameter:
+
+```yaml
+ persistence:
+ listener:
+ is_indexable_callback: "isPublic"
+```
+
+If `is_indexable_callback` is a string and the entity has a method with the
+specified name, the listener will only index entities for which the method
+returns `true`. Additionally, you may provide a service and method name pair:
+
+```yaml
+ persistence:
+ listener:
+ is_indexable_callback: [ "%custom_service_id%", "isIndexable" ]
+```
+
+In this case, the callback_class will be the `isIndexable()` method on the specified
+service and the object being considered for indexing will be passed as the only
+argument. This allows you to do more complex validation (e.g. ACL checks).
+
+If you have the [Symfony ExpressionLanguage](https://github.com/symfony/expression-language)
+component installed, you can use expressions to evaluate the callback:
+
+```yaml
+ persistence:
+ listener:
+ is_indexable_callback: "user.isActive() && user.hasRole('ROLE_USER')"
+```
+
+As you might expect, new entities will only be indexed if the callback_class returns
+`true`. Additionally, modified entities will be updated or removed from the
+index depending on whether the callback_class returns `true` or `false`, respectively.
+The delete listener disregards the callback_class.
+
+> **Propel** doesn't support this feature yet.
\ No newline at end of file
diff --git a/Resources/doc/usage.md b/Resources/doc/usage.md
new file mode 100644
index 0000000..4c962e0
--- /dev/null
+++ b/Resources/doc/usage.md
@@ -0,0 +1,177 @@
+FOSElasticaBundle Usage
+=======================
+
+Basic Searching with a Finder
+-----------------------------
+
+The most useful searching method is to use a finder defined by the type configuration.
+A finder will return results that have been hydrated by the configured persistence backend,
+allowing you to use relationships of returned entities. For more information about
+configuration options for this kind of searching, please see the [types](types.md)
+documentation.
+
+```php
+$finder = $this->container->get('fos_elastica.finder.search.user');
+
+// Option 1. Returns all users who have example.net in any of their mapped fields
+$results = $finder->find('example.net');
+
+// Option 2. Returns a set of hybrid results that contain all Elasticsearch results
+// and their transformed counterparts. Each result is an instance of a HybridResult
+$results = $finder->findHybrid('example.net');
+
+// Option 3a. Pagerfanta'd resultset
+/** var Pagerfanta\Pagerfanta */
+$userPaginator = $finder->findPaginated('bob');
+$countOfResults = $userPaginator->getNbResults();
+
+// Option 3b. KnpPaginator resultset
+
+```
+
+Faceted Searching
+-----------------
+
+When searching with facets, the facets can be retrieved when using the paginated
+methods on the finder.
+
+```php
+$query = new \Elastica\Query();
+$facet = new \Elastica\Facet\Terms('tags');
+$facet->setField('companyGroup');
+$query->addFacet($facet);
+
+$companies = $finder->findPaginated($query);
+$companies->setMaxPerPage($params['limit']);
+$companies->setCurrentPage($params['page']);
+
+$facets = $companies->getAdapter()->getFacets());
+```
+
+Searching the entire index
+--------------------------
+
+You can also define a finder that will work on the entire index. Adjust your index
+configuration as per below:
+
+```yaml
+fos_elastica:
+ indexes:
+ website:
+ finder: ~
+```
+
+You can now use the index wide finder service `fos_elastica.finder.website`:
+
+```php
+/** var FOS\ElasticaBundle\Finder\MappedFinder */
+$finder = $container->get('fos_elastica.finder.website');
+
+// Returns a mixed array of any objects mapped
+$results = $finder->find('bob');
+```
+
+Type Repositories
+-----------------
+
+In the case where you need many different methods for different searching terms, it
+may be better to separate methods for each type into their own dedicated repository
+classes, just like Doctrine ORM's EntityRepository classes.
+
+The manager class that handles repositories has a service key of `fos_elastica.manager`.
+The manager will default to handling ORM entities, and the configuration must be changed
+for MongoDB users.
+
+```yaml
+fos_elastica:
+ default_manager: mongodb
+```
+
+An example for using a repository:
+
+```php
+/** var FOS\ElasticaBundle\Manager\RepositoryManager */
+$repositoryManager = $container->get('fos_elastica.manager');
+
+/** var FOS\ElasticaBundle\Repository */
+$repository = $repositoryManager->getRepository('UserBundle:User');
+
+/** var array of Acme\UserBundle\Entity\User */
+$users = $repository->find('bob');
+```
+
+For more information about customising repositories, see the cookbook entry
+[Custom Repositories](custom-repositories.md).
+
+Using a custom query builder method for transforming results
+------------------------------------------------------------
+
+When returning results from Elasticsearch to be transformed by the bundle, the default
+`createQueryBuilder` method on each objects Repository class will be called. In many
+circumstances this is not ideal and you'd prefer to use a different method to join in
+any entity relations that are required on the page that will be displaying the results.
+
+```yaml
+ user:
+ elastica_to_model_transformer:
+ query_builder_method: createSearchQueryBuilder
+```
+
+Advanced Searching Example
+--------------------------
+
+If you would like to perform more advanced queries, here is one example using
+the snowball stemming algorithm.
+
+It searches for Article entities using `title`, `tags`, and `categoryIds`.
+Results must match at least one specified `categoryIds`, and should match the
+`title` or `tags` criteria. Additionally, we define a snowball analyzer to
+apply to queries against the `title` field.
+
+Assuming a type is configured as follows:
+
+```yaml
+fos_elastica:
+ indexes:
+ site:
+ settings:
+ index:
+ analysis:
+ analyzer:
+ my_analyzer:
+ type: snowball
+ language: English
+ types:
+ article:
+ mappings:
+ title: { boost: 10, analyzer: my_analyzer }
+ tags:
+ categoryIds:
+ persistence:
+ driver: orm
+ model: Acme\DemoBundle\Entity\Article
+ provider: ~
+ finder: ~
+```
+
+The following code will execute a search against the Elasticsearch server:
+
+```php
+$finder = $this->container->get('fos_elastica.finder.site.article');
+$boolQuery = new \Elastica\Query\Bool();
+
+$fieldQuery = new \Elastica\Query\Text();
+$fieldQuery->setFieldQuery('title', 'I am a title string');
+$fieldQuery->setFieldParam('title', 'analyzer', 'my_analyzer');
+$boolQuery->addShould($fieldQuery);
+
+$tagsQuery = new \Elastica\Query\Terms();
+$tagsQuery->setTerms('tags', array('tag1', 'tag2'));
+$boolQuery->addShould($tagsQuery);
+
+$categoryQuery = new \Elastica\Query\Terms();
+$categoryQuery->setTerms('categoryIds', array('1', '2', '3'));
+$boolQuery->addMust($categoryQuery);
+
+$data = $finder->find($boolQuery);
+```
From d33c5d0ece19f5758f4bc6679f26e4fdd17d7f49 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Tue, 17 Dec 2013 21:38:08 +1100
Subject: [PATCH 130/447] Fix tests
---
.travis.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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
From 4ee81dc010f987497169128f891bc4139b90fea9 Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Mon, 6 Jan 2014 09:20:44 +0100
Subject: [PATCH 131/447] Adding support for enabling timestamps
---
DependencyInjection/Configuration.php | 20 ++++++++++++++++++++
DependencyInjection/FOSElasticaExtension.php | 3 +++
2 files changed, 23 insertions(+)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index e9088e8..dd55ba1 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -299,6 +299,7 @@ class Configuration implements ConfigurationInterface
->append($this->getRoutingNode())
->append($this->getParentNode())
->append($this->getAllNode())
+ ->append($this->getTimestampNode())
->end()
;
@@ -647,4 +648,23 @@ class Configuration implements ConfigurationInterface
return $node;
}
+
+ /**
+ * Returns the array node used for "_timestamp"
+ */
+ protected function getTimestampNode()
+ {
+ $builder = new TreeBuilder();
+ $node = $builder->root('_timestamp');
+
+ $node
+ ->children()
+ ->scalarNode('enabled')->defaultValue(true)->end()
+ ->scalarNode('path')->end()
+ ->scalarNode('format')->end()
+ ->end()
+ ;
+
+ return $node;
+ }
}
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 8b85629..a38b90a 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -246,6 +246,9 @@ class FOSElasticaExtension extends Extension
if (isset($type['_all'])) {
$this->indexConfigs[$indexName]['config']['mappings'][$name]['_all'] = $type['_all'];
}
+ if (isset($type['_timestamp'])) {
+ $this->indexConfigs[$indexName]['config']['mappings'][$name]['_timestamp'] = $type['_timestamp'];
+ }
if (!empty($type['dynamic_templates'])) {
$this->indexConfigs[$indexName]['config']['mappings'][$name]['dynamic_templates'] = array();
foreach ($type['dynamic_templates'] as $templateName => $templateData) {
From 274fc0099186980d730da1c6f7249b1b899125ad Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Mon, 6 Jan 2014 10:19:11 +0100
Subject: [PATCH 132/447] Add store and index options to timestamp
---
DependencyInjection/Configuration.php | 2 ++
1 file changed, 2 insertions(+)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index dd55ba1..5cdd52a 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -662,6 +662,8 @@ class Configuration implements ConfigurationInterface
->scalarNode('enabled')->defaultValue(true)->end()
->scalarNode('path')->end()
->scalarNode('format')->end()
+ ->scalarNode('store')->end()
+ ->scalarNode('index')->end()
->end()
;
From 73ee750515b0f62a83c3198b2327589f3f644e98 Mon Sep 17 00:00:00 2001
From: Vermi
Date: Fri, 10 Jan 2014 16:25:45 +0100
Subject: [PATCH 133/447] Removing "->performNoDeepMerging()"in indexes
configuration, allowing custom Bundle defining new types in an existing
index. Configuration is injected in the new Bundle using
prependExtensionConfig()
---
DependencyInjection/Configuration.php | 1 -
1 file changed, 1 deletion(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index e9088e8..bea6cc0 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -132,7 +132,6 @@ class Configuration implements ConfigurationInterface
->arrayNode('indexes')
->useAttributeAsKey('name')
->prototype('array')
- ->performNoDeepMerging()
->children()
->scalarNode('index_name')->end()
->scalarNode('client')->end()
From 74813768358f42b3348e6f07a4b7a4179ee73259 Mon Sep 17 00:00:00 2001
From: nurikabe
Date: Sat, 11 Jan 2014 16:28:15 +0000
Subject: [PATCH 134/447] Use bulk insert. Still working on bulk update/delete
which is not yet suppored in Elastica.
---
Doctrine/Listener.php | 5 +++--
Tests/Doctrine/AbstractListenerTest.php | 6 ++++--
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/Doctrine/Listener.php b/Doctrine/Listener.php
index 383e02f..8c1d99f 100644
--- a/Doctrine/Listener.php
+++ b/Doctrine/Listener.php
@@ -214,9 +214,10 @@ class Listener implements EventSubscriber
*/
private function persistScheduled()
{
- foreach ($this->scheduledForInsertion as $entity) {
- $this->objectPersister->insertOne($entity);
+ if (count($this->scheduledForInsertion)) {
+ $this->objectPersister->insertMany($this->scheduledForInsertion);
}
+
foreach ($this->scheduledForUpdate as $entity) {
$this->objectPersister->replaceOne($entity);
}
diff --git a/Tests/Doctrine/AbstractListenerTest.php b/Tests/Doctrine/AbstractListenerTest.php
index a6ad2aa..3278be1 100644
--- a/Tests/Doctrine/AbstractListenerTest.php
+++ b/Tests/Doctrine/AbstractListenerTest.php
@@ -22,8 +22,8 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($entity, current($listener->scheduledForInsertion));
$persister->expects($this->once())
- ->method('insertOne')
- ->with($entity);
+ ->method('insertMany')
+ ->with($listener->scheduledForInsertion);
$listener->postFlush($eventArgs);
}
@@ -46,6 +46,8 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
$persister->expects($this->never())
->method('insertOne');
+ $persister->expects($this->never())
+ ->method('insertMany');
$listener->postFlush($eventArgs);
}
From 4287a91d506cbc92a1436d21175775ee2dea8c0d Mon Sep 17 00:00:00 2001
From: Tom A
Date: Thu, 16 Jan 2014 23:05:44 -0500
Subject: [PATCH 135/447] Add similarity as a valid field mapping.
http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-core-types.html#similarity
---
DependencyInjection/Configuration.php | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index e9088e8..43f9db4 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -399,7 +399,8 @@ class Configuration implements ConfigurationInterface
->scalarNode('identifier')->defaultValue('id')->end()
->end()
->end()
- ->scalarNode('format')->end();
+ ->scalarNode('format')->end()
+ ->scalarNode('similarity')->end();
;
if (isset($nestings['fields'])) {
From bbacad4bab2f6375a1bf9d841b7f64de17811047 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?T=C3=B3th=20G=C3=A1bor?=
Date: Tue, 10 Dec 2013 18:07:22 +0100
Subject: [PATCH 136/447] no-stop-on-error option added to populate command
---
Command/PopulateCommand.php | 1 +
Doctrine/AbstractProvider.php | 15 +++++++++++-
Tests/Doctrine/AbstractProviderTest.php | 32 +++++++++++++++++++++++++
3 files changed, 47 insertions(+), 1 deletion(-)
mode change 100755 => 100644 Command/PopulateCommand.php
diff --git a/Command/PopulateCommand.php b/Command/PopulateCommand.php
old mode 100755
new mode 100644
index 7297523..661f70d
--- a/Command/PopulateCommand.php
+++ b/Command/PopulateCommand.php
@@ -45,6 +45,7 @@ class PopulateCommand extends ContainerAwareCommand
->addOption('offset', null, InputOption::VALUE_REQUIRED, 'Start indexing at offset', 0)
->addOption('sleep', null, InputOption::VALUE_REQUIRED, 'Sleep time between persisting iterations (microseconds)', 0)
->addOption('batch-size', null, InputOption::VALUE_REQUIRED, 'Index packet size (overrides provider config option)')
+ ->addOption('no-stop-on-error', null, InputOption::VALUE_NONE, 'Do not stop on errors')
->setDescription('Populates search indexes from providers')
;
}
diff --git a/Doctrine/AbstractProvider.php b/Doctrine/AbstractProvider.php
index 1fb41f5..2346c80 100644
--- a/Doctrine/AbstractProvider.php
+++ b/Doctrine/AbstractProvider.php
@@ -3,6 +3,7 @@
namespace FOS\ElasticaBundle\Doctrine;
use Doctrine\Common\Persistence\ManagerRegistry;
+use Elastica\Exception\Bulk\ResponseException as BulkResponseException;
use FOS\ElasticaBundle\Persister\ObjectPersisterInterface;
use FOS\ElasticaBundle\Provider\AbstractProvider as BaseAbstractProvider;
@@ -23,6 +24,7 @@ abstract class AbstractProvider extends BaseAbstractProvider
parent::__construct($objectPersister, $objectClass, array_merge(array(
'clear_object_manager' => true,
'query_builder_method' => 'createQueryBuilder',
+ 'stop_on_error' => true,
), $options));
$this->managerRegistry = $managerRegistry;
@@ -38,6 +40,7 @@ abstract class AbstractProvider extends BaseAbstractProvider
$offset = isset($options['offset']) ? intval($options['offset']) : 0;
$sleep = isset($options['sleep']) ? intval($options['sleep']) : 0;
$batchSize = isset($options['batch-size']) ? intval($options['batch-size']) : $this->options['batch_size'];
+ $stopOnError = isset($options['no-stop-on-error']) ? empty($options['no-stop-on-error']) : $this->options['stop_on_error'];
for (; $offset < $nbObjects; $offset += $batchSize) {
if ($loggerClosure) {
@@ -45,7 +48,17 @@ abstract class AbstractProvider extends BaseAbstractProvider
}
$objects = $this->fetchSlice($queryBuilder, $batchSize, $offset);
- $this->objectPersister->insertMany($objects);
+ if (!$stopOnError) {
+ $this->objectPersister->insertMany($objects);
+ } else {
+ try {
+ $this->objectPersister->insertMany($objects);
+ } catch(BulkResponseException $e) {
+ if ($loggerClosure) {
+ $loggerClosure(sprintf('%s',$e->getMessage()));
+ }
+ }
+ }
if ($this->options['clear_object_manager']) {
$this->managerRegistry->getManagerForClass($this->objectClass)->clear();
diff --git a/Tests/Doctrine/AbstractProviderTest.php b/Tests/Doctrine/AbstractProviderTest.php
index 0a9aceb..a3836bd 100644
--- a/Tests/Doctrine/AbstractProviderTest.php
+++ b/Tests/Doctrine/AbstractProviderTest.php
@@ -135,6 +135,28 @@ class AbstractProviderTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($loggerClosureInvoked);
}
+ public function testPopulateNotStopOnError()
+ {
+ $nbObjects = 1;
+ $objects = array(1);
+
+ $provider = $this->getMockAbstractProvider();
+
+ $provider->expects($this->any())
+ ->method('countObjects')
+ ->will($this->returnValue($nbObjects));
+
+ $provider->expects($this->any())
+ ->method('fetchSlice')
+ ->will($this->returnValue($objects));
+
+ $this->objectPersister->expects($this->any())
+ ->method('insertMany')
+ ->will($this->throwException($this->getMockBulkResponseException()));
+
+ $provider->populate(null, array('no-stop-on-error' => true));
+ }
+
/**
* @return \FOS\ElasticaBundle\Doctrine\AbstractProvider|\PHPUnit_Framework_MockObject_MockObject
*/
@@ -148,6 +170,16 @@ class AbstractProviderTest extends \PHPUnit_Framework_TestCase
));
}
+ /**
+ * @return \Elastica\Exception\Bulk\ResponseException
+ */
+ private function getMockBulkResponseException()
+ {
+ return $this->getMockBuilder('Elastica\Exception\Bulk\ResponseException')
+ ->disableOriginalConstructor()
+ ->getMock();
+ }
+
/**
* @return \Doctrine\Common\Persistence\ManagerRegistry|\PHPUnit_Framework_MockObject_MockObject
*/
From b6d010a9d7e7801c17cb618d8984d70eacff8f15 Mon Sep 17 00:00:00 2001
From: nurikabe
Date: Thu, 23 Jan 2014 16:20:11 +0000
Subject: [PATCH 137/447] Bulk update. Still working on bulk delete for
indexes and types in Elastica.
---
Doctrine/Listener.php | 8 ++------
Persister/ObjectPersister.php | 17 +++++++++++------
Persister/ObjectPersisterInterface.php | 10 +++++++---
3 files changed, 20 insertions(+), 15 deletions(-)
diff --git a/Doctrine/Listener.php b/Doctrine/Listener.php
index 8c1d99f..d6314dc 100644
--- a/Doctrine/Listener.php
+++ b/Doctrine/Listener.php
@@ -214,13 +214,9 @@ class Listener implements EventSubscriber
*/
private function persistScheduled()
{
- if (count($this->scheduledForInsertion)) {
- $this->objectPersister->insertMany($this->scheduledForInsertion);
- }
+ $this->objectPersister->bulkPersist($this->scheduledForInsertion, ObjectPersisterInterface::BULK_INSERT);
+ $this->objectPersister->bulkPersist($this->scheduledForUpdate, ObjectPersisterInterface::BULK_REPLACE);
- foreach ($this->scheduledForUpdate as $entity) {
- $this->objectPersister->replaceOne($entity);
- }
foreach ($this->scheduledForDeletion as $entity) {
$this->objectPersister->deleteOne($entity);
}
diff --git a/Persister/ObjectPersister.php b/Persister/ObjectPersister.php
index 450e43b..b5a1be7 100644
--- a/Persister/ObjectPersister.php
+++ b/Persister/ObjectPersister.php
@@ -83,19 +83,24 @@ class ObjectPersister implements ObjectPersisterInterface
} catch (NotFoundException $e) {}
}
-
/**
- * Inserts an array of objects in the type
+ * Bulk update an array of objects in the type for the given method
*
* @param array $objects array of domain model objects
- **/
- public function insertMany(array $objects)
+ * @param string Method to call
+ */
+ public function bulkPersist(array $objects, $method)
{
+ if (!count($objects)) {
+ return;
+ }
+
$documents = array();
foreach ($objects as $object) {
$documents[] = $this->transformToElasticaDocument($object);
}
- $this->type->addDocuments($documents);
+
+ $this->type->$method($documents);
}
/**
@@ -108,4 +113,4 @@ class ObjectPersister implements ObjectPersisterInterface
{
return $this->transformer->transform($object, $this->fields);
}
-}
+}
\ No newline at end of file
diff --git a/Persister/ObjectPersisterInterface.php b/Persister/ObjectPersisterInterface.php
index a50bcc8..5c4ecd2 100644
--- a/Persister/ObjectPersisterInterface.php
+++ b/Persister/ObjectPersisterInterface.php
@@ -10,6 +10,9 @@ namespace FOS\ElasticaBundle\Persister;
*/
interface ObjectPersisterInterface
{
+ const BULK_INSERT = 'addDocuments';
+ const BULK_REPLACE = 'updateDocuments';
+
/**
* Insert one object into the type
* The object will be transformed to an elastica document
@@ -42,9 +45,10 @@ interface ObjectPersisterInterface
function deleteById($id);
/**
- * Inserts an array of objects in the type
+ * Bulk update an array of objects in the type for the given method
*
* @param array $objects array of domain model objects
- **/
- function insertMany(array $objects);
+ * @param string Method to call
+ */
+ function bulkPersist(array $objects, $method);
}
From 62dc3aaca04c1dc2fe62e763d8dde20d897d6f0d Mon Sep 17 00:00:00 2001
From: pkraeutli
Date: Fri, 24 Jan 2014 14:20:10 +0100
Subject: [PATCH 138/447] Populate command: use isInteractive() instead of
option
---
Command/PopulateCommand.php | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/Command/PopulateCommand.php b/Command/PopulateCommand.php
index 7297523..38bff70 100755
--- a/Command/PopulateCommand.php
+++ b/Command/PopulateCommand.php
@@ -67,10 +67,9 @@ class PopulateCommand extends ContainerAwareCommand
$index = $input->getOption('index');
$type = $input->getOption('type');
$reset = $input->getOption('no-reset') ? false : true;
- $noInteraction = $input->getOption('no-interaction');
$options = $input->getOptions();
- if (!$noInteraction && $reset && $input->getOption('offset')) {
+ if ($input->isInteractive() && $reset && $input->getOption('offset')) {
/** @var DialogHelper $dialog */
$dialog = $this->getHelperSet()->get('dialog');
if (!$dialog->askConfirmation($output, 'You chose to reset the index and start indexing with an offset. Do you really want to do that?', true)) {
From 1c7da33526dea333dfd2eed81bfb04de5031a261 Mon Sep 17 00:00:00 2001
From: Simon Perdrisat
Date: Tue, 28 Jan 2014 11:34:54 +0100
Subject: [PATCH 139/447] [doc] repository methode has to return the query
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 3006bd1..f78c97f 100644
--- a/README.md
+++ b/README.md
@@ -526,7 +526,7 @@ class UserRepository extends Repository
public function findWithCustomQuery($searchText)
{
// build $query with Elastica objects
- $this->find($query);
+ return $this->find($query);
}
}
```
From 076d51ac40dcbbe8fdd69223ab2d7a0377b60ced Mon Sep 17 00:00:00 2001
From: Piotr Antosik
Date: Wed, 29 Jan 2014 17:50:42 +0100
Subject: [PATCH 140/447] Services classes as parameters
---
Resources/config/config.xml | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/Resources/config/config.xml b/Resources/config/config.xml
index 1fb2c1d..85cfbed 100644
--- a/Resources/config/config.xml
+++ b/Resources/config/config.xml
@@ -14,6 +14,10 @@
FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerCollection
FOS\ElasticaBundle\Provider\ProviderRegistry
Symfony\Component\PropertyAccess\PropertyAccessor
+ FOS\ElasticaBundle\Persister\ObjectPersister
+ FOS\ElasticaBundle\Persister\ObjectSerializerPersister
+ FOS\ElasticaBundle\Transformer\ModelToElasticaAutoTransformer
+ FOS\ElasticaBundle\Transformer\ModelToElasticaIdentifierTransformer
@@ -37,7 +41,7 @@
-
+
@@ -49,21 +53,21 @@
-
+
-
+
-
+
From 5480e037e3a005edd548d44a7bc31fb66e406db9 Mon Sep 17 00:00:00 2001
From: Laszlo Horvath
Date: Thu, 30 Jan 2014 12:39:48 +0100
Subject: [PATCH 141/447] adding ttl for documents
---
DependencyInjection/Configuration.php | 21 ++++++++++++++++++++
DependencyInjection/FOSElasticaExtension.php | 3 +++
2 files changed, 24 insertions(+)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index ca97a4d..4ed88af 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -299,6 +299,7 @@ class Configuration implements ConfigurationInterface
->append($this->getParentNode())
->append($this->getAllNode())
->append($this->getTimestampNode())
+ ->append($this->getTtlNode())
->end()
;
@@ -669,4 +670,24 @@ class Configuration implements ConfigurationInterface
return $node;
}
+
+ /**
+ * Returns the array node used for "_ttl"
+ */
+ protected function getTtlNode()
+ {
+ $builder = new TreeBuilder();
+ $node = $builder->root('_ttl');
+
+ $node
+ ->children()
+ ->scalarNode('enabled')->defaultValue(true)->end()
+ ->scalarNode('default')->end()
+ ->scalarNode('store')->end()
+ ->scalarNode('index')->end()
+ ->end()
+ ;
+
+ return $node;
+ }
}
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index a38b90a..52070fd 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -249,6 +249,9 @@ class FOSElasticaExtension extends Extension
if (isset($type['_timestamp'])) {
$this->indexConfigs[$indexName]['config']['mappings'][$name]['_timestamp'] = $type['_timestamp'];
}
+ if (isset($type['_ttl'])) {
+ $this->indexConfigs[$indexName]['config']['mappings'][$name]['_ttl'] = $type['_ttl'];
+ }
if (!empty($type['dynamic_templates'])) {
$this->indexConfigs[$indexName]['config']['mappings'][$name]['dynamic_templates'] = array();
foreach ($type['dynamic_templates'] as $templateName => $templateData) {
From 5e54dcd9558efe686523dae6e0d1cfc0662d429c Mon Sep 17 00:00:00 2001
From: Fabien Somnier
Date: Thu, 30 Jan 2014 13:01:13 +0100
Subject: [PATCH 142/447] Add RAM (current & peak) in populate evolution
information
---
Doctrine/AbstractProvider.php | 5 ++++-
Propel/Provider.php | 5 ++++-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/Doctrine/AbstractProvider.php b/Doctrine/AbstractProvider.php
index 1fb41f5..eebfc79 100644
--- a/Doctrine/AbstractProvider.php
+++ b/Doctrine/AbstractProvider.php
@@ -54,11 +54,14 @@ abstract class AbstractProvider extends BaseAbstractProvider
usleep($sleep);
if ($loggerClosure) {
+ $memory = round(memory_get_usage() / (1024*1024),0); // to get usage in Mo
+ $memoryMax = round(memory_get_peak_usage() / (1024*1024)); // to get max usage in Mo
+ $message = '(RAM : current='.$memory.'Mo peak='.$memoryMax.'Mo)';
$stepNbObjects = count($objects);
$stepCount = $stepNbObjects + $offset;
$percentComplete = 100 * $stepCount / $nbObjects;
$objectsPerSecond = $stepNbObjects / (microtime(true) - $stepStartTime);
- $loggerClosure(sprintf('%0.1f%% (%d/%d), %d objects/s', $percentComplete, $stepCount, $nbObjects, $objectsPerSecond));
+ $loggerClosure(sprintf('%0.1f%% (%d/%d), %d objects/s %s', $percentComplete, $stepCount, $nbObjects, $objectsPerSecond, $message));
}
}
}
diff --git a/Propel/Provider.php b/Propel/Provider.php
index c319691..3eb1c4f 100644
--- a/Propel/Provider.php
+++ b/Propel/Provider.php
@@ -37,11 +37,14 @@ class Provider extends AbstractProvider
usleep($sleep);
if ($loggerClosure) {
+ $memory = round(memory_get_usage() / (1024*1024),0); // to get usage in Mo
+ $memoryMax = round(memory_get_peak_usage() / (1024*1024)); // to get usage in Mo
+ $message = '(RAM : current='.$memory.'Mo peak='.$memoryMax.'Mo)';
$stepNbObjects = count($objects);
$stepCount = $stepNbObjects + $offset;
$percentComplete = 100 * $stepCount / $nbObjects;
$objectsPerSecond = $stepNbObjects / (microtime(true) - $stepStartTime);
- $loggerClosure(sprintf('%0.1f%% (%d/%d), %d objects/s', $percentComplete, $stepCount, $nbObjects, $objectsPerSecond));
+ $loggerClosure(sprintf('%0.1f%% (%d/%d), %d objects/s %s', $percentComplete, $stepCount, $nbObjects, $objectsPerSecond, $message));
}
}
}
From 1dcaadbe6f99b42b346e04239c0c8fd7812bbf51 Mon Sep 17 00:00:00 2001
From: nurikabe
Date: Sat, 1 Feb 2014 02:14:21 +0000
Subject: [PATCH 143/447] Bulk delete
---
Doctrine/Listener.php | 17 +++++++-----
Persister/ObjectPersister.php | 37 +++++++++++++++++++++-----
Persister/ObjectPersisterInterface.php | 24 ++++++++++++-----
README.md | 4 +--
4 files changed, 59 insertions(+), 23 deletions(-)
diff --git a/Doctrine/Listener.php b/Doctrine/Listener.php
index d6314dc..c254513 100644
--- a/Doctrine/Listener.php
+++ b/Doctrine/Listener.php
@@ -210,21 +210,24 @@ class Listener implements EventSubscriber
}
/**
- * Persist scheduled action to ElasticSearch
+ * Persist scheduled objects to ElasticSearch
*/
private function persistScheduled()
{
- $this->objectPersister->bulkPersist($this->scheduledForInsertion, ObjectPersisterInterface::BULK_INSERT);
- $this->objectPersister->bulkPersist($this->scheduledForUpdate, ObjectPersisterInterface::BULK_REPLACE);
-
- foreach ($this->scheduledForDeletion as $entity) {
- $this->objectPersister->deleteOne($entity);
+ if (count($this->scheduledForInsertion)) {
+ $this->objectPersister->insertMany($this->scheduledForInsertion);
+ }
+ if (count($this->scheduledForUpdate)) {
+ $this->objectPersister->replaceMany($this->scheduledForUpdate);
+ }
+ if (count($this->scheduledForDeletion)) {
+ $this->objectPersister->deleteMany($this->scheduledForDeletion);
}
}
/**
* Iterate through scheduled actions before flushing to emulate 2.x behavior. Note that the ElasticSearch index
- * will fall out of sync with the data source in event of a crash on flush.
+ * will fall out of sync with the source data in the event of a crash during flush.
*/
public function preFlush(EventArgs $eventArgs)
{
diff --git a/Persister/ObjectPersister.php b/Persister/ObjectPersister.php
index b5a1be7..3592a78 100644
--- a/Persister/ObjectPersister.php
+++ b/Persister/ObjectPersister.php
@@ -84,23 +84,46 @@ class ObjectPersister implements ObjectPersisterInterface
}
/**
- * Bulk update an array of objects in the type for the given method
+ * Bulk insert an array of objects in the type for the given method
*
* @param array $objects array of domain model objects
* @param string Method to call
*/
- public function bulkPersist(array $objects, $method)
+ public function insertMany(array $objects)
{
- if (!count($objects)) {
- return;
- }
-
$documents = array();
foreach ($objects as $object) {
$documents[] = $this->transformToElasticaDocument($object);
}
+ $this->type->addDocuments($documents);
+ }
- $this->type->$method($documents);
+ /**
+ * Bulk updates an array of objects in the type
+ *
+ * @param array $objects array of domain model objects
+ */
+ public function replaceMany(array $objects)
+ {
+ $documents = array();
+ foreach ($objects as $object) {
+ $documents[] = $this->transformToElasticaDocument($object);
+ }
+ $this->type->updateDocuments($documents);
+ }
+
+ /**
+ * Bulk deletes an array of objects in the type
+ *
+ * @param array $objects array of domain model objects
+ */
+ public function deleteMany(array $objects)
+ {
+ $documents = array();
+ foreach ($objects as $object) {
+ $documents[] = $this->transformToElasticaDocument($object);
+ }
+ $this->type->deleteDocuments($documents);
}
/**
diff --git a/Persister/ObjectPersisterInterface.php b/Persister/ObjectPersisterInterface.php
index 5c4ecd2..a25aafc 100644
--- a/Persister/ObjectPersisterInterface.php
+++ b/Persister/ObjectPersisterInterface.php
@@ -10,9 +10,6 @@ namespace FOS\ElasticaBundle\Persister;
*/
interface ObjectPersisterInterface
{
- const BULK_INSERT = 'addDocuments';
- const BULK_REPLACE = 'updateDocuments';
-
/**
* Insert one object into the type
* The object will be transformed to an elastica document
@@ -41,14 +38,27 @@ interface ObjectPersisterInterface
* @param mixed $id
*
* @return null
- **/
+ */
function deleteById($id);
/**
- * Bulk update an array of objects in the type for the given method
+ * Bulk inserts an array of objects in the type
*
* @param array $objects array of domain model objects
- * @param string Method to call
*/
- function bulkPersist(array $objects, $method);
+ function insertMany(array $objects);
+
+ /**
+ * Bulk updates an array of objects in the type
+ *
+ * @param array $objects array of domain model objects
+ */
+ function replaceMany(array $objects);
+
+ /**
+ * Bulk deletes an array of objects in the type
+ *
+ * @param array $objects array of domain model objects
+ */
+ function deleteMany(array $objects);
}
diff --git a/README.md b/README.md
index b3a4c5d..cb6e5f8 100644
--- a/README.md
+++ b/README.md
@@ -627,8 +627,8 @@ to `true`:
delete: true
immediate: true
-> Updating ElasticSearch before flushing may cause the ElasticSearch index to fall out of sync with the
-> original data in the event of a crash.
+> Using `immediate` to update ElasticSearch before flush completes may cause the ElasticSearch index to fall out of
+> sync with the source database in the event of a crash during the flush itself, such as in the case of a bad query.
### Checking an entity method for listener
From 559d7c13f277d534fbf883ae5d989c0fe4e1adce Mon Sep 17 00:00:00 2001
From: nurikabe
Date: Sat, 1 Feb 2014 03:37:47 +0000
Subject: [PATCH 144/447] Update tests
---
Tests/Doctrine/AbstractListenerTest.php | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/Tests/Doctrine/AbstractListenerTest.php b/Tests/Doctrine/AbstractListenerTest.php
index 3278be1..a9eff66 100644
--- a/Tests/Doctrine/AbstractListenerTest.php
+++ b/Tests/Doctrine/AbstractListenerTest.php
@@ -65,8 +65,8 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($entity, current($listener->scheduledForUpdate));
$persister->expects($this->once())
- ->method('replaceOne')
- ->with($entity);
+ ->method('replaceMany')
+ ->with(array($entity));
$persister->expects($this->never())
->method('deleteById');
@@ -105,8 +105,8 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
$persister->expects($this->never())
->method('replaceOne');
$persister->expects($this->once())
- ->method('deleteOne')
- ->with($entity);
+ ->method('deleteMany')
+ ->with(array($entity));
$listener->postFlush($eventArgs);
}
@@ -136,8 +136,8 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($entity, current($listener->scheduledForDeletion));
$persister->expects($this->once())
- ->method('deleteOne')
- ->with($entity);
+ ->method('deleteMany')
+ ->with(array($entity));
$listener->postFlush($eventArgs);
}
@@ -167,8 +167,8 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($entity, current($listener->scheduledForDeletion));
$persister->expects($this->once())
- ->method('deleteOne')
- ->with($entity);
+ ->method('deleteMany')
+ ->with(array($entity));
$listener->postFlush($eventArgs);
}
From f348ebd0265aaa1d46e09c8aca5f6d646f27263c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Robert=20Sch=C3=B6nthal?=
Date: Mon, 3 Feb 2014 09:47:16 +0100
Subject: [PATCH 145/447] fixes ignore_missing option and unknown index
---
Transformer/ElasticaToModelTransformerCollection.php | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Transformer/ElasticaToModelTransformerCollection.php b/Transformer/ElasticaToModelTransformerCollection.php
index a261e81..f65f8db 100644
--- a/Transformer/ElasticaToModelTransformerCollection.php
+++ b/Transformer/ElasticaToModelTransformerCollection.php
@@ -67,7 +67,9 @@ class ElasticaToModelTransformerCollection implements ElasticaToModelTransformer
$result = array();
foreach ($elasticaObjects as $object) {
- $result[] = $transformed[$object->getType()][$object->getId()];
+ if (array_key_exists($object->getId(), $transformed[$object->getType()])) {
+ $result[] = $transformed[$object->getType()][$object->getId()];
+ }
}
return $result;
From a121a777743525f46c65dc29d983c8eb92720664 Mon Sep 17 00:00:00 2001
From: Fabien Somnier
Date: Mon, 3 Feb 2014 17:50:35 +0100
Subject: [PATCH 146/447] Avoid index reset error in case of unexistant index
---
Command/PopulateCommand.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Command/PopulateCommand.php b/Command/PopulateCommand.php
index 7297523..9d00db1 100755
--- a/Command/PopulateCommand.php
+++ b/Command/PopulateCommand.php
@@ -107,7 +107,7 @@ class PopulateCommand extends ContainerAwareCommand
*/
private function populateIndex(OutputInterface $output, $index, $reset, $options)
{
- if ($reset) {
+ if ($reset && $this->indexManager->getIndex($index)->exists()) {
$output->writeln(sprintf('Resetting %s', $index));
$this->resetter->resetIndex($index);
}
From 48b785e8764a887f903cbb81476b4368f5588bd5 Mon Sep 17 00:00:00 2001
From: Fabien Somnier
Date: Mon, 3 Feb 2014 18:12:20 +0100
Subject: [PATCH 147/447] New method getMemoryUsage to get RAM information
message
---
Doctrine/AbstractProvider.php | 5 +----
Propel/Provider.php | 5 +----
Provider/AbstractProvider.php | 12 ++++++++++++
3 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/Doctrine/AbstractProvider.php b/Doctrine/AbstractProvider.php
index eebfc79..796a5e4 100644
--- a/Doctrine/AbstractProvider.php
+++ b/Doctrine/AbstractProvider.php
@@ -54,14 +54,11 @@ abstract class AbstractProvider extends BaseAbstractProvider
usleep($sleep);
if ($loggerClosure) {
- $memory = round(memory_get_usage() / (1024*1024),0); // to get usage in Mo
- $memoryMax = round(memory_get_peak_usage() / (1024*1024)); // to get max usage in Mo
- $message = '(RAM : current='.$memory.'Mo peak='.$memoryMax.'Mo)';
$stepNbObjects = count($objects);
$stepCount = $stepNbObjects + $offset;
$percentComplete = 100 * $stepCount / $nbObjects;
$objectsPerSecond = $stepNbObjects / (microtime(true) - $stepStartTime);
- $loggerClosure(sprintf('%0.1f%% (%d/%d), %d objects/s %s', $percentComplete, $stepCount, $nbObjects, $objectsPerSecond, $message));
+ $loggerClosure(sprintf('%0.1f%% (%d/%d), %d objects/s %s', $percentComplete, $stepCount, $nbObjects, $objectsPerSecond, $this->getMemoryUsage()));
}
}
}
diff --git a/Propel/Provider.php b/Propel/Provider.php
index 3eb1c4f..393beba 100644
--- a/Propel/Provider.php
+++ b/Propel/Provider.php
@@ -37,14 +37,11 @@ class Provider extends AbstractProvider
usleep($sleep);
if ($loggerClosure) {
- $memory = round(memory_get_usage() / (1024*1024),0); // to get usage in Mo
- $memoryMax = round(memory_get_peak_usage() / (1024*1024)); // to get usage in Mo
- $message = '(RAM : current='.$memory.'Mo peak='.$memoryMax.'Mo)';
$stepNbObjects = count($objects);
$stepCount = $stepNbObjects + $offset;
$percentComplete = 100 * $stepCount / $nbObjects;
$objectsPerSecond = $stepNbObjects / (microtime(true) - $stepStartTime);
- $loggerClosure(sprintf('%0.1f%% (%d/%d), %d objects/s %s', $percentComplete, $stepCount, $nbObjects, $objectsPerSecond, $message));
+ $loggerClosure(sprintf('%0.1f%% (%d/%d), %d objects/s %s', $percentComplete, $stepCount, $nbObjects, $objectsPerSecond, $this->getMemoryUsage()));
}
}
}
diff --git a/Provider/AbstractProvider.php b/Provider/AbstractProvider.php
index 06883a3..48da5d7 100644
--- a/Provider/AbstractProvider.php
+++ b/Provider/AbstractProvider.php
@@ -26,4 +26,16 @@ abstract class AbstractProvider implements ProviderInterface
'batch_size' => 100,
), $options);
}
+
+ /**
+ * Get string with RAM usage information (current and peak)
+ *
+ * @return string
+ */
+ protected function getMemoryUsage() {
+ $memory = round(memory_get_usage() / (1024*1024),0); // to get usage in Mo
+ $memoryMax = round(memory_get_peak_usage() / (1024*1024)); // to get max usage in Mo
+ $message = '(RAM : current='.$memory.'Mo peak='.$memoryMax.'Mo)';
+ return $message;
+ }
}
From 04390b37d1bacb16cce87384e0c33914ace7b967 Mon Sep 17 00:00:00 2001
From: tgallice
Date: Tue, 4 Feb 2014 10:07:58 +0100
Subject: [PATCH 148/447] Force slash at the end of the url parameter
---
DependencyInjection/Configuration.php | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 4ed88af..0c6ca82 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -101,7 +101,12 @@ class Configuration implements ConfigurationInterface
->arrayNode('servers')
->prototype('array')
->children()
- ->scalarNode('url')->end()
+ ->scalarNode('url')
+ ->validate()
+ ->ifTrue(function($v) { return substr($v['url'], -1) !== '/'; })
+ ->then(function($v) { return $v['url'].'/'; })
+ ->end()
+ ->end()
->scalarNode('host')->end()
->scalarNode('port')->end()
->scalarNode('logger')
From d04a403f71f82b46c3a3314031595b0c60b9dee9 Mon Sep 17 00:00:00 2001
From: Hung Tran
Date: Tue, 4 Feb 2014 19:41:38 -0600
Subject: [PATCH 149/447] added support for setting search options
---
Finder/FinderInterface.php | 3 ++-
Finder/PaginatedFinderInterface.php | 6 ++++--
Finder/TransformedFinder.php | 23 +++++++++++++----------
Paginator/RawPaginatorAdapter.php | 10 ++++++++--
Paginator/TransformedPaginatorAdapter.php | 4 ++--
Repository.php | 16 ++++++++--------
6 files changed, 37 insertions(+), 25 deletions(-)
diff --git a/Finder/FinderInterface.php b/Finder/FinderInterface.php
index 4805d58..7c257de 100644
--- a/Finder/FinderInterface.php
+++ b/Finder/FinderInterface.php
@@ -9,7 +9,8 @@ interface FinderInterface
*
* @param mixed $query Can be a string, an array or an \Elastica\Query object
* @param int $limit How many results to get
+ * @param array $options
* @return array results
*/
- function find($query, $limit = null);
+ function find($query, $limit = null, $options = array());
}
diff --git a/Finder/PaginatedFinderInterface.php b/Finder/PaginatedFinderInterface.php
index 3581cda..fa10b70 100644
--- a/Finder/PaginatedFinderInterface.php
+++ b/Finder/PaginatedFinderInterface.php
@@ -12,15 +12,17 @@ interface PaginatedFinderInterface extends FinderInterface
* Searches for query results and returns them wrapped in a paginator
*
* @param mixed $query Can be a string, an array or an \Elastica\Query object
+ * @param array $options
* @return Pagerfanta paginated results
*/
- function findPaginated($query);
+ function findPaginated($query, $options = array());
/**
* Creates a paginator adapter for this query
*
* @param mixed $query
+ * @param array $options
* @return PaginatorAdapterInterface
*/
- function createPaginatorAdapter($query);
+ function createPaginatorAdapter($query, $options = array());
}
diff --git a/Finder/TransformedFinder.php b/Finder/TransformedFinder.php
index 4c8aa98..9080701 100644
--- a/Finder/TransformedFinder.php
+++ b/Finder/TransformedFinder.php
@@ -29,18 +29,19 @@ class TransformedFinder implements PaginatedFinderInterface
*
* @param string $query
* @param integer $limit
+ * @param array $options
* @return array of model objects
**/
- public function find($query, $limit = null)
+ public function find($query, $limit = null, $options = array())
{
- $results = $this->search($query, $limit);
+ $results = $this->search($query, $limit, $options);
return $this->transformer->transform($results);
}
- public function findHybrid($query, $limit = null)
+ public function findHybrid($query, $limit = null, $options = array())
{
- $results = $this->search($query, $limit);
+ $results = $this->search($query, $limit, $options);
return $this->transformer->hybridTransform($results);
}
@@ -64,15 +65,16 @@ class TransformedFinder implements PaginatedFinderInterface
/**
* @param $query
* @param null|int $limit
+ * @param array $options
* @return array
*/
- protected function search($query, $limit = null)
+ protected function search($query, $limit = null, $options = array())
{
$queryObject = Query::create($query);
if (null !== $limit) {
$queryObject->setSize($limit);
}
- $results = $this->searchable->search($queryObject)->getResults();
+ $results = $this->searchable->search($queryObject, $options)->getResults();
return $results;
}
@@ -81,12 +83,13 @@ class TransformedFinder implements PaginatedFinderInterface
* Gets a paginator wrapping the result of a search
*
* @param string $query
+ * @param array $options
* @return Pagerfanta
*/
- public function findPaginated($query)
+ public function findPaginated($query, $options = array())
{
$queryObject = Query::create($query);
- $paginatorAdapter = $this->createPaginatorAdapter($queryObject);
+ $paginatorAdapter = $this->createPaginatorAdapter($queryObject, $options);
return new Pagerfanta(new FantaPaginatorAdapter($paginatorAdapter));
}
@@ -94,10 +97,10 @@ class TransformedFinder implements PaginatedFinderInterface
/**
* {@inheritdoc}
*/
- public function createPaginatorAdapter($query)
+ public function createPaginatorAdapter($query, $options = array())
{
$query = Query::create($query);
- return new TransformedPaginatorAdapter($this->searchable, $query, $this->transformer);
+ return new TransformedPaginatorAdapter($this->searchable, $query, $options, $this->transformer);
}
}
diff --git a/Paginator/RawPaginatorAdapter.php b/Paginator/RawPaginatorAdapter.php
index d4b5357..e99746f 100644
--- a/Paginator/RawPaginatorAdapter.php
+++ b/Paginator/RawPaginatorAdapter.php
@@ -22,6 +22,11 @@ class RawPaginatorAdapter implements PaginatorAdapterInterface
*/
private $query;
+ /**
+ * @var array search options
+ */
+ private $options;
+
/**
* @var integer the number of hits
*/
@@ -38,10 +43,11 @@ class RawPaginatorAdapter implements PaginatorAdapterInterface
* @param SearchableInterface $searchable the object to search in
* @param Query $query the query to search
*/
- public function __construct(SearchableInterface $searchable, Query $query)
+ public function __construct(SearchableInterface $searchable, Query $query, array $options = array())
{
$this->searchable = $searchable;
$this->query = $query;
+ $this->options = $options;
}
/**
@@ -72,7 +78,7 @@ class RawPaginatorAdapter implements PaginatorAdapterInterface
$query->setFrom($offset);
$query->setSize($itemCountPerPage);
- $resultSet = $this->searchable->search($query);
+ $resultSet = $this->searchable->search($query, $this->options);
$this->totalHits = $resultSet->getTotalHits();
$this->facets = $resultSet->getFacets();
return $resultSet;
diff --git a/Paginator/TransformedPaginatorAdapter.php b/Paginator/TransformedPaginatorAdapter.php
index 7bc038a..10976f7 100644
--- a/Paginator/TransformedPaginatorAdapter.php
+++ b/Paginator/TransformedPaginatorAdapter.php
@@ -18,9 +18,9 @@ class TransformedPaginatorAdapter extends RawPaginatorAdapter
* @param Query $query the query to search
* @param ElasticaToModelTransformerInterface $transformer the transformer for fetching the results
*/
- public function __construct(SearchableInterface $searchable, Query $query, ElasticaToModelTransformerInterface $transformer)
+ public function __construct(SearchableInterface $searchable, Query $query, array $options = array(), ElasticaToModelTransformerInterface $transformer)
{
- parent::__construct($searchable, $query);
+ parent::__construct($searchable, $query, $options);
$this->transformer = $transformer;
}
diff --git a/Repository.php b/Repository.php
index 413f1e4..70b2a21 100644
--- a/Repository.php
+++ b/Repository.php
@@ -19,23 +19,23 @@ class Repository
$this->finder = $finder;
}
- public function find($query, $limit=null)
+ public function find($query, $limit = null, $options = array())
{
- return $this->finder->find($query, $limit);
+ return $this->finder->find($query, $limit, $options);
}
- public function findHybrid($query, $limit=null)
+ public function findHybrid($query, $limit = null, $options = array())
{
- return $this->finder->findHybrid($query, $limit);
+ return $this->finder->findHybrid($query, $limit, $options);
}
- public function findPaginated($query)
+ public function findPaginated($query, $options = array())
{
- return $this->finder->findPaginated($query);
+ return $this->finder->findPaginated($query, $options);
}
- public function createPaginatorAdapter($query)
+ public function createPaginatorAdapter($query, $options = array())
{
- return $this->finder->createPaginatorAdapter($query);
+ return $this->finder->createPaginatorAdapter($query, $options);
}
}
From 5be3a8c22ea9577f12200b42b14318899c1260de Mon Sep 17 00:00:00 2001
From: Hung Tran
Date: Wed, 5 Feb 2014 11:21:14 -0600
Subject: [PATCH 150/447] added query string to collector and updated tests
---
Client.php | 2 +-
Logger/ElasticaLogger.php | 6 ++++--
Resources/views/Collector/elastica.html.twig | 3 ++-
Tests/ClientTest.php | 1 +
Tests/Logger/ElasticaLoggerTest.php | 4 +++-
5 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/Client.php b/Client.php
index ea0c572..7719095 100644
--- a/Client.php
+++ b/Client.php
@@ -27,7 +27,7 @@ class Client extends ElasticaClient
'transport' => $connection->getTransport(),
);
- $this->_logger->logQuery($path, $method, $data, $time, $connection_array);
+ $this->_logger->logQuery($path, $method, $data, $time, $connection_array, $query);
}
return $response;
diff --git a/Logger/ElasticaLogger.php b/Logger/ElasticaLogger.php
index 7aacac5..60f28db 100644
--- a/Logger/ElasticaLogger.php
+++ b/Logger/ElasticaLogger.php
@@ -37,10 +37,11 @@ class ElasticaLogger implements LoggerInterface
* @param string $path Path to call
* @param string $method Rest method to use (GET, POST, DELETE, PUT)
* @param array $data arguments
+ * @param array $query arguments
* @param float $time execution time
* @param array $connection host, port and transport of the query
*/
- public function logQuery($path, $method, $data, $time, $connection = array())
+ public function logQuery($path, $method, $data, $time, $connection = array(), $query = array())
{
if ($this->debug) {
$this->queries[] = array(
@@ -48,7 +49,8 @@ class ElasticaLogger implements LoggerInterface
'method' => $method,
'data' => $data,
'executionMS' => $time,
- 'connection' => $connection
+ 'connection' => $connection,
+ 'queryString' => $query,
);
}
diff --git a/Resources/views/Collector/elastica.html.twig b/Resources/views/Collector/elastica.html.twig
index 0eb50a6..637dae7 100644
--- a/Resources/views/Collector/elastica.html.twig
+++ b/Resources/views/Collector/elastica.html.twig
@@ -44,6 +44,7 @@
{% for key, query in collector.queries %}
Path: {{ query.path }}
+ Query: {{ query.queryString|url_encode }}
Method: {{ query.method }} ({{ query.connection.transport }} on {{ query.connection.host }}:{{ query.connection.port }})
{{ query.data|json_encode }}
@@ -60,7 +61,7 @@
- curl -X{{ query.method }} '{{ query.connection.transport|lower }}://{{ query.connection.host }}:{{ query.connection.port }}/{{ query.path }}' -d '{{ query.data|json_encode }}'
+ curl -X{{ query.method }} '{{ query.connection.transport|lower }}://{{ query.connection.host }}:{{ query.connection.port }}/{{ query.path }}{% if query.queryString|length %}?{{ query.queryString|url_encode }}{% endif %}' -d '{{ query.data|json_encode }}'
{% endif %}
diff --git a/Tests/ClientTest.php b/Tests/ClientTest.php
index c8509cf..8a9d91a 100644
--- a/Tests/ClientTest.php
+++ b/Tests/ClientTest.php
@@ -24,6 +24,7 @@ class ClientTest extends \PHPUnit_Framework_TestCase
Request::GET,
$this->isType('array'),
$this->isType('float'),
+ $this->isType('array'),
$this->isType('array')
);
diff --git a/Tests/Logger/ElasticaLoggerTest.php b/Tests/Logger/ElasticaLoggerTest.php
index 30ce30c..96adf53 100644
--- a/Tests/Logger/ElasticaLoggerTest.php
+++ b/Tests/Logger/ElasticaLoggerTest.php
@@ -70,6 +70,7 @@ class ElasticaLoggerTest extends \PHPUnit_Framework_TestCase
$data = array('data');
$time = 12;
$connection = array('host' => 'localhost', 'port' => '8999', 'transport' => 'https');
+ $query = array('search_type' => 'dfs_query_then_fetch');
$expected = array(
'path' => $path,
@@ -77,9 +78,10 @@ class ElasticaLoggerTest extends \PHPUnit_Framework_TestCase
'data' => $data,
'executionMS' => $time,
'connection' => $connection,
+ 'queryString' => $query,
);
- $elasticaLogger->logQuery($path, $method, $data, $time, $connection);
+ $elasticaLogger->logQuery($path, $method, $data, $time, $connection, $query);
$returnedQueries = $elasticaLogger->getQueries();
$this->assertEquals($expected, $returnedQueries[0]);
}
From 3b1a756e6f89e828b2f9f2c5b280d0f86a72637c Mon Sep 17 00:00:00 2001
From: Richard Miller
Date: Thu, 6 Feb 2014 21:11:12 +0000
Subject: [PATCH 151/447] Add support for using aliases to allow hot swapping
of indexes when populating
---
Client.php | 5 +
Command/PopulateCommand.php | 1 +
DependencyInjection/Configuration.php | 5 +-
DependencyInjection/FOSElasticaExtension.php | 5 +
DynamicIndex.php | 28 ++++
Resetter.php | 136 ++++++++++++++++++-
Resources/config/config.xml | 2 +-
7 files changed, 176 insertions(+), 6 deletions(-)
create mode 100644 DynamicIndex.php
diff --git a/Client.php b/Client.php
index ea0c572..67252ec 100644
--- a/Client.php
+++ b/Client.php
@@ -32,4 +32,9 @@ class Client extends ElasticaClient
return $response;
}
+
+ public function getIndex($name)
+ {
+ return new DynamicIndex($this, $name);
+ }
}
diff --git a/Command/PopulateCommand.php b/Command/PopulateCommand.php
index 7297523..31ecc4b 100755
--- a/Command/PopulateCommand.php
+++ b/Command/PopulateCommand.php
@@ -124,6 +124,7 @@ class PopulateCommand extends ContainerAwareCommand
}
$output->writeln(sprintf('Refreshing %s', $index));
+ $this->resetter->postPopulate($index);
$this->indexManager->getIndex($index)->refresh();
}
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 4ed88af..403de85 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -134,6 +134,7 @@ class Configuration implements ConfigurationInterface
->prototype('array')
->children()
->scalarNode('index_name')->end()
+ ->booleanNode('use_alias')->defaultValue(false)->end()
->scalarNode('client')->end()
->scalarNode('finder')
->treatNullLike(true)
@@ -670,7 +671,7 @@ class Configuration implements ConfigurationInterface
return $node;
}
-
+
/**
* Returns the array node used for "_ttl"
*/
@@ -689,5 +690,5 @@ class Configuration implements ConfigurationInterface
;
return $node;
- }
+ }
}
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 52070fd..a67be0f 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -124,6 +124,7 @@ class FOSElasticaExtension extends Extension
$indexIds[$name] = $indexId;
$this->indexConfigs[$name] = array(
'index' => new Reference($indexId),
+ 'name_or_alias' => $indexName,
'config' => array(
'mappings' => array()
)
@@ -134,6 +135,10 @@ class FOSElasticaExtension extends Extension
if (!empty($index['settings'])) {
$this->indexConfigs[$name]['config']['settings'] = $index['settings'];
}
+ if ($index['use_alias']) {
+ $this->indexConfigs[$name]['use_alias'] = true;
+ }
+
$this->loadTypes(isset($index['types']) ? $index['types'] : array(), $container, $name, $indexId, $typePrototypeConfig);
}
diff --git a/DynamicIndex.php b/DynamicIndex.php
new file mode 100644
index 0000000..cbec8e9
--- /dev/null
+++ b/DynamicIndex.php
@@ -0,0 +1,28 @@
+
+ */
+class DynamicIndex extends Index
+{
+ /**
+ * Reassign index name
+ *
+ * While it's technically a regular setter for name property, it's specifically named overrideName, but not setName
+ * since it's used for a very specific case and normally should not be used
+ *
+ * @param string $name Index name
+ *
+ * @return void
+ */
+ public function overrideName($name)
+ {
+ $this->_name = $name;
+ }
+}
diff --git a/Resetter.php b/Resetter.php
index 26a6bb5..b8e7b80 100644
--- a/Resetter.php
+++ b/Resetter.php
@@ -2,6 +2,8 @@
namespace FOS\ElasticaBundle;
+use Elastica\Exception\ExceptionInterface;
+use Elastica\Index;
use Elastica\Type\Mapping;
/**
@@ -26,8 +28,8 @@ class Resetter
*/
public function resetAllIndexes()
{
- foreach ($this->indexConfigsByName as $indexConfig) {
- $indexConfig['index']->create($indexConfig['config'], true);
+ foreach (array_keys($this->indexConfigsByName) as $name) {
+ $this->resetIndex($name);
}
}
@@ -40,7 +42,17 @@ class Resetter
public function resetIndex($indexName)
{
$indexConfig = $this->getIndexConfig($indexName);
- $indexConfig['index']->create($indexConfig['config'], true);
+ $esIndex = $indexConfig['index'];
+ if (isset($indexConfig['use_alias']) && $indexConfig['use_alias']) {
+ $name = $indexConfig['name_or_alias'];
+ $name .= date('-Y-m-d-Gis');
+ $esIndex->overrideName($name);
+ $esIndex->create($indexConfig['config']);
+
+ return;
+ }
+
+ $esIndex->create($indexConfig['config'], true);
}
/**
@@ -102,4 +114,122 @@ class Resetter
return $this->indexConfigsByName[$indexName];
}
+
+ public function postPopulate($indexName)
+ {
+ $indexConfig = $this->getIndexConfig($indexName);
+ if (isset($indexConfig['use_alias']) && $indexConfig['use_alias']) {
+ $this->switchIndexAlias($indexName);
+ }
+ }
+
+ /**
+ * Switches the alias for given index to the newly populated index
+ * and deletes the old index
+ *
+ * @param string $indexName Index name
+ *
+ * @throws \RuntimeException
+ */
+ private function switchIndexAlias($indexName)
+ {
+ $indexConfig = $this->getIndexConfig($indexName);
+ $esIndex = $indexConfig['index'];
+ $aliasName = $indexConfig['name_or_alias'];
+ $oldIndexName = false;
+ $newIndexName = $esIndex->getName();
+
+ $aliasedIndexes = $this->getAliasedIndexes($esIndex, $aliasName);
+
+ if (count($aliasedIndexes) > 1) {
+ throw new \RuntimeException(
+ sprintf(
+ 'Alias %s is used for multiple indexes: [%s].
+ Make sure it\'s either not used or is assigned to one index only',
+ $aliasName,
+ join(', ', $aliasedIndexes)
+ )
+ );
+ }
+
+ // Change the alias to point to the new index
+ // Elastica's addAlias can't be used directly, because in current (0.19.x) version it's not atomic
+ // In 0.20.x it's atomic, but it doesn't return the old index name
+ $aliasUpdateRequest = array('actions' => array());
+ if (count($aliasedIndexes) == 1) {
+ // if the alias is set - add an action to remove it
+ $oldIndexName = $aliasedIndexes[0];
+ $aliasUpdateRequest['actions'][] = array(
+ 'remove' => array('index' => $oldIndexName, 'alias' => $aliasName)
+ );
+ }
+
+ // add an action to point the alias to the new index
+ $aliasUpdateRequest['actions'][] = array(
+ 'add' => array('index' => $newIndexName, 'alias' => $aliasName)
+ );
+
+ try {
+ $esIndex->getClient()->request('_aliases', 'POST', $aliasUpdateRequest);
+ } catch (ExceptionInterface $renameAliasException) {
+ $additionalError = '';
+ // if we failed to move the alias, delete the newly built index
+ try {
+ $esIndex->delete();
+ } catch (ExceptionInterface $deleteNewIndexException) {
+ $additionalError = sprintf(
+ 'Tried to delete newly built index %s, but also failed: %s',
+ $newIndexName,
+ $deleteNewIndexException->getError()
+ );
+ }
+
+ throw new \RuntimeException(
+ sprintf(
+ 'Failed to updated index alias: %s. %s',
+ $renameAliasException->getMessage(),
+ $additionalError ?: sprintf('Newly built index %s was deleted', $newIndexName)
+ )
+ );
+ }
+
+ // Delete the old index after the alias has been switched
+ if ($oldIndexName) {
+ $oldIndex = new Index($esIndex->getClient(), $oldIndexName);
+ try {
+ $oldIndex->delete();
+ } catch (ExceptionInterface $deleteOldIndexException) {
+ throw new \RuntimeException(
+ sprintf(
+ 'Failed to delete old index %s with message: %s',
+ $oldIndexName,
+ $deleteOldIndexException->getMessage()
+ )
+ );
+ }
+ }
+ }
+
+ /**
+ * Returns array of indexes which are mapped to given alias
+ *
+ * @param Index $esIndex ES Index
+ * @param string $aliasName Alias name
+ *
+ * @return array
+ */
+ private function getAliasedIndexes(Index $esIndex, $aliasName)
+ {
+ $aliasesInfo = $esIndex->getClient()->request('_aliases', 'GET')->getData();
+ $aliasedIndexes = array();
+
+ foreach ($aliasesInfo as $indexName => $indexInfo) {
+ $aliases = array_keys($indexInfo['aliases']);
+ if (in_array($aliasName, $aliases)) {
+ $aliasedIndexes[] = $indexName;
+ }
+ }
+
+ return $aliasedIndexes;
+ }
}
diff --git a/Resources/config/config.xml b/Resources/config/config.xml
index 85cfbed..4419b4a 100644
--- a/Resources/config/config.xml
+++ b/Resources/config/config.xml
@@ -6,7 +6,7 @@
FOS\ElasticaBundle\Client
- Elastica\Index
+ FOS\ElasticaBundle\DynamicIndex
Elastica\Type
FOS\ElasticaBundle\Logger\ElasticaLogger
FOS\ElasticaBundle\DataCollector\ElasticaDataCollector
From 03bf793b656a11646ae74a351ce46dd3de74b045 Mon Sep 17 00:00:00 2001
From: Richard Miller
Date: Mon, 10 Feb 2014 10:55:13 +0000
Subject: [PATCH 152/447] Make real index name use uniqid so can be reset
within a second
---
Resetter.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Resetter.php b/Resetter.php
index b8e7b80..4a7f13b 100644
--- a/Resetter.php
+++ b/Resetter.php
@@ -45,7 +45,7 @@ class Resetter
$esIndex = $indexConfig['index'];
if (isset($indexConfig['use_alias']) && $indexConfig['use_alias']) {
$name = $indexConfig['name_or_alias'];
- $name .= date('-Y-m-d-Gis');
+ $name .= uniqid();
$esIndex->overrideName($name);
$esIndex->create($indexConfig['config']);
@@ -124,7 +124,7 @@ class Resetter
}
/**
- * Switches the alias for given index to the newly populated index
+ * Switches the alias for given index (by key) to the newly populated index
* and deletes the old index
*
* @param string $indexName Index name
From 1402bdc9e63911510e093d22deb7b8290856719c Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Thu, 13 Feb 2014 09:11:05 +0100
Subject: [PATCH 153/447] Keep all special mapping fields for types when
resetting a single type. Field list is according to the current documentation
of elasticsearch 0.90
---
Resetter.php | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/Resetter.php b/Resetter.php
index 26a6bb5..d0f3014 100644
--- a/Resetter.php
+++ b/Resetter.php
@@ -74,12 +74,11 @@ class Resetter
{
$mapping = Mapping::create($indexConfig['properties']);
- if (isset($indexConfig['_parent'])) {
- $mapping->setParam('_parent', array('type' => $indexConfig['_parent']['type']));
- }
-
- if (isset($indexConfig['dynamic_templates'])) {
- $mapping->setParam('dynamic_templates', $indexConfig['dynamic_templates']);
+ $mappingSpecialFields = array('_uid', '_id', '_source', '_all', '_analyzer', '_boost', '_parent', '_routing', '_index', '_size', '_timestamp', '_ttl');
+ foreach ($mappingSpecialFields as $specialField) {
+ if (isset($indexConfig[$specialField])) {
+ $mapping->setParam($specialField, $indexConfig[$specialField]);
+ }
}
return $mapping;
From ead3c95c88ed11756d0fdfbf11f9c7a8dfe84271 Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Thu, 13 Feb 2014 09:45:27 +0100
Subject: [PATCH 154/447] Keep dynamic templates
---
Resetter.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Resetter.php b/Resetter.php
index d0f3014..d193c9d 100644
--- a/Resetter.php
+++ b/Resetter.php
@@ -74,7 +74,7 @@ class Resetter
{
$mapping = Mapping::create($indexConfig['properties']);
- $mappingSpecialFields = array('_uid', '_id', '_source', '_all', '_analyzer', '_boost', '_parent', '_routing', '_index', '_size', '_timestamp', '_ttl');
+ $mappingSpecialFields = array('_uid', '_id', '_source', '_all', '_analyzer', '_boost', '_parent', '_routing', '_index', '_size', '_timestamp', '_ttl', 'dynamic_templates');
foreach ($mappingSpecialFields as $specialField) {
if (isset($indexConfig[$specialField])) {
$mapping->setParam($specialField, $indexConfig[$specialField]);
From 765e400278fff2e59030e47bdead2f8240ef1fef Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Thu, 13 Feb 2014 10:06:10 +0100
Subject: [PATCH 155/447] handle _parent separately
---
Resetter.php | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/Resetter.php b/Resetter.php
index d193c9d..69620a2 100644
--- a/Resetter.php
+++ b/Resetter.php
@@ -74,13 +74,17 @@ class Resetter
{
$mapping = Mapping::create($indexConfig['properties']);
- $mappingSpecialFields = array('_uid', '_id', '_source', '_all', '_analyzer', '_boost', '_parent', '_routing', '_index', '_size', '_timestamp', '_ttl', 'dynamic_templates');
+ $mappingSpecialFields = array('_uid', '_id', '_source', '_all', '_analyzer', '_boost', '_routing', '_index', '_size', '_timestamp', '_ttl', 'dynamic_templates');
foreach ($mappingSpecialFields as $specialField) {
if (isset($indexConfig[$specialField])) {
$mapping->setParam($specialField, $indexConfig[$specialField]);
}
}
+ if (isset($indexConfig['_parent'])) {
+ $mapping->setParam('_parent', array('type' => $indexConfig['_parent']['type']));
+ }
+
return $mapping;
}
From 3065c96a2ca51ec03f5aa32877a75079faa8b413 Mon Sep 17 00:00:00 2001
From: Patrick McAndrew
Date: Fri, 14 Feb 2014 17:32:22 +0000
Subject: [PATCH 156/447] Add ability to specify server timeout
---
DependencyInjection/Configuration.php | 1 +
1 file changed, 1 insertion(+)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 79cadf2..b2a1756 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -102,6 +102,7 @@ class Configuration implements ConfigurationInterface
->scalarNode('url')->end()
->scalarNode('host')->end()
->scalarNode('port')->end()
+ ->scalarNode('timeout')->end()
->end()
->end()
->end()
From 7d2776e27aad52dc7808a5db55e795b436790aef Mon Sep 17 00:00:00 2001
From: Hung Tran
Date: Tue, 18 Feb 2014 10:12:31 -0600
Subject: [PATCH 157/447] fixed phpdoc
---
Logger/ElasticaLogger.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Logger/ElasticaLogger.php b/Logger/ElasticaLogger.php
index 60f28db..0e0a9c0 100644
--- a/Logger/ElasticaLogger.php
+++ b/Logger/ElasticaLogger.php
@@ -37,9 +37,9 @@ class ElasticaLogger implements LoggerInterface
* @param string $path Path to call
* @param string $method Rest method to use (GET, POST, DELETE, PUT)
* @param array $data arguments
- * @param array $query arguments
* @param float $time execution time
* @param array $connection host, port and transport of the query
+ * @param array $query arguments
*/
public function logQuery($path, $method, $data, $time, $connection = array(), $query = array())
{
From b8cc6d758c3fb8a6397184bb423deebbae38208b Mon Sep 17 00:00:00 2001
From: Karel Souffriau
Date: Wed, 19 Feb 2014 09:31:22 +0100
Subject: [PATCH 158/447] CS fix in AbstractProvider
---
Provider/AbstractProvider.php | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Provider/AbstractProvider.php b/Provider/AbstractProvider.php
index 48da5d7..8f5ad60 100644
--- a/Provider/AbstractProvider.php
+++ b/Provider/AbstractProvider.php
@@ -32,10 +32,12 @@ abstract class AbstractProvider implements ProviderInterface
*
* @return string
*/
- protected function getMemoryUsage() {
+ protected function getMemoryUsage()
+ {
$memory = round(memory_get_usage() / (1024*1024),0); // to get usage in Mo
$memoryMax = round(memory_get_peak_usage() / (1024*1024)); // to get max usage in Mo
$message = '(RAM : current='.$memory.'Mo peak='.$memoryMax.'Mo)';
+
return $message;
}
}
From 41bf07ec5995e47d95fb4b01d0434eb04e283680 Mon Sep 17 00:00:00 2001
From: Karel Souffriau
Date: Wed, 19 Feb 2014 11:01:54 +0100
Subject: [PATCH 159/447] Fixed issues in #426
---
Command/PopulateCommand.php | 4 +++-
Doctrine/AbstractProvider.php | 6 +++---
Tests/Doctrine/AbstractProviderTest.php | 4 +++-
3 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/Command/PopulateCommand.php b/Command/PopulateCommand.php
index 07badd7..b13ddc3 100644
--- a/Command/PopulateCommand.php
+++ b/Command/PopulateCommand.php
@@ -45,7 +45,7 @@ class PopulateCommand extends ContainerAwareCommand
->addOption('offset', null, InputOption::VALUE_REQUIRED, 'Start indexing at offset', 0)
->addOption('sleep', null, InputOption::VALUE_REQUIRED, 'Sleep time between persisting iterations (microseconds)', 0)
->addOption('batch-size', null, InputOption::VALUE_REQUIRED, 'Index packet size (overrides provider config option)')
- ->addOption('no-stop-on-error', null, InputOption::VALUE_NONE, 'Do not stop on errors')
+ ->addOption('ignore-errors', null, InputOption::VALUE_NONE, 'Do not stop on errors')
->setDescription('Populates search indexes from providers')
;
}
@@ -70,6 +70,8 @@ class PopulateCommand extends ContainerAwareCommand
$reset = $input->getOption('no-reset') ? false : true;
$options = $input->getOptions();
+ $options['ignore-errors'] = $input->hasOption('ignore-errors');
+
if ($input->isInteractive() && $reset && $input->getOption('offset')) {
/** @var DialogHelper $dialog */
$dialog = $this->getHelperSet()->get('dialog');
diff --git a/Doctrine/AbstractProvider.php b/Doctrine/AbstractProvider.php
index 109cfa0..9d1575c 100644
--- a/Doctrine/AbstractProvider.php
+++ b/Doctrine/AbstractProvider.php
@@ -23,8 +23,8 @@ abstract class AbstractProvider extends BaseAbstractProvider
{
parent::__construct($objectPersister, $objectClass, array_merge(array(
'clear_object_manager' => true,
+ 'ignore_errors' => false,
'query_builder_method' => 'createQueryBuilder',
- 'stop_on_error' => true,
), $options));
$this->managerRegistry = $managerRegistry;
@@ -40,7 +40,7 @@ abstract class AbstractProvider extends BaseAbstractProvider
$offset = isset($options['offset']) ? intval($options['offset']) : 0;
$sleep = isset($options['sleep']) ? intval($options['sleep']) : 0;
$batchSize = isset($options['batch-size']) ? intval($options['batch-size']) : $this->options['batch_size'];
- $stopOnError = isset($options['no-stop-on-error']) ? empty($options['no-stop-on-error']) : $this->options['stop_on_error'];
+ $ignoreErrors = isset($options['ignore-errors']) ? $options['ignore-errors'] : $this->options['ignore_errors'];
for (; $offset < $nbObjects; $offset += $batchSize) {
if ($loggerClosure) {
@@ -48,7 +48,7 @@ abstract class AbstractProvider extends BaseAbstractProvider
}
$objects = $this->fetchSlice($queryBuilder, $batchSize, $offset);
- if (!$stopOnError) {
+ if (!$ignoreErrors) {
$this->objectPersister->insertMany($objects);
} else {
try {
diff --git a/Tests/Doctrine/AbstractProviderTest.php b/Tests/Doctrine/AbstractProviderTest.php
index a3836bd..2492eed 100644
--- a/Tests/Doctrine/AbstractProviderTest.php
+++ b/Tests/Doctrine/AbstractProviderTest.php
@@ -154,7 +154,9 @@ class AbstractProviderTest extends \PHPUnit_Framework_TestCase
->method('insertMany')
->will($this->throwException($this->getMockBulkResponseException()));
- $provider->populate(null, array('no-stop-on-error' => true));
+ $this->setExpectedException('Elastica\Exception\Bulk\ResponseException');
+
+ $provider->populate(null, array('ignore-errors' => false));
}
/**
From 44180793fcef2b15671d2d75364c69154dc6e447 Mon Sep 17 00:00:00 2001
From: Karel Souffriau
Date: Wed, 19 Feb 2014 12:29:51 +0100
Subject: [PATCH 160/447] Add changelog file for 3.0
---
CHANGELOG-3.0.md | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
create mode 100644 CHANGELOG-3.0.md
diff --git a/CHANGELOG-3.0.md b/CHANGELOG-3.0.md
new file mode 100644
index 0000000..534a25e
--- /dev/null
+++ b/CHANGELOG-3.0.md
@@ -0,0 +1,17 @@
+CHANGELOG for 3.0.x
+===================
+
+This changelog references the relevant changes (bug and security fixes) done
+in 3.0 minor versions.
+
+To get the diff for a specific change, go to
+https://github.com/FriendsOfSymfony/FOSElasticaBundle/commit/XXX where XXX is
+the commit hash. To get the diff between two versions, go to
+https://github.com/FriendsOfSymfony/FOSElasticaBundle/compare/v3.0.0...v3.0.1
+
+To generate a changelog summary since the last version, run
+`git log --no-merges --oneline v3.0.0...3.0.x`
+
+* 3.0.0-ALPHA2 (2014-xx-xx)
+
+ * 41bf07e: Renamed the `no-stop-on-error` option in PopulateCommand to `ignore-errors`
From 63cca11a0b0a0a89f368d71a5afcb3944800d2eb Mon Sep 17 00:00:00 2001
From: Karel Souffriau
Date: Wed, 19 Feb 2014 12:43:44 +0100
Subject: [PATCH 161/447] Tweak: use hasOption() in PopulateCommand instead of
checking for booleans
---
Command/PopulateCommand.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Command/PopulateCommand.php b/Command/PopulateCommand.php
index b13ddc3..7d8a46e 100644
--- a/Command/PopulateCommand.php
+++ b/Command/PopulateCommand.php
@@ -67,7 +67,7 @@ class PopulateCommand extends ContainerAwareCommand
{
$index = $input->getOption('index');
$type = $input->getOption('type');
- $reset = $input->getOption('no-reset') ? false : true;
+ $reset = $input->hasOption('no-reset');
$options = $input->getOptions();
$options['ignore-errors'] = $input->hasOption('ignore-errors');
From 891dd51abebcdeaaa7ac4de017a8ef0a5868fa42 Mon Sep 17 00:00:00 2001
From: Karel Souffriau
Date: Wed, 19 Feb 2014 12:50:48 +0100
Subject: [PATCH 162/447] Fixed bug made in #479
---
Command/PopulateCommand.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Command/PopulateCommand.php b/Command/PopulateCommand.php
index 7d8a46e..afed5ed 100644
--- a/Command/PopulateCommand.php
+++ b/Command/PopulateCommand.php
@@ -67,7 +67,7 @@ class PopulateCommand extends ContainerAwareCommand
{
$index = $input->getOption('index');
$type = $input->getOption('type');
- $reset = $input->hasOption('no-reset');
+ $reset = !$input->hasOption('no-reset');
$options = $input->getOptions();
$options['ignore-errors'] = $input->hasOption('ignore-errors');
From 1c74f61b4ef5cf1b2d1c9b83c5814f173d7edddf Mon Sep 17 00:00:00 2001
From: Karel Souffriau
Date: Wed, 19 Feb 2014 12:58:02 +0100
Subject: [PATCH 163/447] AbstractProvider cleanup
---
Provider/AbstractProvider.php | 23 ++++++++++++++++++-----
1 file changed, 18 insertions(+), 5 deletions(-)
diff --git a/Provider/AbstractProvider.php b/Provider/AbstractProvider.php
index 8f5ad60..2761a25 100644
--- a/Provider/AbstractProvider.php
+++ b/Provider/AbstractProvider.php
@@ -4,10 +4,24 @@ namespace FOS\ElasticaBundle\Provider;
use FOS\ElasticaBundle\Persister\ObjectPersisterInterface;
+/**
+ * AbstractProvider
+ */
abstract class AbstractProvider implements ProviderInterface
{
- protected $objectClass;
+ /**
+ * @var ObjectPersisterInterface
+ */
protected $objectPersister;
+
+ /**
+ * @var string
+ */
+ protected $objectClass;
+
+ /**
+ * @var array
+ */
protected $options;
/**
@@ -34,10 +48,9 @@ abstract class AbstractProvider implements ProviderInterface
*/
protected function getMemoryUsage()
{
- $memory = round(memory_get_usage() / (1024*1024),0); // to get usage in Mo
- $memoryMax = round(memory_get_peak_usage() / (1024*1024)); // to get max usage in Mo
- $message = '(RAM : current='.$memory.'Mo peak='.$memoryMax.'Mo)';
+ $memory = round(memory_get_usage() / (1024 * 1024)); // to get usage in Mo
+ $memoryMax = round(memory_get_peak_usage() / (1024 * 1024)); // to get max usage in Mo
- return $message;
+ return sprintf('(RAM : current=%uMo peak=%uMo)', $memory, $memoryMax);
}
}
From 6f8b3a5a0f028edfb99ad714b0c448c05c36ca00 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Fri, 21 Feb 2014 08:58:43 +1100
Subject: [PATCH 164/447] Fix populate command option
---
Command/PopulateCommand.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Command/PopulateCommand.php b/Command/PopulateCommand.php
index afed5ed..a67df94 100644
--- a/Command/PopulateCommand.php
+++ b/Command/PopulateCommand.php
@@ -67,7 +67,7 @@ class PopulateCommand extends ContainerAwareCommand
{
$index = $input->getOption('index');
$type = $input->getOption('type');
- $reset = !$input->hasOption('no-reset');
+ $reset = !$input->getOption('no-reset');
$options = $input->getOptions();
$options['ignore-errors'] = $input->hasOption('ignore-errors');
From eecdd3474a2ddb2b46dc98fffc4b4bb641dfaed6 Mon Sep 17 00:00:00 2001
From: Matteo Galli
Date: Fri, 21 Feb 2014 16:47:42 +0100
Subject: [PATCH 165/447] Fixes #459
---
DependencyInjection/FOSElasticaExtension.php | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 52070fd..96e1fdf 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -4,6 +4,7 @@ namespace FOS\ElasticaBundle\DependencyInjection;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
+use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
@@ -198,6 +199,10 @@ class FOSElasticaExtension extends Extension
if (isset($type['serializer']['version'])) {
$callbackDef->addMethodCall('setVersion', array($type['serializer']['version']));
}
+ $callbackClassImplementedInterfaces = class_implements($this->serializerConfig['callback_class']); // PHP < 5.4 friendly
+ if (isset($callbackClassImplementedInterfaces['Symfony\Component\DependencyInjection\ContainerAwareInterface'])) {
+ $callbackDef->addMethodCall('setContainer', array(new Reference('service_container')));
+ }
$container->setDefinition($callbackId, $callbackDef);
From 2b04f6cf34807854226794ff78dd3f4f207f73ed Mon Sep 17 00:00:00 2001
From: Karel Souffriau
Date: Tue, 25 Feb 2014 11:05:26 +0100
Subject: [PATCH 166/447] ElasticaLogger cleanup
---
Logger/ElasticaLogger.php | 28 +++++++++++++++++++---------
1 file changed, 19 insertions(+), 9 deletions(-)
diff --git a/Logger/ElasticaLogger.php b/Logger/ElasticaLogger.php
index 0e0a9c0..5b1269f 100644
--- a/Logger/ElasticaLogger.php
+++ b/Logger/ElasticaLogger.php
@@ -14,32 +14,42 @@ use Psr\Log\LoggerInterface;
*/
class ElasticaLogger implements LoggerInterface
{
+ /**
+ * @var LoggerInterface
+ */
protected $logger;
- protected $queries;
+
+ /**
+ * @var array
+ */
+ protected $queries = array();
+
+ /**
+ * @var boolean
+ */
protected $debug;
/**
* Constructor.
*
* @param LoggerInterface|null $logger The Symfony logger
- * @param bool $debug
+ * @param boolean $debug
*/
public function __construct(LoggerInterface $logger = null, $debug = false)
{
$this->logger = $logger;
- $this->queries = array();
$this->debug = $debug;
}
/**
* Logs a query.
*
- * @param string $path Path to call
- * @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
- * @param array $query arguments
+ * @param string $path Path to call
+ * @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
+ * @param array $query Arguments
*/
public function logQuery($path, $method, $data, $time, $connection = array(), $query = array())
{
From 418b9d72cec839d1b5f2dcb73cbd83bdd276bdbe Mon Sep 17 00:00:00 2001
From: tgallice
Date: Tue, 4 Mar 2014 17:54:49 +0100
Subject: [PATCH 167/447] Rework configuration validation to fix #461
---
DependencyInjection/Configuration.php | 4 ++--
.../DependencyInjection/ConfigurationTest.php | 18 ++++++++++++++++++
2 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 107744d..4488bf2 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -103,8 +103,8 @@ class Configuration implements ConfigurationInterface
->children()
->scalarNode('url')
->validate()
- ->ifTrue(function($v) { return substr($v['url'], -1) !== '/'; })
- ->then(function($v) { return $v['url'].'/'; })
+ ->ifTrue(function($url) { return substr($url, -1) !== '/'; })
+ ->then(function($url) { return $url.'/'; })
->end()
->end()
->scalarNode('host')->end()
diff --git a/Tests/DependencyInjection/ConfigurationTest.php b/Tests/DependencyInjection/ConfigurationTest.php
index 35b2af3..0f0d374 100644
--- a/Tests/DependencyInjection/ConfigurationTest.php
+++ b/Tests/DependencyInjection/ConfigurationTest.php
@@ -3,6 +3,7 @@
namespace FOS\ElasticaBundle\Tests\Resetter\DependencyInjection;
use FOS\ElasticaBundle\DependencyInjection\Configuration;
+use Symfony\Component\Config\Definition\Processor;
/**
* ConfigurationTest
@@ -85,4 +86,21 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
$this->assertInstanceOf('Symfony\Component\Config\Definition\ScalarNode', $mapping['index']);
$this->assertNull($mapping['index']->getDefaultValue());
}
+
+ public function testSlashIsAddedAtTheEndOfServerUrl()
+ {
+ $config = array(
+ 'clients' => array(
+ 'default' => array(
+ 'url' => 'http://www.github.com',
+ ),
+ ),
+ );
+
+ $processor = new Processor();
+
+ $configuration = $processor->processConfiguration($this->configuration, array($config));
+
+ $this->assertEquals('http://www.github.com/', $configuration['clients']['default']['servers'][0]['url']);
+ }
}
From a1f7449efc7e8190726812f987e6cba98e4bccbe Mon Sep 17 00:00:00 2001
From: Bastien Jaillot
Date: Wed, 5 Mar 2014 15:59:38 +0100
Subject: [PATCH 168/447] [doc] inform about the override of Elastica logger
Add a documentation related to this change: https://github.com/FriendsOfSymfony/FOSElasticaBundle/pull/395#issuecomment-27729759
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index f78c97f..aaaf0a5 100644
--- a/README.md
+++ b/README.md
@@ -58,6 +58,7 @@ Most of the time, you will need only one.
clients:
default: { host: localhost, port: 9200 }
+A client configuration can also override the Elastica logger to change the used class ```logger: ``` or to simply disable it ```logger: false```. Disabling the logger should be done on production because it can cause a memory leak.
#### Declare a serializer
From 7f53badad545a9e1d5b04a9b02c238fb7a5e30b7 Mon Sep 17 00:00:00 2001
From: Berny Cantos
Date: Thu, 5 Sep 2013 13:45:36 +0200
Subject: [PATCH 169/447] Add support for include_in_{parent,root} for nested
and objects
---
DependencyInjection/Configuration.php | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 4488bf2..adcaf6a 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -415,6 +415,10 @@ class Configuration implements ConfigurationInterface
}
if (isset($nestings['properties'])) {
+ $node
+ ->booleanNode('include_in_parent')->end()
+ ->booleanNode('include_in_root')->end()
+ ;
$this->addNestedFieldConfig($node, $nestings, 'properties');
}
}
From 0116a6ac4f88da2210660c0e6ca55515b0450656 Mon Sep 17 00:00:00 2001
From: Ray
Date: Thu, 6 Mar 2014 12:38:23 -0430
Subject: [PATCH 170/447] Add support for clients requiring basic HTTP
authentication
---
Client.php | 1 +
DependencyInjection/Configuration.php | 8 +++++++-
Logger/ElasticaLogger.php | 2 +-
README.md | 17 +++++++++++++++++
4 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/Client.php b/Client.php
index 7719095..601fc77 100644
--- a/Client.php
+++ b/Client.php
@@ -25,6 +25,7 @@ class Client extends ElasticaClient
'host' => $connection->getHost(),
'port' => $connection->getPort(),
'transport' => $connection->getTransport(),
+ 'headers' => $connection->getConfig('headers'),
);
$this->_logger->logQuery($path, $method, $data, $time, $connection_array, $query);
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 4488bf2..a01d1cb 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -78,7 +78,8 @@ class Configuration implements ConfigurationInterface
array(
'host' => $v['host'],
'port' => $v['port'],
- 'logger' => isset($v['logger']) ? $v['logger'] : null
+ 'logger' => isset($v['logger']) ? $v['logger'] : null,
+ 'headers' => isset($v['headers']) ? $v['headers'] : null,
)
)
);
@@ -114,6 +115,11 @@ class Configuration implements ConfigurationInterface
->treatNullLike('fos_elastica.logger')
->treatTrueLike('fos_elastica.logger')
->end()
+ ->arrayNode('headers')
+ ->children()
+ ->scalarNode('Authorization')->end()
+ ->end()
+ ->end()
->scalarNode('timeout')->end()
->end()
->end()
diff --git a/Logger/ElasticaLogger.php b/Logger/ElasticaLogger.php
index 0e0a9c0..85acf70 100644
--- a/Logger/ElasticaLogger.php
+++ b/Logger/ElasticaLogger.php
@@ -38,7 +38,7 @@ 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
+ * @param array $connection host, port, transport and headers of the query
* @param array $query arguments
*/
public function logQuery($path, $method, $data, $time, $connection = array(), $query = array())
diff --git a/README.md b/README.md
index f78c97f..cd1a1ba 100644
--- a/README.md
+++ b/README.md
@@ -58,6 +58,23 @@ Most of the time, you will need only one.
clients:
default: { host: localhost, port: 9200 }
+If your client requires Basic HTTP Authentication, you can specify an Authorization Header to
+include in HTTP requests. The Authorization Header value is a ``base64`` encoded string that
+includes the authentication username and password, and can be obtained by running the following
+command in your terminal:
+
+ php -r "Print 'Basic ' . base64_encode('your_auth_username' . ':' . 'your_auth_password');"
+
+A sample configuration with Basic HTTP Authentication is:
+
+ #app/config/config.yml
+ fos_elastica:
+ clients:
+ default:
+ host: example.com
+ port: 80
+ headers:
+ Authorization: "Basic jdumrGK7rY9TMuQOPng7GZycmxyMHNoir=="
#### Declare a serializer
From fe871c5ac48d2be18a2efef46cd2b14ca001fe1a Mon Sep 17 00:00:00 2001
From: Miha Vrhovnik
Date: Tue, 11 Mar 2014 14:50:00 +0100
Subject: [PATCH 171/447] Fix wrong annotation
---
Paginator/RawPaginatorAdapter.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Paginator/RawPaginatorAdapter.php b/Paginator/RawPaginatorAdapter.php
index e99746f..b74a9e4 100644
--- a/Paginator/RawPaginatorAdapter.php
+++ b/Paginator/RawPaginatorAdapter.php
@@ -33,7 +33,7 @@ class RawPaginatorAdapter implements PaginatorAdapterInterface
private $totalHits;
/**
- * @array for the facets
+ * @var array for the facets
*/
private $facets;
From 726892c586949b8cf13ccca7fa7c1f3c3ca43f2d Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Thu, 13 Mar 2014 10:43:35 +0100
Subject: [PATCH 172/447] Ignore TypeMissingException when resetting a single
type. This allows to create new types without having to recreate the whole
index.
---
Resetter.php | 9 ++++++++-
Tests/ResetterTest.php | 29 +++++++++++++++++++++++++++++
2 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/Resetter.php b/Resetter.php
index 69620a2..b22f6a1 100644
--- a/Resetter.php
+++ b/Resetter.php
@@ -2,6 +2,7 @@
namespace FOS\ElasticaBundle;
+use Elastica\Exception\ResponseException;
use Elastica\Type\Mapping;
/**
@@ -59,7 +60,13 @@ class Resetter
}
$type = $indexConfig['index']->getType($typeName);
- $type->delete();
+ try {
+ $type->delete();
+ } catch (ResponseException $e) {
+ if (strpos($e->getMessage(), 'TypeMissingException') !== 0) {
+ throw $e;
+ }
+ }
$mapping = $this->createMapping($indexConfig['config']['mappings'][$typeName]);
$type->setMapping($mapping);
}
diff --git a/Tests/ResetterTest.php b/Tests/ResetterTest.php
index aa0fbcc..b4e5649 100644
--- a/Tests/ResetterTest.php
+++ b/Tests/ResetterTest.php
@@ -2,6 +2,9 @@
namespace FOS\ElasticaBundle\Tests\Resetter;
+use Elastica\Exception\ResponseException;
+use Elastica\Request;
+use Elastica\Response;
use FOS\ElasticaBundle\Resetter;
use Elastica\Type\Mapping;
@@ -130,6 +133,32 @@ class ResetterTest extends \PHPUnit_Framework_TestCase
$resetter->resetIndexType('foo', 'c');
}
+ public function testResetIndexTypeIgnoreTypeMissingException()
+ {
+ $type = $this->getMockElasticaType();
+
+ $this->indexConfigsByName['foo']['index']->expects($this->once())
+ ->method('getType')
+ ->with('a')
+ ->will($this->returnValue($type));
+
+ $type->expects($this->once())
+ ->method('delete')
+ ->will($this->throwException(new ResponseException(
+ new Request(''),
+ new Response(array('error' => 'TypeMissingException[[de_20131022] type[bla] missing]', 'status' => 404)))
+ ));
+
+ $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);
+
+ $resetter = new Resetter($this->indexConfigsByName);
+ $resetter->resetIndexType('foo', 'a');
+ }
+
public function testIndexMappingForParent()
{
$type = $this->getMockElasticaType();
From 2f9896c893063b7142a0ac1d2980e05c9050f2df Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Thu, 13 Mar 2014 10:45:57 +0100
Subject: [PATCH 173/447] Check for TypeMissingException anywhere in exception
message
---
Resetter.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Resetter.php b/Resetter.php
index b22f6a1..863524b 100644
--- a/Resetter.php
+++ b/Resetter.php
@@ -63,7 +63,7 @@ class Resetter
try {
$type->delete();
} catch (ResponseException $e) {
- if (strpos($e->getMessage(), 'TypeMissingException') !== 0) {
+ if (strpos($e->getMessage(), 'TypeMissingException') === false) {
throw $e;
}
}
From cdd6e3af45a7fb9f97b53887416e0b3511763452 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Fri, 14 Mar 2014 08:59:59 +1100
Subject: [PATCH 174/447] Bump elastica version
---
composer.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/composer.json b/composer.json
index 094eba5..e588494 100644
--- a/composer.json
+++ b/composer.json
@@ -16,7 +16,7 @@
"symfony/console": "~2.1",
"symfony/form": "~2.1",
"symfony/property-access": "~2.2",
- "ruflin/elastica": "~0.20",
+ "ruflin/elastica": ">=0.20, <1.1-dev",
"psr/log": "~1.0"
},
"require-dev":{
From 6a26c63b2c5d0d56b9d4346e523b12ce25af6576 Mon Sep 17 00:00:00 2001
From: Piotr Antosik
Date: Fri, 14 Mar 2014 18:41:49 +0100
Subject: [PATCH 175/447] fix some block comment
---
Client.php | 3 +++
FOSElasticaBundle.php | 6 +++++-
Paginator/RawPaginatorAdapter.php | 3 ++-
Paginator/TransformedPaginatorAdapter.php | 5 +++--
Resetter.php | 1 +
5 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/Client.php b/Client.php
index 7719095..ab819f8 100644
--- a/Client.php
+++ b/Client.php
@@ -11,6 +11,9 @@ use FOS\ElasticaBundle\Logger\ElasticaLogger;
*/
class Client extends ElasticaClient
{
+ /**
+ * {@inheritdoc}
+ */
public function request($path, $method = Request::GET, $data = array(), array $query = array())
{
$start = microtime(true);
diff --git a/FOSElasticaBundle.php b/FOSElasticaBundle.php
index 5ac1f2a..44424d3 100644
--- a/FOSElasticaBundle.php
+++ b/FOSElasticaBundle.php
@@ -8,10 +8,14 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\HttpKernel\Bundle\Bundle;
+/**
+ * Bundle.
+ *
+ */
class FOSElasticaBundle extends Bundle
{
/**
- * @see Symfony\Component\HttpKernel\Bundle\Bundle::build()
+ * {@inheritdoc}
*/
public function build(ContainerBuilder $container)
{
diff --git a/Paginator/RawPaginatorAdapter.php b/Paginator/RawPaginatorAdapter.php
index b74a9e4..8bd4ee2 100644
--- a/Paginator/RawPaginatorAdapter.php
+++ b/Paginator/RawPaginatorAdapter.php
@@ -41,7 +41,8 @@ class RawPaginatorAdapter implements PaginatorAdapterInterface
* @see PaginatorAdapterInterface::__construct
*
* @param SearchableInterface $searchable the object to search in
- * @param Query $query the query to search
+ * @param Query $query the query to search
+ * @param array $options
*/
public function __construct(SearchableInterface $searchable, Query $query, array $options = array())
{
diff --git a/Paginator/TransformedPaginatorAdapter.php b/Paginator/TransformedPaginatorAdapter.php
index 10976f7..3b4716f 100644
--- a/Paginator/TransformedPaginatorAdapter.php
+++ b/Paginator/TransformedPaginatorAdapter.php
@@ -14,8 +14,9 @@ class TransformedPaginatorAdapter extends RawPaginatorAdapter
private $transformer;
/**
- * @param SearchableInterface $searchable the object to search in
- * @param Query $query the query to search
+ * @param SearchableInterface $searchable the object to search in
+ * @param Query $query the query to search
+ * @param array $options
* @param ElasticaToModelTransformerInterface $transformer the transformer for fetching the results
*/
public function __construct(SearchableInterface $searchable, Query $query, array $options = array(), ElasticaToModelTransformerInterface $transformer)
diff --git a/Resetter.php b/Resetter.php
index 863524b..c97cd34 100644
--- a/Resetter.php
+++ b/Resetter.php
@@ -50,6 +50,7 @@ class Resetter
* @param string $indexName
* @param string $typeName
* @throws \InvalidArgumentException if no index or type mapping exists for the given names
+ * @throws ResponseException
*/
public function resetIndexType($indexName, $typeName)
{
From dc01b189ed8ecb3670bd205fa2c8940547e60c40 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Mon, 17 Mar 2014 09:26:16 +1100
Subject: [PATCH 176/447] Update CHANGELOG-3.0.md
---
CHANGELOG-3.0.md | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG-3.0.md b/CHANGELOG-3.0.md
index 534a25e..eb3e8c8 100644
--- a/CHANGELOG-3.0.md
+++ b/CHANGELOG-3.0.md
@@ -12,6 +12,14 @@ https://github.com/FriendsOfSymfony/FOSElasticaBundle/compare/v3.0.0...v3.0.1
To generate a changelog summary since the last version, run
`git log --no-merges --oneline v3.0.0...3.0.x`
-* 3.0.0-ALPHA2 (2014-xx-xx)
+* 3.0.0-ALPHA3 (xxxx-xx-xx)
+
+ * #463: allowing hot swappable reindexing
+ * #415: BC BREAK: document indexing occurs in postFlush rather than the pre* events previously.
+
+* 3.0.0-ALPHA2 (2014-03-17)
* 41bf07e: Renamed the `no-stop-on-error` option in PopulateCommand to `ignore-errors`
+ * 418b9d7: Fixed validation of url configuration
+ * 726892c: Ignore TypeMissingException when resetting a single type. This allows to create new types without having to recreate the whole index.
+ * 7f53bad Add support for include_in_{parent,root} for nested and objects
From 7d13823488c414cd42f794c1f3cacb82b6c96542 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Tue, 18 Mar 2014 09:10:44 +1100
Subject: [PATCH 177/447] Bump symfony requirement
---
composer.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/composer.json b/composer.json
index e588494..8f22393 100644
--- a/composer.json
+++ b/composer.json
@@ -12,7 +12,7 @@
],
"require": {
"php": ">=5.3.2",
- "symfony/framework-bundle": "~2.1",
+ "symfony/framework-bundle": "~2.3",
"symfony/console": "~2.1",
"symfony/form": "~2.1",
"symfony/property-access": "~2.2",
From babe20800e6bff5af8bfd0de54bb72175dca0ff4 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Tue, 18 Mar 2014 09:12:11 +1100
Subject: [PATCH 178/447] Updated changelog
---
CHANGELOG-3.0.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGELOG-3.0.md b/CHANGELOG-3.0.md
index eb3e8c8..a80d09d 100644
--- a/CHANGELOG-3.0.md
+++ b/CHANGELOG-3.0.md
@@ -16,6 +16,7 @@ To generate a changelog summary since the last version, run
* #463: allowing hot swappable reindexing
* #415: BC BREAK: document indexing occurs in postFlush rather than the pre* events previously.
+ * 7d13823: Dropped (broken) support for Symfony <2.3
* 3.0.0-ALPHA2 (2014-03-17)
From de70e78b5370f6f9f014351e3169dfb035ed8415 Mon Sep 17 00:00:00 2001
From: rayrigam
Date: Tue, 18 Mar 2014 18:14:03 -0430
Subject: [PATCH 179/447] Update Configuration.php
Updated to support any HTTP request header type in the "headers" section.
---
DependencyInjection/Configuration.php | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index a01d1cb..d629ea6 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -101,6 +101,7 @@ class Configuration implements ConfigurationInterface
->children()
->arrayNode('servers')
->prototype('array')
+ ->fixXmlConfig('header')
->children()
->scalarNode('url')
->validate()
@@ -116,9 +117,8 @@ class Configuration implements ConfigurationInterface
->treatTrueLike('fos_elastica.logger')
->end()
->arrayNode('headers')
- ->children()
- ->scalarNode('Authorization')->end()
- ->end()
+ ->useAttributeAsKey('name')
+ ->prototype('scalar')->end()
->end()
->scalarNode('timeout')->end()
->end()
From 4dc08cd006f3260411d7bb26e74c61ec6268d959 Mon Sep 17 00:00:00 2001
From: Ray
Date: Tue, 18 Mar 2014 20:07:30 -0430
Subject: [PATCH 180/447] Added notice about added support for HTTP headers.
---
CHANGELOG-3.0.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGELOG-3.0.md b/CHANGELOG-3.0.md
index a80d09d..fd2ecd5 100644
--- a/CHANGELOG-3.0.md
+++ b/CHANGELOG-3.0.md
@@ -17,6 +17,7 @@ To generate a changelog summary since the last version, run
* #463: allowing hot swappable reindexing
* #415: BC BREAK: document indexing occurs in postFlush rather than the pre* events previously.
* 7d13823: Dropped (broken) support for Symfony <2.3
+ * #496: Added support for HTTP headers
* 3.0.0-ALPHA2 (2014-03-17)
From 2009f8810911e1999aa8d2966b0c076854258daa Mon Sep 17 00:00:00 2001
From: Peter Mitchell
Date: Wed, 19 Mar 2014 08:40:52 -0400
Subject: [PATCH 181/447] Make fetchSlice compatible with custom repo method
If a user configures query_builder_method for the doctrine provider, and
does not alias the root entity to equal Provider::ENTITY_ALIAS then a
DQL error will occur during index population.
> [Semantical Error] [...] near 'a.id ASC': Error: 'a' is not defined.
Provider::countObjects already handles this by dynamically fetching the
alias with QueryBuilder::getRootAliases, and Provider::fetchSlice should
be doing the same.
nb. "Provider" refers to FOS\ElasticaBundle\Doctrine\ORM\Provider
---
Doctrine/ORM/Provider.php | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/Doctrine/ORM/Provider.php b/Doctrine/ORM/Provider.php
index 3549550..5d0164f 100644
--- a/Doctrine/ORM/Provider.php
+++ b/Doctrine/ORM/Provider.php
@@ -9,7 +9,7 @@ use FOS\ElasticaBundle\Exception\InvalidArgumentTypeException;
class Provider extends AbstractProvider
{
const ENTITY_ALIAS = 'a';
-
+
/**
* @see FOS\ElasticaBundle\Doctrine\AbstractProvider::countObjects()
*/
@@ -50,12 +50,13 @@ class Provider extends AbstractProvider
*/
$orderBy = $queryBuilder->getDQLPart('orderBy');
if (empty($orderBy)) {
+ $rootAliases = $queryBuilder->getRootAliases();
$identifierFieldNames = $this->managerRegistry
->getManagerForClass($this->objectClass)
->getClassMetadata($this->objectClass)
->getIdentifierFieldNames();
foreach ($identifierFieldNames as $fieldName) {
- $queryBuilder->addOrderBy(static::ENTITY_ALIAS.'.'.$fieldName);
+ $queryBuilder->addOrderBy($rootAliases[0].'.'.$fieldName);
}
}
From 455ff9e0f7dea27c45570859218211a45a9fe0ea Mon Sep 17 00:00:00 2001
From: Joris van de Sande
Date: Mon, 24 Mar 2014 13:13:57 +0100
Subject: [PATCH 182/447] Unset fields if no nested fields are defined
---
DependencyInjection/Configuration.php | 4 +++
.../DependencyInjection/ConfigurationTest.php | 30 +++++++++++++++++++
2 files changed, 34 insertions(+)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 0445748..40b26c6 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -334,6 +334,10 @@ class Configuration implements ConfigurationInterface
$childrenNode = $node
->useAttributeAsKey('name')
->prototype('array')
+ ->validate()
+ ->ifTrue(function($v) { return isset($v['fields']) && empty($v['fields']); })
+ ->then(function($v) { unset($v['fields']); return $v; })
+ ->end()
->treatNullLike(array())
->addDefaultsIfNotSet()
->children();
diff --git a/Tests/DependencyInjection/ConfigurationTest.php b/Tests/DependencyInjection/ConfigurationTest.php
index 0f0d374..93143ec 100644
--- a/Tests/DependencyInjection/ConfigurationTest.php
+++ b/Tests/DependencyInjection/ConfigurationTest.php
@@ -103,4 +103,34 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('http://www.github.com/', $configuration['clients']['default']['servers'][0]['url']);
}
+
+ public function testEmptyFieldsIndexIsUnset()
+ {
+ $config = array(
+ 'indexes' => array(
+ 'test' => array(
+ 'types' => array(
+ 'test' => array(
+ 'mappings' => array(
+ 'title' => array(
+ 'type' => 'string',
+ 'fields' => array(
+ 'autocomplete' => null
+ )
+ ),
+ 'content' => null
+ )
+ )
+ )
+ )
+ )
+ );
+
+ $processor = new Processor();
+
+ $configuration = $processor->processConfiguration(new Configuration(array($config)), array($config));
+
+ $this->assertArrayNotHasKey('fields', $configuration['indexes']['test']['types']['test']['mappings']['content']);
+ $this->assertArrayHasKey('fields', $configuration['indexes']['test']['types']['test']['mappings']['title']);
+ }
}
From 720917f609381921db52622a9796b2c13a84647a Mon Sep 17 00:00:00 2001
From: nurikabe
Date: Mon, 24 Mar 2014 11:16:31 -0400
Subject: [PATCH 183/447] Clone entities on delete to preserve ids
---
Doctrine/Listener.php | 7 +++++--
Tests/Doctrine/AbstractListenerTest.php | 8 ++++++--
2 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/Doctrine/Listener.php b/Doctrine/Listener.php
index c254513..43ac744 100644
--- a/Doctrine/Listener.php
+++ b/Doctrine/Listener.php
@@ -195,17 +195,20 @@ class Listener implements EventSubscriber
$this->scheduledForUpdate[] = $entity;
} else {
// Delete if no longer indexable
- $this->scheduledForDeletion[] = $entity;
+ $this->scheduledForDeletion[] = clone $entity;
}
}
}
+ /**
+ * Delete objects preRemove instead of postRemove so that we have access to the id
+ */
public function preRemove(EventArgs $eventArgs)
{
$entity = $eventArgs->getEntity();
if ($entity instanceof $this->objectClass) {
- $this->scheduledForDeletion[] = $entity;
+ $this->scheduledForDeletion[] = clone $entity;
}
}
diff --git a/Tests/Doctrine/AbstractListenerTest.php b/Tests/Doctrine/AbstractListenerTest.php
index a9eff66..8e49f24 100644
--- a/Tests/Doctrine/AbstractListenerTest.php
+++ b/Tests/Doctrine/AbstractListenerTest.php
@@ -133,7 +133,9 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
$listener = $this->createListener($persister, get_class($entity), array());
$listener->preRemove($eventArgs);
- $this->assertEquals($entity, current($listener->scheduledForDeletion));
+ $scheduledClone = current($listener->scheduledForDeletion);
+ $this->assertEquals($entity, $scheduledClone);
+ $this->assertNotSame($entity, $scheduledClone);
$persister->expects($this->once())
->method('deleteMany')
@@ -164,7 +166,9 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
$listener = $this->createListener($persister, get_class($entity), array(), 'identifier');
$listener->preRemove($eventArgs);
- $this->assertEquals($entity, current($listener->scheduledForDeletion));
+ $scheduledClone = current($listener->scheduledForDeletion);
+ $this->assertEquals($entity, $scheduledClone);
+ $this->assertNotSame($entity, $scheduledClone);
$persister->expects($this->once())
->method('deleteMany')
From 361d80a720e27ef63bc5bd6a188435a7a6b6102c Mon Sep 17 00:00:00 2001
From: nurikabe
Date: Mon, 24 Mar 2014 11:18:55 -0400
Subject: [PATCH 184/447] Prevent division by zero error
---
Doctrine/AbstractProvider.php | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Doctrine/AbstractProvider.php b/Doctrine/AbstractProvider.php
index 9d1575c..3fafe50 100644
--- a/Doctrine/AbstractProvider.php
+++ b/Doctrine/AbstractProvider.php
@@ -70,7 +70,8 @@ abstract class AbstractProvider extends BaseAbstractProvider
$stepNbObjects = count($objects);
$stepCount = $stepNbObjects + $offset;
$percentComplete = 100 * $stepCount / $nbObjects;
- $objectsPerSecond = $stepNbObjects / (microtime(true) - $stepStartTime);
+ $timeDifference = microtime(true) - $stepStartTime;
+ $objectsPerSecond = $timeDifference ? ($stepNbObjects / $timeDifference) : $stepNbObjects;
$loggerClosure(sprintf('%0.1f%% (%d/%d), %d objects/s %s', $percentComplete, $stepCount, $nbObjects, $objectsPerSecond, $this->getMemoryUsage()));
}
}
From eb7758605e9255b4d8e8a90567c52ae50f15f617 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Wed, 26 Mar 2014 10:07:50 +1100
Subject: [PATCH 185/447] Documentation updates
---
README.md | 6 +++-
.../cookbook/elastica-client-http-headers.md | 18 ++++++++++
Resources/doc/cookbook/logging.md | 36 +++++++++++++++++++
Resources/doc/index.md | 8 +++--
Resources/doc/setup.md | 15 ++++----
Resources/doc/types.md | 16 ++++++++-
6 files changed, 87 insertions(+), 12 deletions(-)
create mode 100644 Resources/doc/cookbook/elastica-client-http-headers.md
create mode 100644 Resources/doc/cookbook/logging.md
diff --git a/README.md b/README.md
index ce5afab..8267e57 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,11 @@ FOSElasticaBundle
This bundle provides integration with [ElasticSearch](http://www.elasticsearch.org) and [Elastica](https://github.com/ruflin/Elastica) with
Symfony2. Features include:
-- Features...
+- Integrates the Elastica library into a Symfony2 environment
+- Automatically generate mappings using a serializer
+- Listeners for Doctrine events for automatic indexing
+
+> **Note** Propel support is limited and contributions fixing issues are welcome!
[](http://travis-ci.org/FriendsOfSymfony/FOSElasticaBundle) [](https://packagist.org/packages/FriendsOfSymfony/elastica-bundle) [](https://packagist.org/packages/FriendsOfSymfony/elastica-bundle)
diff --git a/Resources/doc/cookbook/elastica-client-http-headers.md b/Resources/doc/cookbook/elastica-client-http-headers.md
new file mode 100644
index 0000000..781d639
--- /dev/null
+++ b/Resources/doc/cookbook/elastica-client-http-headers.md
@@ -0,0 +1,18 @@
+Setting HTTP Headers on the Elastica Client
+===========================================
+
+It may be necessary to set HTTP headers on the Elastica client, for example an
+Authorization header.
+
+They can be set using the headers configuration key:
+
+```yaml
+# app/config/config.yml
+fos_elastica:
+ clients:
+ default:
+ host: example.com
+ port: 80
+ headers:
+ Authorization: "Basic jdumrGK7rY9TMuQOPng7GZycmxyMHNoir=="
+```
diff --git a/Resources/doc/cookbook/logging.md b/Resources/doc/cookbook/logging.md
new file mode 100644
index 0000000..b2d2e6c
--- /dev/null
+++ b/Resources/doc/cookbook/logging.md
@@ -0,0 +1,36 @@
+Logging and its performance considerations
+==========================================
+
+By default, FOSElasticaBundle sets a logger against each Elastica client configured and
+logs all information sent to and received from Elasticsearch. This can lead to large
+memory usage during population or reindexing of an index.
+
+FOSElasticaBundle provides an option to disable a logger by setting the property on the
+client configuration to false:
+
+```yaml
+# app/config/config.yml
+fos_elastica:
+ clients:
+ default:
+ host: example.com
+ logger: false
+```
+
+It may be desirable to set this configuration property to `%kernel.debug%`, which would
+only switch the logging capabilities of FOSElasticaBundle on when debugging is enabled.
+
+Custom Logger Service
+---------------------
+
+It is also possible to specify a custom logger instance to be injected into each client by
+specifying the service id of the logger you wish to use.
+
+```yaml
+# app/config/config.yml
+fos_elastica:
+ clients:
+ default:
+ host: example.com
+ logger: 'acme.custom.logger'
+```
diff --git a/Resources/doc/index.md b/Resources/doc/index.md
index d9b6c65..1bc093e 100644
--- a/Resources/doc/index.md
+++ b/Resources/doc/index.md
@@ -1,7 +1,8 @@
FOSElasticaBundle Documentation
===============================
-Available documentation for FOSElasticaBundle:
+Available documentation for FOSElasticaBundle
+---------------------------------------------
* [Setup](setup.md)
* [Usage](usage.md)
@@ -9,6 +10,9 @@ Available documentation for FOSElasticaBundle:
* [Types](types.md)
Cookbook Entries
+----------------
* [Custom Repositories](cookbook/custom-repositories.md)
-* [Suppressing server errors](cookbook/suppress-server-errors.md)
\ No newline at end of file
+* [HTTP Headers for Elastica](cookbook/elastica-client-http-headers.md)
+* Performance - [Logging](cookbook/logging.md)
+* [Suppressing server errors](cookbook/suppress-server-errors.md)
diff --git a/Resources/doc/setup.md b/Resources/doc/setup.md
index 7ae4018..e60c372 100644
--- a/Resources/doc/setup.md
+++ b/Resources/doc/setup.md
@@ -38,7 +38,7 @@ C) Basic Bundle Configuration
-----------------------------
The basic minimal configuration for FOSElasticaBundle is one client with one Elasticsearch
-index. In almost all cases, an application will only need a single index. An index can
+index. In almost all cases, an application will only need a single index. An index can
be considered comparable to a Doctrine Entity Manager, where the index will hold multiple
type definitions.
@@ -51,7 +51,7 @@ fos_elastica:
search: ~
```
-In this example, an Elastica index (an instance of `Elastica\Index`) is available as a
+In this example, an Elastica index (an instance of `Elastica\Index`) is available as a
service with the key `fos_elastica.index.search`.
If the Elasticsearch index name needs to be different to the service name in your
@@ -71,7 +71,7 @@ index of search_dev.
D) Defining index types
-----------------------
-By default, FOSElasticaBundle requires each type that is to be indexed to be mapped.
+By default, FOSElasticaBundle requires each type that is to be indexed to be mapped.
It is possible to use a serializer to avoid this requirement. To use a serializer, see
the [serializer documentation](serializer.md)
@@ -95,12 +95,10 @@ Each defined type is made available as a service, and in this case the service k
`fos_elastica.index.search.user` and is an instance of `Elastica\Type`.
FOSElasticaBundle requires a provider for each type that will notify when an object
-that maps to a type has been modified. The bundle ships with support for Doctrine and
+that maps to a type has been modified. The bundle ships with support for Doctrine and
Propel objects.
-Below is an example for the Doctrine ORM. For additional information regarding
-integration with Doctrine or Propel or how to create a custom provider, see
-[type-providers.md].
+Below is an example for the Doctrine ORM.
```yaml
user:
@@ -118,6 +116,7 @@ integration with Doctrine or Propel or how to create a custom provider, see
provider: ~
listener: ~
finder: ~
+ immediate: ~
```
There are a significant number of options available for types, that can be
@@ -127,7 +126,7 @@ E) Populating the Elasticsearch index
-------------------------------------
When using the providers and listeners that come with the bundle, any new or modified
-object will be indexed automatically. In some cases, where the database is modified
+object will be indexed automatically. In some cases, where the database is modified
externally, the Elasticsearch index must be updated manually. This can be achieved by
running the console command:
diff --git a/Resources/doc/types.md b/Resources/doc/types.md
index a66971f..38fa045 100644
--- a/Resources/doc/types.md
+++ b/Resources/doc/types.md
@@ -261,4 +261,18 @@ As you might expect, new entities will only be indexed if the callback_class ret
index depending on whether the callback_class returns `true` or `false`, respectively.
The delete listener disregards the callback_class.
-> **Propel** doesn't support this feature yet.
\ No newline at end of file
+> **Propel** doesn't support this feature yet.
+
+Flushing Method
+---------------
+
+FOSElasticaBundle, since 3.0.0 performs its indexing in the postFlush Doctrine event
+instead of prePersist and preUpdate which means that indexing will only occur when there
+has been a successful flush. This new default makes more sense but in the instance where
+you want to perform indexing before the flush is confirmed you may set the `immediate`
+option on a type persistence configuration to false.
+
+```yaml
+ persistence:
+ immediate: false
+```
From e25a5420a59f44ae88ea77d94ca91e02f3a29a9c Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Wed, 26 Mar 2014 12:36:02 +1100
Subject: [PATCH 186/447] Logger enabled with debugging
---
DependencyInjection/Configuration.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 5049c7d..348fd74 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -121,7 +121,7 @@ class Configuration implements ConfigurationInterface
->scalarNode('host')->end()
->scalarNode('port')->end()
->scalarNode('logger')
- ->defaultValue('fos_elastica.logger')
+ ->defaultValue('%kernel.debug%')
->treatNullLike('fos_elastica.logger')
->treatTrueLike('fos_elastica.logger')
->end()
From 9f27c1dade8b6ceb2d04763cdf5afa0eb708a257 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Wed, 26 Mar 2014 12:36:36 +1100
Subject: [PATCH 187/447] Update changelog
---
CHANGELOG-3.0.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGELOG-3.0.md b/CHANGELOG-3.0.md
index fd2ecd5..abd05cd 100644
--- a/CHANGELOG-3.0.md
+++ b/CHANGELOG-3.0.md
@@ -14,6 +14,7 @@ To generate a changelog summary since the last version, run
* 3.0.0-ALPHA3 (xxxx-xx-xx)
+ * a9c4c93: Logger is now only enabled in debug mode by default
* #463: allowing hot swappable reindexing
* #415: BC BREAK: document indexing occurs in postFlush rather than the pre* events previously.
* 7d13823: Dropped (broken) support for Symfony <2.3
From 38b4074745ad5c1a58882523857b0aa8ffd46ad0 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Wed, 26 Mar 2014 12:40:27 +1100
Subject: [PATCH 188/447] Update logger documentation based on configuration
change
---
Resources/doc/cookbook/logging.md | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/Resources/doc/cookbook/logging.md b/Resources/doc/cookbook/logging.md
index b2d2e6c..726e77e 100644
--- a/Resources/doc/cookbook/logging.md
+++ b/Resources/doc/cookbook/logging.md
@@ -5,8 +5,10 @@ By default, FOSElasticaBundle sets a logger against each Elastica client configu
logs all information sent to and received from Elasticsearch. This can lead to large
memory usage during population or reindexing of an index.
-FOSElasticaBundle provides an option to disable a logger by setting the property on the
-client configuration to false:
+By default FOSElasticaBundle will only enable a logger when debug mode is enabled, meaning
+in a production environment there wont be a logger enabled. To enable a logger anyway, you
+can set the logger property of a client configuration to true or a service id of a logging
+service you wish to use.
```yaml
# app/config/config.yml
@@ -14,12 +16,9 @@ fos_elastica:
clients:
default:
host: example.com
- logger: false
+ logger: true
```
-It may be desirable to set this configuration property to `%kernel.debug%`, which would
-only switch the logging capabilities of FOSElasticaBundle on when debugging is enabled.
-
Custom Logger Service
---------------------
From a81a6305209df01d43bf32159f6ad4d7334acfea Mon Sep 17 00:00:00 2001
From: Joakim Friberg
Date: Thu, 27 Mar 2014 16:33:20 +0100
Subject: [PATCH 189/447] Corrected bundle class name in install instructions
---
Resources/doc/setup.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Resources/doc/setup.md b/Resources/doc/setup.md
index e60c372..4ae40af 100644
--- a/Resources/doc/setup.md
+++ b/Resources/doc/setup.md
@@ -29,7 +29,7 @@ public function registerBundles()
{
$bundles = array(
// ...
- new FOS\RestBundle\FOSRestBundle(),
+ new FOS\ElasticaBundle\FOSElasticaBundle(),
);
}
```
From 0de48d2190b03583703c3084a1a8296e4d8cb17b Mon Sep 17 00:00:00 2001
From: nurikabe
Date: Sat, 29 Mar 2014 18:36:06 -0400
Subject: [PATCH 190/447] Use identifiers for bulk delete rather than cloning
objects
---
Doctrine/Listener.php | 41 ++++++++++++++++++++++---
Persister/ObjectPersister.php | 10 ++++++
Persister/ObjectPersisterInterface.php | 7 +++++
Tests/Doctrine/AbstractListenerTest.php | 23 ++++++--------
4 files changed, 63 insertions(+), 18 deletions(-)
diff --git a/Doctrine/Listener.php b/Doctrine/Listener.php
index 43ac744..b6217a6 100644
--- a/Doctrine/Listener.php
+++ b/Doctrine/Listener.php
@@ -9,7 +9,12 @@ use FOS\ElasticaBundle\Persister\ObjectPersister;
use Symfony\Component\ExpressionLanguage\Expression;
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
use Symfony\Component\ExpressionLanguage\SyntaxError;
+use Symfony\Component\PropertyAccess\PropertyAccess;
+/**
+ * Automatically update ElasticSearch based on changes to the Doctrine source
+ * data. One listener is generated for each Doctrine entity / ElasticSearch type.
+ */
class Listener implements EventSubscriber
{
/**
@@ -48,10 +53,14 @@ class Listener implements EventSubscriber
protected $isIndexableCallback;
/**
- * Objects scheduled for insertion, replacement, or removal
+ * Objects scheduled for insertion and replacement
*/
public $scheduledForInsertion = array();
public $scheduledForUpdate = array();
+
+ /**
+ * IDs of objects scheduled for removal
+ */
public $scheduledForDeletion = array();
/**
@@ -61,6 +70,13 @@ class Listener implements EventSubscriber
*/
protected $expressionLanguage;
+ /**
+ * PropertyAccessor instance
+ *
+ * @var PropertyAccessorInterface
+ */
+ protected $propertyAccessor;
+
/**
* Constructor.
*
@@ -75,6 +91,8 @@ class Listener implements EventSubscriber
$this->objectClass = $objectClass;
$this->events = $events;
$this->esIdentifierField = $esIdentifierField;
+
+ $this->propertyAccessor = PropertyAccess::createPropertyAccessor();
}
/**
@@ -195,20 +213,21 @@ class Listener implements EventSubscriber
$this->scheduledForUpdate[] = $entity;
} else {
// Delete if no longer indexable
- $this->scheduledForDeletion[] = clone $entity;
+ $this->scheduleForDeletion($entity);
}
}
}
/**
- * Delete objects preRemove instead of postRemove so that we have access to the id
+ * Delete objects preRemove instead of postRemove so that we have access to the id. Because this is called
+ * preRemove, first check that the entity is managed by Doctrine
*/
public function preRemove(EventArgs $eventArgs)
{
$entity = $eventArgs->getEntity();
if ($entity instanceof $this->objectClass) {
- $this->scheduledForDeletion[] = clone $entity;
+ $this->scheduleForDeletion($entity);
}
}
@@ -224,7 +243,7 @@ class Listener implements EventSubscriber
$this->objectPersister->replaceMany($this->scheduledForUpdate);
}
if (count($this->scheduledForDeletion)) {
- $this->objectPersister->deleteMany($this->scheduledForDeletion);
+ $this->objectPersister->deleteManyByIdentifiers($this->scheduledForDeletion);
}
}
@@ -245,4 +264,16 @@ class Listener implements EventSubscriber
{
$this->persistScheduled();
}
+
+ /**
+ * Record the specified identifier to delete. Do not need to entire object.
+ * @param mixed $object
+ * @return mixed
+ */
+ protected function scheduleForDeletion($object)
+ {
+ if ($identifierValue = $this->propertyAccessor->getValue($object, $this->esIdentifierField)) {
+ $this->scheduledForDeletion[] = $identifierValue;
+ }
+ }
}
diff --git a/Persister/ObjectPersister.php b/Persister/ObjectPersister.php
index 3592a78..64cf5db 100644
--- a/Persister/ObjectPersister.php
+++ b/Persister/ObjectPersister.php
@@ -126,6 +126,16 @@ class ObjectPersister implements ObjectPersisterInterface
$this->type->deleteDocuments($documents);
}
+ /**
+ * Bulk deletes records from an array of identifiers
+ *
+ * @param array $identifiers array of domain model object identifiers
+ */
+ public function deleteManyByIdentifiers(array $identifiers)
+ {
+ $this->type->getIndex()->getClient()->deleteIds($identifiers, $this->type->getIndex(), $this->type);
+ }
+
/**
* Transforms an object to an elastica document
*
diff --git a/Persister/ObjectPersisterInterface.php b/Persister/ObjectPersisterInterface.php
index a25aafc..2b4c8ee 100644
--- a/Persister/ObjectPersisterInterface.php
+++ b/Persister/ObjectPersisterInterface.php
@@ -61,4 +61,11 @@ interface ObjectPersisterInterface
* @param array $objects array of domain model objects
*/
function deleteMany(array $objects);
+
+ /**
+ * Bulk deletes records from an array of identifiers
+ *
+ * @param array $identifiers array of domain model object identifiers
+ */
+ public function deleteManyByIdentifiers(array $identifiers);
}
diff --git a/Tests/Doctrine/AbstractListenerTest.php b/Tests/Doctrine/AbstractListenerTest.php
index 8e49f24..ee657f1 100644
--- a/Tests/Doctrine/AbstractListenerTest.php
+++ b/Tests/Doctrine/AbstractListenerTest.php
@@ -100,13 +100,13 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
$listener->postUpdate($eventArgs);
$this->assertEmpty($listener->scheduledForUpdate);
- $this->assertEquals($entity, current($listener->scheduledForDeletion));
+ $this->assertEquals($entity->getId(), current($listener->scheduledForDeletion));
$persister->expects($this->never())
->method('replaceOne');
$persister->expects($this->once())
- ->method('deleteMany')
- ->with(array($entity));
+ ->method('deleteManyByIdentifiers')
+ ->with(array($entity->getId()));
$listener->postFlush($eventArgs);
}
@@ -133,13 +133,11 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
$listener = $this->createListener($persister, get_class($entity), array());
$listener->preRemove($eventArgs);
- $scheduledClone = current($listener->scheduledForDeletion);
- $this->assertEquals($entity, $scheduledClone);
- $this->assertNotSame($entity, $scheduledClone);
+ $this->assertEquals($entity->getId(), current($listener->scheduledForDeletion));
$persister->expects($this->once())
- ->method('deleteMany')
- ->with(array($entity));
+ ->method('deleteManyByIdentifiers')
+ ->with(array($entity->getId()));
$listener->postFlush($eventArgs);
}
@@ -151,6 +149,7 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
$persister = $this->getMockPersister();
$entity = new Listener\Entity(1);
+ $entity->identifier = 'foo';
$eventArgs = $this->createLifecycleEventArgs($entity, $objectManager);
$objectManager->expects($this->any())
@@ -166,13 +165,11 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
$listener = $this->createListener($persister, get_class($entity), array(), 'identifier');
$listener->preRemove($eventArgs);
- $scheduledClone = current($listener->scheduledForDeletion);
- $this->assertEquals($entity, $scheduledClone);
- $this->assertNotSame($entity, $scheduledClone);
+ $this->assertEquals($entity->identifier, current($listener->scheduledForDeletion));
$persister->expects($this->once())
- ->method('deleteMany')
- ->with(array($entity));
+ ->method('deleteManyByIdentifiers')
+ ->with(array($entity->identifier));
$listener->postFlush($eventArgs);
}
From f15ca028596a9226fcff636138533a1a39f39ce5 Mon Sep 17 00:00:00 2001
From: Joseph Bielawski
Date: Mon, 31 Mar 2014 11:59:37 +0200
Subject: [PATCH 191/447] Fix documentation for client overwriting.
---
.../doc/cookbook/suppress-server-errors.md | 33 +++++++++++++++----
1 file changed, 26 insertions(+), 7 deletions(-)
diff --git a/Resources/doc/cookbook/suppress-server-errors.md b/Resources/doc/cookbook/suppress-server-errors.md
index aa74276..d89ffd6 100644
--- a/Resources/doc/cookbook/suppress-server-errors.md
+++ b/Resources/doc/cookbook/suppress-server-errors.md
@@ -1,5 +1,5 @@
Suppressing Server Errors
-========================
+=========================
By default, exceptions from the Elastica client library will propagate through
the bundle's Client class. For instance, if the Elasticsearch server is offline,
@@ -12,25 +12,44 @@ container parameter with a custom class. In the following example, we override
the `Client::request()` method and return the equivalent of an empty search
response if an exception occurred.
-```
+Sample client code:
+-------------------
+
+```php
+
+
+
+
+ Acme\ElasticaBundle\Client
+
+
+
From 588c4e2d025bea489547dcc2e0bc068f4d97919e Mon Sep 17 00:00:00 2001
From: Joris van de Sande
Date: Mon, 31 Mar 2014 12:52:29 +0200
Subject: [PATCH 192/447] Unset nested "fields" for deeper nested configs too
---
DependencyInjection/Configuration.php | 4 ++++
Tests/DependencyInjection/ConfigurationTest.php | 16 +++++++++++++++-
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 348fd74..e77919c 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -458,6 +458,10 @@ class Configuration implements ConfigurationInterface
->arrayNode($property)
->useAttributeAsKey('name')
->prototype('array')
+ ->validate()
+ ->ifTrue(function($v) { return isset($v['fields']) && empty($v['fields']); })
+ ->then(function($v) { unset($v['fields']); return $v; })
+ ->end()
->treatNullLike(array())
->addDefaultsIfNotSet()
->children();
diff --git a/Tests/DependencyInjection/ConfigurationTest.php b/Tests/DependencyInjection/ConfigurationTest.php
index 93143ec..5919ea7 100644
--- a/Tests/DependencyInjection/ConfigurationTest.php
+++ b/Tests/DependencyInjection/ConfigurationTest.php
@@ -118,7 +118,19 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
'autocomplete' => null
)
),
- 'content' => null
+ 'content' => null,
+ 'children' => array(
+ 'type' => 'nested',
+ 'properties' => array(
+ 'title' => array(
+ 'type' => 'string',
+ 'fields' => array(
+ 'autocomplete' => null
+ )
+ ),
+ 'content' => null
+ )
+ )
)
)
)
@@ -132,5 +144,7 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
$this->assertArrayNotHasKey('fields', $configuration['indexes']['test']['types']['test']['mappings']['content']);
$this->assertArrayHasKey('fields', $configuration['indexes']['test']['types']['test']['mappings']['title']);
+ $this->assertArrayNotHasKey('fields', $configuration['indexes']['test']['types']['test']['mappings']['children']['properties']['content']);
+ $this->assertArrayHasKey('fields', $configuration['indexes']['test']['types']['test']['mappings']['children']['properties']['title']);
}
}
From 20810fa4150e1c739ad2c848d81af61b738e76e0 Mon Sep 17 00:00:00 2001
From: baggachipz
Date: Mon, 31 Mar 2014 15:16:32 -0400
Subject: [PATCH 193/447] Upsert-type functionality for existing ORM Entities
This is an attempt to fix the issue: https://github.com/FriendsOfSymfony/FOSElasticaBundle/issues/526
It will cause a significant slowdown in a large batch, but it appears to be the only way to prevent an exception from bubbling up during a normal use case.
---
Persister/ObjectPersister.php | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/Persister/ObjectPersister.php b/Persister/ObjectPersister.php
index 3592a78..aa20561 100644
--- a/Persister/ObjectPersister.php
+++ b/Persister/ObjectPersister.php
@@ -107,7 +107,15 @@ class ObjectPersister implements ObjectPersisterInterface
{
$documents = array();
foreach ($objects as $object) {
- $documents[] = $this->transformToElasticaDocument($object);
+ $document = $this->transformToElasticaDocument($object);
+
+ try {
+ $this->type->getDocument($document->getId());
+ } catch (NotFoundException $e) {
+ $this->type->addDocument($document);
+ }
+
+ $documents[] = $document;
}
$this->type->updateDocuments($documents);
}
@@ -136,4 +144,4 @@ class ObjectPersister implements ObjectPersisterInterface
{
return $this->transformer->transform($object, $this->fields);
}
-}
\ No newline at end of file
+}
From a89856be504b0d87808b188f6cddcc6b0a427887 Mon Sep 17 00:00:00 2001
From: nurikabe
Date: Wed, 2 Apr 2014 07:18:46 -0400
Subject: [PATCH 194/447] Reset / create new index even if the index doesn't
exist
---
Command/PopulateCommand.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Command/PopulateCommand.php b/Command/PopulateCommand.php
index 98834c7..af5fd5d 100644
--- a/Command/PopulateCommand.php
+++ b/Command/PopulateCommand.php
@@ -109,7 +109,7 @@ class PopulateCommand extends ContainerAwareCommand
*/
private function populateIndex(OutputInterface $output, $index, $reset, $options)
{
- if ($reset && $this->indexManager->getIndex($index)->exists()) {
+ if ($reset) {
$output->writeln(sprintf('Resetting %s', $index));
$this->resetter->resetIndex($index);
}
From 1628413e65bcfc4457f8f627de8b836964d1512c Mon Sep 17 00:00:00 2001
From: Josh Worden
Date: Wed, 2 Apr 2014 10:06:24 -0500
Subject: [PATCH 195/447] Added support for getting documents in unified
Doctrine Listener
---
Doctrine/Listener.php | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Doctrine/Listener.php b/Doctrine/Listener.php
index b6217a6..47c3c9a 100644
--- a/Doctrine/Listener.php
+++ b/Doctrine/Listener.php
@@ -197,7 +197,7 @@ class Listener implements EventSubscriber
public function postPersist(EventArgs $eventArgs)
{
- $entity = $eventArgs->getEntity();
+ $entity = (method_exists($eventArgs, 'getEntity')) ? $eventArgs->getEntity() : $eventArgs->getDocument();
if ($entity instanceof $this->objectClass && $this->isObjectIndexable($entity)) {
$this->scheduledForInsertion[] = $entity;
@@ -206,7 +206,7 @@ class Listener implements EventSubscriber
public function postUpdate(EventArgs $eventArgs)
{
- $entity = $eventArgs->getEntity();
+ $entity = (method_exists($eventArgs, 'getEntity')) ? $eventArgs->getEntity() : $eventArgs->getDocument();
if ($entity instanceof $this->objectClass) {
if ($this->isObjectIndexable($entity)) {
@@ -224,7 +224,7 @@ class Listener implements EventSubscriber
*/
public function preRemove(EventArgs $eventArgs)
{
- $entity = $eventArgs->getEntity();
+ $entity = (method_exists($eventArgs, 'getEntity')) ? $eventArgs->getEntity() : $eventArgs->getDocument();
if ($entity instanceof $this->objectClass) {
$this->scheduleForDeletion($entity);
From e74acb1e4fd577a4aa51e166e0f2b9e2e9f06db4 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Thu, 3 Apr 2014 08:00:52 +1100
Subject: [PATCH 196/447] Revert "Avoid index reset error in case of unexistant
index"
This reverts commit a121a777743525f46c65dc29d983c8eb92720664.
---
Command/PopulateCommand.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Command/PopulateCommand.php b/Command/PopulateCommand.php
index 98834c7..af5fd5d 100644
--- a/Command/PopulateCommand.php
+++ b/Command/PopulateCommand.php
@@ -109,7 +109,7 @@ class PopulateCommand extends ContainerAwareCommand
*/
private function populateIndex(OutputInterface $output, $index, $reset, $options)
{
- if ($reset && $this->indexManager->getIndex($index)->exists()) {
+ if ($reset) {
$output->writeln(sprintf('Resetting %s', $index));
$this->resetter->resetIndex($index);
}
From 13c2d10e399317af9b9aa24d55b382befb3830cf Mon Sep 17 00:00:00 2001
From: Patrick Zahnd
Date: Fri, 13 Sep 2013 15:34:59 +0200
Subject: [PATCH 197/447] Added knp paginator sort functionality to
PaginateElasticaQuerySubscriber
---
Paginator/RawPaginatorAdapter.php | 10 +++++
Resources/config/config.xml | 3 ++
.../PaginateElasticaQuerySubscriber.php | 43 +++++++++++++++++++
3 files changed, 56 insertions(+)
diff --git a/Paginator/RawPaginatorAdapter.php b/Paginator/RawPaginatorAdapter.php
index 8bd4ee2..9136bc0 100644
--- a/Paginator/RawPaginatorAdapter.php
+++ b/Paginator/RawPaginatorAdapter.php
@@ -126,4 +126,14 @@ class RawPaginatorAdapter implements PaginatorAdapterInterface
return $this->facets;
}
+
+ /**
+ * Returns the Query
+ *
+ * @return Query the search query
+ */
+ public function getQuery()
+ {
+ return $this->query;
+ }
}
diff --git a/Resources/config/config.xml b/Resources/config/config.xml
index 4419b4a..b9da716 100644
--- a/Resources/config/config.xml
+++ b/Resources/config/config.xml
@@ -86,6 +86,9 @@
+
+
+
diff --git a/Subscriber/PaginateElasticaQuerySubscriber.php b/Subscriber/PaginateElasticaQuerySubscriber.php
index cbe508d..fc775c7 100644
--- a/Subscriber/PaginateElasticaQuerySubscriber.php
+++ b/Subscriber/PaginateElasticaQuerySubscriber.php
@@ -9,9 +9,20 @@ use FOS\ElasticaBundle\Paginator\PartialResultsInterface;
class PaginateElasticaQuerySubscriber implements EventSubscriberInterface
{
+ private $container;
+
+ public function setContainer($container)
+ {
+ $this->container = $container;
+ }
+
public function items(ItemsEvent $event)
{
if ($event->target instanceof PaginatorAdapterInterface) {
+
+ // Add sort to query
+ $this->addPagingSort($event);
+
/** @var $results PartialResultsInterface */
$results = $event->target->getResults($event->getOffset(), $event->getLimit());
@@ -26,6 +37,38 @@ class PaginateElasticaQuerySubscriber implements EventSubscriberInterface
}
}
+ /**
+ * Adds knp paging sort to query
+ *
+ * @param ItemsEvent $event
+ * @return void
+ */
+ protected function addPagingSort(ItemsEvent $event)
+ {
+ $request = $this->container->get('request');
+ $options = $event->options;
+ $sortField = $request->get($options['sortFieldParameterName']);
+
+ if (!empty($sortField)) {
+ // determine sort direction
+ $dir = 'asc';
+ $sortDirection = $request->get($options['sortDirectionParameterName']);
+ if ('desc' === strtolower($sortDirection)) {
+ $dir = 'desc';
+ }
+
+ // check if the requested sort field is in the sort whitelist
+ if (isset($options['sortFieldWhitelist']) && !in_array($sortField, $options['sortFieldWhitelist'])) {
+ throw new \UnexpectedValueException(sprintf('Cannot sort by: [%s] this field is not in whitelist', $sortField));
+ }
+
+ // set sort on active query
+ $event->target->getQuery()->setSort(array(
+ $sortField => array('order' => $dir),
+ ));
+ }
+ }
+
public static function getSubscribedEvents()
{
return array(
From 1bc148569baa3b7ad8ac31211e93c629d5fe7cda Mon Sep 17 00:00:00 2001
From: Piotr Antosik
Date: Mon, 24 Feb 2014 13:47:26 +0100
Subject: [PATCH 198/447] Added knp paginator sort functionality to
PaginateElasticaQuerySubscriber
---
Resources/config/config.xml | 6 +++---
.../PaginateElasticaQuerySubscriber.php | 20 +++++++++----------
2 files changed, 12 insertions(+), 14 deletions(-)
diff --git a/Resources/config/config.xml b/Resources/config/config.xml
index b9da716..1e49590 100644
--- a/Resources/config/config.xml
+++ b/Resources/config/config.xml
@@ -85,10 +85,10 @@
-
-
-
+
+
+
diff --git a/Subscriber/PaginateElasticaQuerySubscriber.php b/Subscriber/PaginateElasticaQuerySubscriber.php
index fc775c7..0b7cfd6 100644
--- a/Subscriber/PaginateElasticaQuerySubscriber.php
+++ b/Subscriber/PaginateElasticaQuerySubscriber.php
@@ -2,6 +2,7 @@
namespace FOS\ElasticaBundle\Subscriber;
+use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Knp\Component\Pager\Event\ItemsEvent;
use FOS\ElasticaBundle\Paginator\PaginatorAdapterInterface;
@@ -9,19 +10,18 @@ use FOS\ElasticaBundle\Paginator\PartialResultsInterface;
class PaginateElasticaQuerySubscriber implements EventSubscriberInterface
{
- private $container;
+ private $request;
- public function setContainer($container)
+ public function setRequest(Request $request = null)
{
- $this->container = $container;
+ $this->request = $request;
}
public function items(ItemsEvent $event)
{
if ($event->target instanceof PaginatorAdapterInterface) {
-
// Add sort to query
- $this->addPagingSort($event);
+ $this->setSorting($event);
/** @var $results PartialResultsInterface */
$results = $event->target->getResults($event->getOffset(), $event->getLimit());
@@ -40,19 +40,17 @@ class PaginateElasticaQuerySubscriber implements EventSubscriberInterface
/**
* Adds knp paging sort to query
*
- * @param ItemsEvent $event
- * @return void
+ * @param ItemsEvent $event
*/
- protected function addPagingSort(ItemsEvent $event)
+ protected function setSorting(ItemsEvent $event)
{
- $request = $this->container->get('request');
$options = $event->options;
- $sortField = $request->get($options['sortFieldParameterName']);
+ $sortField = $this->request->get($options['sortFieldParameterName']);
if (!empty($sortField)) {
// determine sort direction
$dir = 'asc';
- $sortDirection = $request->get($options['sortDirectionParameterName']);
+ $sortDirection = $this->request->get($options['sortDirectionParameterName']);
if ('desc' === strtolower($sortDirection)) {
$dir = 'desc';
}
From b6e2583455e9397b45e25167f527351458e6c410 Mon Sep 17 00:00:00 2001
From: Josh Worden
Date: Fri, 4 Apr 2014 10:47:50 -0500
Subject: [PATCH 199/447] Added getDoctrineObject method to retrieve an entity
or document from a LifecycleEventArgs instance in the unified Listener class
---
Doctrine/Listener.php | 34 +++++++++++++++++++++++++++++++---
1 file changed, 31 insertions(+), 3 deletions(-)
diff --git a/Doctrine/Listener.php b/Doctrine/Listener.php
index 47c3c9a..ad5641e 100644
--- a/Doctrine/Listener.php
+++ b/Doctrine/Listener.php
@@ -179,6 +179,34 @@ class Listener implements EventSubscriber
return strtolower($ref->getShortName());
}
+ /**
+ * Provides unified method for retrieving a doctrine object from an EventArgs instance
+ *
+ * @param EventArgs $eventArgs
+ * @return object Entity | Document
+ * @throws \RuntimeException if no valid getter is found.
+ */
+ private function getDoctrineObject(EventArgs $eventArgs)
+ {
+
+ if (method_exists($eventArgs, 'getObject')) {
+
+ return $eventArgs->getObject();
+
+ } elseif (method_exists($eventArgs, 'getEntity')) {
+
+ return $eventArgs->getEntity();
+
+ } elseif (method_exists($eventArgs, 'getDocument')) {
+
+ return $eventArgs->getDocument();
+
+ }
+
+ throw new \RuntimeException('Unable to retrieve object from EventArgs.');
+
+ }
+
/**
* @return bool|ExpressionLanguage
*/
@@ -197,7 +225,7 @@ class Listener implements EventSubscriber
public function postPersist(EventArgs $eventArgs)
{
- $entity = (method_exists($eventArgs, 'getEntity')) ? $eventArgs->getEntity() : $eventArgs->getDocument();
+ $entity = $this->getDoctrineObject($eventArgs);
if ($entity instanceof $this->objectClass && $this->isObjectIndexable($entity)) {
$this->scheduledForInsertion[] = $entity;
@@ -206,7 +234,7 @@ class Listener implements EventSubscriber
public function postUpdate(EventArgs $eventArgs)
{
- $entity = (method_exists($eventArgs, 'getEntity')) ? $eventArgs->getEntity() : $eventArgs->getDocument();
+ $entity = $this->getDoctrineObject($eventArgs);
if ($entity instanceof $this->objectClass) {
if ($this->isObjectIndexable($entity)) {
@@ -224,7 +252,7 @@ class Listener implements EventSubscriber
*/
public function preRemove(EventArgs $eventArgs)
{
- $entity = (method_exists($eventArgs, 'getEntity')) ? $eventArgs->getEntity() : $eventArgs->getDocument();
+ $entity = $this->getDoctrineObject($eventArgs);
if ($entity instanceof $this->objectClass) {
$this->scheduleForDeletion($entity);
From 6f444f1ce84cf85f51e801ffd70387211238aeba Mon Sep 17 00:00:00 2001
From: Evan Owens
Date: Fri, 4 Apr 2014 15:51:55 -0400
Subject: [PATCH 200/447] Bulk upsert
---
Persister/ObjectPersister.php | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/Persister/ObjectPersister.php b/Persister/ObjectPersister.php
index e1c086d..38541c8 100644
--- a/Persister/ObjectPersister.php
+++ b/Persister/ObjectPersister.php
@@ -99,7 +99,7 @@ class ObjectPersister implements ObjectPersisterInterface
}
/**
- * Bulk updates an array of objects in the type
+ * Bulk update an array of objects in the type. Create document if it does not already exist.
*
* @param array $objects array of domain model objects
*/
@@ -108,13 +108,7 @@ class ObjectPersister implements ObjectPersisterInterface
$documents = array();
foreach ($objects as $object) {
$document = $this->transformToElasticaDocument($object);
-
- try {
- $this->type->getDocument($document->getId());
- } catch (NotFoundException $e) {
- $this->type->addDocument($document);
- }
-
+ $document->setDocAsUpsert(true);
$documents[] = $document;
}
$this->type->updateDocuments($documents);
From 10f6149f8cff0e1162e2eb3c6c5181176fcd604d Mon Sep 17 00:00:00 2001
From: Evan Owens
Date: Sat, 5 Apr 2014 07:04:52 +1000
Subject: [PATCH 201/447] Remove rogue paren
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 8267e57..7909d2b 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@ Documentation
Documentation for FOSElasticaBundle is in `Resources/doc/index.md`
-[Read the documentation for 3.0.x (master))](https://github.com/FriendsOfSymfony/FOSElasticaBundle/blob/master/Resources/doc/index.md)
+[Read the documentation for 3.0.x (master)](https://github.com/FriendsOfSymfony/FOSElasticaBundle/blob/master/Resources/doc/index.md)
[Read the documentation for 2.1.x](https://github.com/FriendsOfSymfony/FOSElasticaBundle/blob/2.1.x/README.md)
From 377b2843baf6f80f4c10f6aaa0f4b3a8b7f7c79c Mon Sep 17 00:00:00 2001
From: Evan Owens
Date: Sat, 5 Apr 2014 07:12:16 +1000
Subject: [PATCH 202/447] Fix documentation about `immediate`
Unless I misimplemented this, "immediate" means persist to ElasticSearch "immediately"; before flushing. Default behavior is false; persist to ElasticSearch postFlush.
---
Resources/doc/types.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Resources/doc/types.md b/Resources/doc/types.md
index 38fa045..e01b5ae 100644
--- a/Resources/doc/types.md
+++ b/Resources/doc/types.md
@@ -270,9 +270,9 @@ FOSElasticaBundle, since 3.0.0 performs its indexing in the postFlush Doctrine e
instead of prePersist and preUpdate which means that indexing will only occur when there
has been a successful flush. This new default makes more sense but in the instance where
you want to perform indexing before the flush is confirmed you may set the `immediate`
-option on a type persistence configuration to false.
+option on a type persistence configuration to `true`.
```yaml
persistence:
- immediate: false
+ immediate: true
```
From 53332eb057b79ec75b94bf56c6281969cfff203b Mon Sep 17 00:00:00 2001
From: Evan Owens
Date: Fri, 4 Apr 2014 18:32:48 -0400
Subject: [PATCH 203/447] Allow for catching/logging persistance errors per
listener
---
DependencyInjection/Configuration.php | 3 ++
DependencyInjection/FOSElasticaExtension.php | 6 ++-
Doctrine/Listener.php | 7 +++-
Persister/ObjectPersister.php | 42 +++++++++++++++++---
Resources/doc/types.md | 18 ++++++++-
5 files changed, 68 insertions(+), 8 deletions(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index e77919c..002c78e 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -289,6 +289,9 @@ class Configuration implements ConfigurationInterface
->scalarNode('update')->defaultTrue()->end()
->scalarNode('delete')->defaultTrue()->end()
->booleanNode('immediate')->defaultFalse()->end()
+ ->scalarNode('logger')
+ ->treatTrueLike('fos_elastica.logger')
+ ->end()
->scalarNode('service')->end()
->variableNode('is_indexable_callback')->defaultNull()->end()
->end()
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 1d1540f..7511e2b 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -432,8 +432,12 @@ class FOSElasticaExtension extends Extension
$listenerDef = new DefinitionDecorator($abstractListenerId);
$listenerDef->replaceArgument(0, new Reference($objectPersisterId));
$listenerDef->replaceArgument(1, $typeConfig['model']);
- $listenerDef->replaceArgument(3, $typeConfig['identifier']);
$listenerDef->replaceArgument(2, $this->getDoctrineEvents($typeConfig));
+ $listenerDef->replaceArgument(3, $typeConfig['identifier']);
+ if (isset($typeConfig['listener']['logger'])) {
+ $listenerDef->replaceArgument(4, new Reference($typeConfig['listener']['logger']));
+ }
+
switch ($typeConfig['driver']) {
case 'orm': $listenerDef->addTag('doctrine.event_subscriber'); break;
case 'mongodb': $listenerDef->addTag('doctrine_mongodb.odm.event_subscriber'); break;
diff --git a/Doctrine/Listener.php b/Doctrine/Listener.php
index b6217a6..ded3998 100644
--- a/Doctrine/Listener.php
+++ b/Doctrine/Listener.php
@@ -2,6 +2,7 @@
namespace FOS\ElasticaBundle\Doctrine;
+use Psr\Log\LoggerInterface;
use Doctrine\Common\EventArgs;
use Doctrine\Common\EventSubscriber;
use FOS\ElasticaBundle\Persister\ObjectPersisterInterface;
@@ -85,13 +86,17 @@ class Listener implements EventSubscriber
* @param array $events
* @param string $esIdentifierField
*/
- public function __construct(ObjectPersisterInterface $objectPersister, $objectClass, array $events, $esIdentifierField = 'id')
+ public function __construct(ObjectPersisterInterface $objectPersister, $objectClass, array $events, $esIdentifierField = 'id', $logger = null)
{
$this->objectPersister = $objectPersister;
$this->objectClass = $objectClass;
$this->events = $events;
$this->esIdentifierField = $esIdentifierField;
+ if ($logger) {
+ $this->objectPersister->setLogger($logger);
+ }
+
$this->propertyAccessor = PropertyAccess::createPropertyAccessor();
}
diff --git a/Persister/ObjectPersister.php b/Persister/ObjectPersister.php
index 38541c8..cea6167 100644
--- a/Persister/ObjectPersister.php
+++ b/Persister/ObjectPersister.php
@@ -2,6 +2,8 @@
namespace FOS\ElasticaBundle\Persister;
+use Psr\Log\LoggerInterface;
+use Elastica\Exception\BulkException;
use Elastica\Exception\NotFoundException;
use FOS\ElasticaBundle\Transformer\ModelToElasticaTransformerInterface;
use Elastica\Type;
@@ -19,6 +21,7 @@ class ObjectPersister implements ObjectPersisterInterface
protected $transformer;
protected $objectClass;
protected $fields;
+ protected $logger;
public function __construct(Type $type, ModelToElasticaTransformerInterface $transformer, $objectClass, array $fields)
{
@@ -28,6 +31,18 @@ class ObjectPersister implements ObjectPersisterInterface
$this->fields = $fields;
}
+ public function setLogger(LoggerInterface $logger)
+ {
+ $this->logger = $logger;
+ }
+
+ private function log(BulkException $e)
+ {
+ if ($this->logger) {
+ $this->logger->error($e);
+ }
+ }
+
/**
* Insert one object into the type
* The object will be transformed to an elastica document
@@ -95,7 +110,11 @@ class ObjectPersister implements ObjectPersisterInterface
foreach ($objects as $object) {
$documents[] = $this->transformToElasticaDocument($object);
}
- $this->type->addDocuments($documents);
+ try {
+ $this->type->addDocuments($documents);
+ } catch (BulkException $e) {
+ $this->log($e);
+ }
}
/**
@@ -111,7 +130,12 @@ class ObjectPersister implements ObjectPersisterInterface
$document->setDocAsUpsert(true);
$documents[] = $document;
}
- $this->type->updateDocuments($documents);
+
+ try {
+ $this->type->updateDocuments($documents);
+ } catch (BulkException $e) {
+ $this->log($e);
+ }
}
/**
@@ -125,7 +149,11 @@ class ObjectPersister implements ObjectPersisterInterface
foreach ($objects as $object) {
$documents[] = $this->transformToElasticaDocument($object);
}
- $this->type->deleteDocuments($documents);
+ try {
+ $this->type->deleteDocuments($documents);
+ } catch (BulkException $e) {
+ $this->log($e);
+ }
}
/**
@@ -135,7 +163,11 @@ class ObjectPersister implements ObjectPersisterInterface
*/
public function deleteManyByIdentifiers(array $identifiers)
{
- $this->type->getIndex()->getClient()->deleteIds($identifiers, $this->type->getIndex(), $this->type);
+ try {
+ $this->type->getIndex()->getClient()->deleteIds($identifiers, $this->type->getIndex(), $this->type);
+ } catch (BulkException $e) {
+ $this->log($e);
+ }
}
/**
@@ -148,4 +180,4 @@ class ObjectPersister implements ObjectPersisterInterface
{
return $this->transformer->transform($object, $this->fields);
}
-}
+}
\ No newline at end of file
diff --git a/Resources/doc/types.md b/Resources/doc/types.md
index 38fa045..7e0fe05 100644
--- a/Resources/doc/types.md
+++ b/Resources/doc/types.md
@@ -274,5 +274,21 @@ option on a type persistence configuration to false.
```yaml
persistence:
- immediate: false
+ listener:
+ is_indexable_callback: "user.isActive() && user.hasRole('ROLE_USER')"
```
+
+Logging Errors
+--------------
+
+By default FOSElasticaBundle will not catch errors thrown by Elastica/ElasticSearch.
+Configure a logger per listener if you would rather catch and log these.
+
+```yaml
+ persistence:
+ listener:
+ logger: true
+```
+
+Specifying `true` will use the default Elastica logger. Alternatively define your own
+logger service id.
From a4834716945cf6be391c9a8f24626fc42fe67c9e Mon Sep 17 00:00:00 2001
From: nurikabe
Date: Fri, 4 Apr 2014 22:56:47 -0400
Subject: [PATCH 204/447] Set listener loggers to fos_elastica.logger if null
---
DependencyInjection/Configuration.php | 1 +
Persister/ObjectPersister.php | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 002c78e..1bdcdcd 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -290,6 +290,7 @@ class Configuration implements ConfigurationInterface
->scalarNode('delete')->defaultTrue()->end()
->booleanNode('immediate')->defaultFalse()->end()
->scalarNode('logger')
+ ->treatNullLike('fos_elastica.logger')
->treatTrueLike('fos_elastica.logger')
->end()
->scalarNode('service')->end()
diff --git a/Persister/ObjectPersister.php b/Persister/ObjectPersister.php
index cea6167..98165ef 100644
--- a/Persister/ObjectPersister.php
+++ b/Persister/ObjectPersister.php
@@ -180,4 +180,4 @@ class ObjectPersister implements ObjectPersisterInterface
{
return $this->transformer->transform($object, $this->fields);
}
-}
\ No newline at end of file
+}
From 998c69bfc38328bfe66e9cd263262dc7a34d7274 Mon Sep 17 00:00:00 2001
From: Hugo Henrique
Date: Sun, 6 Apr 2014 15:17:02 -0300
Subject: [PATCH 205/447] Update usage.md
This link to documentation custom repositories is broken
---
Resources/doc/usage.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Resources/doc/usage.md b/Resources/doc/usage.md
index 4c962e0..fd6a878 100644
--- a/Resources/doc/usage.md
+++ b/Resources/doc/usage.md
@@ -101,7 +101,7 @@ $users = $repository->find('bob');
```
For more information about customising repositories, see the cookbook entry
-[Custom Repositories](custom-repositories.md).
+[Custom Repositories](cookbook/custom-repositories.md).
Using a custom query builder method for transforming results
------------------------------------------------------------
From 22e5a1d4ab1ca8efb3da6ad803268c68cceba491 Mon Sep 17 00:00:00 2001
From: Joshua Worden
Date: Mon, 7 Apr 2014 10:58:11 -0500
Subject: [PATCH 206/447] CS fix
---
Doctrine/Listener.php | 6 ------
1 file changed, 6 deletions(-)
diff --git a/Doctrine/Listener.php b/Doctrine/Listener.php
index ad5641e..5d89e63 100644
--- a/Doctrine/Listener.php
+++ b/Doctrine/Listener.php
@@ -190,17 +190,11 @@ class Listener implements EventSubscriber
{
if (method_exists($eventArgs, 'getObject')) {
-
return $eventArgs->getObject();
-
} elseif (method_exists($eventArgs, 'getEntity')) {
-
return $eventArgs->getEntity();
-
} elseif (method_exists($eventArgs, 'getDocument')) {
-
return $eventArgs->getDocument();
-
}
throw new \RuntimeException('Unable to retrieve object from EventArgs.');
From f07e55417d4fb679b616fa5c9208ac36278c0629 Mon Sep 17 00:00:00 2001
From: nurikabe
Date: Mon, 7 Apr 2014 16:16:37 -0400
Subject: [PATCH 207/447] Re-throw exception if no logger defined
---
Persister/ObjectPersister.php | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/Persister/ObjectPersister.php b/Persister/ObjectPersister.php
index 98165ef..c279ec7 100644
--- a/Persister/ObjectPersister.php
+++ b/Persister/ObjectPersister.php
@@ -36,11 +36,20 @@ class ObjectPersister implements ObjectPersisterInterface
$this->logger = $logger;
}
+ /**
+ * Log exception if logger defined for persister belonging to the current listener, otherwise re-throw
+ *
+ * @param BulkException $e
+ * @throws BulkException
+ * @return null
+ */
private function log(BulkException $e)
{
- if ($this->logger) {
- $this->logger->error($e);
+ if (! $this->logger) {
+ throw $e;
}
+
+ $this->logger->error($e);
}
/**
From b3fdf7b256bc66f27fef1d6e851411a8755f199c Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Thu, 10 Apr 2014 13:05:23 +1000
Subject: [PATCH 208/447] Logger for a listener is false by default
---
DependencyInjection/Configuration.php | 1 +
1 file changed, 1 insertion(+)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 1bdcdcd..b0a7b59 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -290,6 +290,7 @@ class Configuration implements ConfigurationInterface
->scalarNode('delete')->defaultTrue()->end()
->booleanNode('immediate')->defaultFalse()->end()
->scalarNode('logger')
+ ->defaultFalse()
->treatNullLike('fos_elastica.logger')
->treatTrueLike('fos_elastica.logger')
->end()
From 1bc085141b5a5e368b09a57245a40883815351e7 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Thu, 10 Apr 2014 13:14:03 +1000
Subject: [PATCH 209/447] Fix logger option for listeners
---
DependencyInjection/FOSElasticaExtension.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 7511e2b..51cb94f 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -208,7 +208,7 @@ class FOSElasticaExtension extends Extension
}
$callbackClassImplementedInterfaces = class_implements($this->serializerConfig['callback_class']); // PHP < 5.4 friendly
if (isset($callbackClassImplementedInterfaces['Symfony\Component\DependencyInjection\ContainerAwareInterface'])) {
- $callbackDef->addMethodCall('setContainer', array(new Reference('service_container')));
+ $callbackDef->addMethodCall('setContainer', array(new Reference('service_container')));
}
$container->setDefinition($callbackId, $callbackDef);
@@ -434,7 +434,7 @@ class FOSElasticaExtension extends Extension
$listenerDef->replaceArgument(1, $typeConfig['model']);
$listenerDef->replaceArgument(2, $this->getDoctrineEvents($typeConfig));
$listenerDef->replaceArgument(3, $typeConfig['identifier']);
- if (isset($typeConfig['listener']['logger'])) {
+ if ($typeConfig['listener']['logger']) {
$listenerDef->replaceArgument(4, new Reference($typeConfig['listener']['logger']));
}
From 088452cf8895f1ee2776f03abff470d434bac4e3 Mon Sep 17 00:00:00 2001
From: Dylan Schoenmakers
Date: Thu, 3 Apr 2014 18:50:03 +0900
Subject: [PATCH 210/447] Added example to usage.md
Added example for using a custom query builder method to usage.md.
---
Resources/doc/usage.md | 26 +++++++++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/Resources/doc/usage.md b/Resources/doc/usage.md
index 4c962e0..89120e2 100644
--- a/Resources/doc/usage.md
+++ b/Resources/doc/usage.md
@@ -112,11 +112,35 @@ circumstances this is not ideal and you'd prefer to use a different method to jo
any entity relations that are required on the page that will be displaying the results.
```yaml
- user:
+ user:
+ persistence:
elastica_to_model_transformer:
query_builder_method: createSearchQueryBuilder
```
+An example for using a custom query builder method:
+
+```php
+class UserRepository extends EntityRepository
+{
+ /**
+ * Used by Elastica to transform results to model
+ *
+ * @param string $entityAlias
+ * @return Doctrine\ORM\QueryBuilder
+ */
+ public function createSearchQueryBuilder($entityAlias)
+ {
+ $qb = $this->createQueryBuilder($entityAlias);
+
+ $qb->select($entityAlias, 'g')
+ ->innerJoin($entityAlias.'.groups', 'g');
+
+ return $qb;
+ }
+}
+```
+
Advanced Searching Example
--------------------------
From 4cfe24ae028e93ad7c5324e7808b577cf766ca5d Mon Sep 17 00:00:00 2001
From: Joshua Worden
Date: Thu, 10 Apr 2014 07:38:01 -0500
Subject: [PATCH 211/447] Update CS
---
Doctrine/Listener.php | 2 --
1 file changed, 2 deletions(-)
diff --git a/Doctrine/Listener.php b/Doctrine/Listener.php
index 5d89e63..2b6df94 100644
--- a/Doctrine/Listener.php
+++ b/Doctrine/Listener.php
@@ -188,7 +188,6 @@ class Listener implements EventSubscriber
*/
private function getDoctrineObject(EventArgs $eventArgs)
{
-
if (method_exists($eventArgs, 'getObject')) {
return $eventArgs->getObject();
} elseif (method_exists($eventArgs, 'getEntity')) {
@@ -198,7 +197,6 @@ class Listener implements EventSubscriber
}
throw new \RuntimeException('Unable to retrieve object from EventArgs.');
-
}
/**
From 449c33aea3fbb50966157c442908646a69d17051 Mon Sep 17 00:00:00 2001
From: Bob van de Vijver
Date: Sat, 12 Apr 2014 13:30:52 +0200
Subject: [PATCH 212/447] Fixes multiple updates on multiple flush executions
---
Doctrine/Listener.php | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Doctrine/Listener.php b/Doctrine/Listener.php
index 763ddec..ff9fc60 100644
--- a/Doctrine/Listener.php
+++ b/Doctrine/Listener.php
@@ -258,17 +258,21 @@ class Listener implements EventSubscriber
/**
* Persist scheduled objects to ElasticSearch
+ * After persisting, clear the scheduled queue to prevent multiple data updates when using multiple flush calls
*/
private function persistScheduled()
{
if (count($this->scheduledForInsertion)) {
$this->objectPersister->insertMany($this->scheduledForInsertion);
+ $this->scheduledForInsertion = array();
}
if (count($this->scheduledForUpdate)) {
$this->objectPersister->replaceMany($this->scheduledForUpdate);
+ $this->scheduledForUpdate = array();
}
if (count($this->scheduledForDeletion)) {
$this->objectPersister->deleteManyByIdentifiers($this->scheduledForDeletion);
+ $this->scheduledForDeletion = array();
}
}
From 165696a5a0372db7634772ca8e1ee9847a4022ea Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Tue, 15 Apr 2014 08:43:11 +1000
Subject: [PATCH 213/447] Bump Elastica requirement
---
composer.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/composer.json b/composer.json
index 8f22393..8dd19b6 100644
--- a/composer.json
+++ b/composer.json
@@ -16,7 +16,7 @@
"symfony/console": "~2.1",
"symfony/form": "~2.1",
"symfony/property-access": "~2.2",
- "ruflin/elastica": ">=0.20, <1.1-dev",
+ "ruflin/elastica": ">=0.90.2.0, <1.1-dev",
"psr/log": "~1.0"
},
"require-dev":{
From 4e638a0492896223808c36350ac60f4b35549b48 Mon Sep 17 00:00:00 2001
From: Ahmed Mohamed
Date: Wed, 16 Apr 2014 05:27:23 +0200
Subject: [PATCH 214/447] Ensure non-empty properties under fields mappings
---
Transformer/ModelToElasticaAutoTransformer.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Transformer/ModelToElasticaAutoTransformer.php b/Transformer/ModelToElasticaAutoTransformer.php
index 3107d0a..9694a3b 100644
--- a/Transformer/ModelToElasticaAutoTransformer.php
+++ b/Transformer/ModelToElasticaAutoTransformer.php
@@ -71,7 +71,7 @@ class ModelToElasticaAutoTransformer implements ModelToElasticaTransformerInterf
$value = $this->propertyAccessor->getValue($object, $key);
- if (isset($mapping['type']) && in_array($mapping['type'], array('nested', 'object')) && isset($mapping['properties'])) {
+ if (isset($mapping['type']) && in_array($mapping['type'], array('nested', 'object')) && isset($mapping['properties']) && !empty($mapping['properties'])) {
/* $value is a nested document or object. Transform $value into
* an array of documents, respective the mapped properties.
*/
From d33f2e547f8a35277f9835a18e137b82892d9627 Mon Sep 17 00:00:00 2001
From: Piotr Antosik
Date: Thu, 17 Apr 2014 10:14:53 +0200
Subject: [PATCH 215/447] Fix immediate doc
---
Resources/doc/types.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Resources/doc/types.md b/Resources/doc/types.md
index 99c3668..e55df5a 100644
--- a/Resources/doc/types.md
+++ b/Resources/doc/types.md
@@ -274,7 +274,8 @@ option on a type persistence configuration to `true`.
```yaml
persistence:
- immediate: true
+ listener:
+ immediate: true
```
Logging Errors
From 2bd6aba7ef0a722e690a550c21445d2faf81f09f Mon Sep 17 00:00:00 2001
From: ben
Date: Fri, 18 Apr 2014 13:57:08 +0200
Subject: [PATCH 216/447] Added GeoShape mapping options
---
DependencyInjection/Configuration.php | 3 +++
1 file changed, 3 insertions(+)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index b0a7b59..bb67e42 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -423,6 +423,9 @@ class Configuration implements ConfigurationInterface
->booleanNode('include_in_all')->defaultValue(true)->end()
->booleanNode('enabled')->defaultValue(true)->end()
->scalarNode('lat_lon')->end()
+ ->scalarNode('tree')->end()
+ ->scalarNode('precision')->end()
+ ->scalarNode('tree_levels')->end()
->scalarNode('index_name')->end()
->booleanNode('omit_norms')->end()
->scalarNode('index_options')->end()
From 0dcb77d7491ef2f2bdd87db357b393c8b790f28b Mon Sep 17 00:00:00 2001
From: Ruslan Zavacky
Date: Sat, 19 Apr 2014 18:31:56 +0300
Subject: [PATCH 217/447] More classes exposed as parameters.
---
Resources/config/config.xml | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/Resources/config/config.xml b/Resources/config/config.xml
index 1e49590..c10568d 100644
--- a/Resources/config/config.xml
+++ b/Resources/config/config.xml
@@ -8,6 +8,10 @@
FOS\ElasticaBundle\Client
FOS\ElasticaBundle\DynamicIndex
Elastica\Type
+ FOS\ElasticaBundle\IndexManager
+ FOS\ElasticaBundle\Resetter
+ FOS\ElasticaBundle\Finder\TransformedFinder
+ FOS\ElasticaBundle\Subscriber\PaginateElasticaQuerySubscriber
FOS\ElasticaBundle\Logger\ElasticaLogger
FOS\ElasticaBundle\DataCollector\ElasticaDataCollector
FOS\ElasticaBundle\Manager\RepositoryManager
@@ -32,12 +36,12 @@
-
+
-
+
@@ -48,7 +52,7 @@
-
+
@@ -84,7 +88,7 @@
-
+
From 806452813a33b19641fa9172b7acf96d58f0b587 Mon Sep 17 00:00:00 2001
From: Ahmed Mohamed
Date: Sun, 20 Apr 2014 03:41:41 +0200
Subject: [PATCH 218/447] Add test multiple objects mapping of at least one
auto-mapped and at least one manually mapped
---
.../ModelToElasticaAutoTransformerTest.php | 50 +++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
index 646d1a4..1fa6a8e 100644
--- a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
+++ b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php
@@ -107,6 +107,11 @@ class POPO
return array('foo' => 'foo', 'bar' => 'foo', 'id' => 1);
}
+ public function getNestedObject()
+ {
+ return array('key1' => (object)array('id' => 1, 'key1sub1' => 'value1sub1', 'key1sub2' => 'value1sub2'));
+ }
+
public function getUpper()
{
return (object) array('id' => 'parent', 'name' => 'a random name');
@@ -296,6 +301,51 @@ class ModelToElasticaAutoTransformerTest extends \PHPUnit_Framework_TestCase
), $data['obj']);
}
+ public function testObjectsMappingOfAtLeastOneAutoMappedObjectAndAtLeastOneManuallyMappedObject()
+ {
+ $transformer = $this->getTransformer();
+ $document = $transformer->transform(
+ new POPO(),
+ array(
+ 'obj' => array('type' => 'object', 'properties' => array()),
+ 'nestedObject' => array(
+ 'type' => 'object',
+ 'properties' => array(
+ 'key1sub1' => array(
+ 'type' => 'string',
+ 'properties' => array()
+ ),
+ 'key1sub2' => array(
+ 'type' => 'string',
+ 'properties' => array()
+ )
+ )
+ )
+ )
+ );
+ $data = $document->getData();
+
+ $this->assertTrue(array_key_exists('obj', $data));
+ $this->assertTrue(array_key_exists('nestedObject', $data));
+ $this->assertInternalType('array', $data['obj']);
+ $this->assertInternalType('array', $data['nestedObject']);
+ $this->assertEquals(
+ array(
+ 'foo' => 'foo',
+ 'bar' => 'foo',
+ 'id' => 1
+ ),
+ $data['obj']
+ );
+ $this->assertEquals(
+ array(
+ 'key1sub1' => 'value1sub1',
+ 'key1sub2' => 'value1sub2'
+ ),
+ $data['nestedObject'][0]
+ );
+ }
+
public function testParentMapping()
{
$transformer = $this->getTransformer();
From c9fd1cc5d99ba7d46050802b5dc9a78b44eb6dbc Mon Sep 17 00:00:00 2001
From: Ahmed Mohamed
Date: Sun, 20 Apr 2014 06:11:20 +0200
Subject: [PATCH 219/447] Revert declaring PaginateElasticaQuerySubscriber as a
paremeter, so not to break Knp compiler pass
---
Resources/config/config.xml | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/Resources/config/config.xml b/Resources/config/config.xml
index c10568d..7687250 100644
--- a/Resources/config/config.xml
+++ b/Resources/config/config.xml
@@ -11,7 +11,6 @@
FOS\ElasticaBundle\IndexManager
FOS\ElasticaBundle\Resetter
FOS\ElasticaBundle\Finder\TransformedFinder
- FOS\ElasticaBundle\Subscriber\PaginateElasticaQuerySubscriber
FOS\ElasticaBundle\Logger\ElasticaLogger
FOS\ElasticaBundle\DataCollector\ElasticaDataCollector
FOS\ElasticaBundle\Manager\RepositoryManager
@@ -88,7 +87,7 @@
-
+
From 39f1033a34e28ab6013e63654b9ec72b9865f3ff Mon Sep 17 00:00:00 2001
From: Cassiano
Date: Thu, 24 Apr 2014 09:39:22 -0300
Subject: [PATCH 220/447] Update Configuration.php
Adding the option to set index_analyzer and search_analyzer to _all field.
---
DependencyInjection/Configuration.php | 2 ++
1 file changed, 2 insertions(+)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 40b26c6..b7ef2ab 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -667,6 +667,8 @@ class Configuration implements ConfigurationInterface
$node
->children()
->scalarNode('enabled')->defaultValue(true)->end()
+ ->scalarNode('index_analyzer')->end()
+ ->scalarNode('search_analyzer')->end()
->end()
;
From c93bbb9081c3915e457713990c02afc700c0a933 Mon Sep 17 00:00:00 2001
From: Evan Villemez
Date: Thu, 1 May 2014 11:05:16 -0400
Subject: [PATCH 221/447] stop config from adding empty arrays into type
mappings
---
DependencyInjection/Configuration.php | 24 ++++++--
.../DependencyInjection/ConfigurationTest.php | 56 +++++++++++++++++++
2 files changed, 76 insertions(+), 4 deletions(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index b0a7b59..e4fd323 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -351,8 +351,16 @@ class Configuration implements ConfigurationInterface
->useAttributeAsKey('name')
->prototype('array')
->validate()
- ->ifTrue(function($v) { return isset($v['fields']) && empty($v['fields']); })
- ->then(function($v) { unset($v['fields']); return $v; })
+ ->always()
+ ->then(function($v) {
+ foreach (array('fields','properties') as $prop) {
+ if (isset($v[$prop]) && empty($v[$prop])) {
+ unset($v[$prop]);
+ }
+ }
+
+ return $v;
+ })
->end()
->treatNullLike(array())
->addDefaultsIfNotSet()
@@ -464,8 +472,16 @@ class Configuration implements ConfigurationInterface
->useAttributeAsKey('name')
->prototype('array')
->validate()
- ->ifTrue(function($v) { return isset($v['fields']) && empty($v['fields']); })
- ->then(function($v) { unset($v['fields']); return $v; })
+ ->always()
+ ->then(function($v) {
+ foreach (array('fields','properties') as $prop) {
+ if (isset($v[$prop]) && empty($v[$prop])) {
+ unset($v[$prop]);
+ }
+ }
+
+ return $v;
+ })
->end()
->treatNullLike(array())
->addDefaultsIfNotSet()
diff --git a/Tests/DependencyInjection/ConfigurationTest.php b/Tests/DependencyInjection/ConfigurationTest.php
index 5919ea7..08ada08 100644
--- a/Tests/DependencyInjection/ConfigurationTest.php
+++ b/Tests/DependencyInjection/ConfigurationTest.php
@@ -147,4 +147,60 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
$this->assertArrayNotHasKey('fields', $configuration['indexes']['test']['types']['test']['mappings']['children']['properties']['content']);
$this->assertArrayHasKey('fields', $configuration['indexes']['test']['types']['test']['mappings']['children']['properties']['title']);
}
+
+ public function testEmptyPropertiesIndexIsUnset()
+ {
+ $config = array(
+ 'indexes' => array(
+ 'test' => array(
+ 'types' => array(
+ 'test' => array(
+ 'mappings' => array(
+ 'title' => array(
+ 'type' => 'string',
+ 'fields' => array(
+ 'autocomplete' => null
+ )
+ ),
+ 'content' => null,
+ 'children' => array(
+ 'type' => 'object',
+ 'properties' => array(
+ 'title' => array(
+ 'type' => 'string',
+ 'fields' => array(
+ 'autocomplete' => null
+ )
+ ),
+ 'content' => null,
+ 'tags' => array(
+ 'properties' => array(
+ 'tag' => array(
+ 'type' => 'string',
+ 'index' => 'not_analyzed'
+ )
+ )
+ )
+ )
+ ),
+ )
+ )
+ )
+ )
+ )
+ );
+
+ $processor = new Processor();
+
+ $configuration = $processor->processConfiguration(new Configuration(array($config)), array($config));
+
+ $mapping = $configuration['indexes']['test']['types']['test']['mappings'];
+ $this->assertArrayNotHasKey('properties', $mapping['content']);
+ $this->assertArrayNotHasKey('properties', $mapping['title']);
+ $this->assertArrayHasKey('properties', $mapping['children']);
+ $this->assertArrayNotHasKey('properties', $mapping['children']['properties']['title']);
+ $this->assertArrayNotHasKey('properties', $mapping['children']['properties']['content']);
+ $this->assertArrayHasKey('properties', $mapping['children']['properties']['tags']);
+ $this->assertArrayNotHasKey('properties', $mapping['children']['properties']['tags']['properties']['tag']);
+ }
}
From d9f3fa1a595d82b4305b2706e44a65c6add05d16 Mon Sep 17 00:00:00 2001
From: Patrick McAndrew
Date: Fri, 2 May 2014 15:07:15 +0100
Subject: [PATCH 222/447] commit 1dcaadbe6f99b42b346e04239c0c8fd7812bbf51
Persister/ObjectPersister.php line 112:
$this->type->updateDocuments($documents); introduces a dependency on Elastica
0.9.10.0
---
composer.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/composer.json b/composer.json
index 8dd19b6..24801e7 100644
--- a/composer.json
+++ b/composer.json
@@ -16,7 +16,7 @@
"symfony/console": "~2.1",
"symfony/form": "~2.1",
"symfony/property-access": "~2.2",
- "ruflin/elastica": ">=0.90.2.0, <1.1-dev",
+ "ruflin/elastica": ">=0.90.10.0, <1.1-dev",
"psr/log": "~1.0"
},
"require-dev":{
From ae02364e7c66fae05176e0462090a85fd0b16bf9 Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Mon, 5 May 2014 08:53:33 +0200
Subject: [PATCH 223/447] use elastica library 1.1 and higher
---
composer.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/composer.json b/composer.json
index 24801e7..580785d 100644
--- a/composer.json
+++ b/composer.json
@@ -16,7 +16,7 @@
"symfony/console": "~2.1",
"symfony/form": "~2.1",
"symfony/property-access": "~2.2",
- "ruflin/elastica": ">=0.90.10.0, <1.1-dev",
+ "ruflin/elastica": ">=1.1-dev",
"psr/log": "~1.0"
},
"require-dev":{
From eaa9f8399744fb1966848e3bc2b83d1b2f5c9c54 Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Mon, 5 May 2014 11:55:48 +0200
Subject: [PATCH 224/447] remove empty fields arrays from mapping, this is not
ignored anymore by elasticsearch 1.*
---
DependencyInjection/FOSElasticaExtension.php | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 51cb94f..2019d5e 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -234,6 +234,7 @@ class FOSElasticaExtension extends Extension
$this->indexConfigs[$indexName]['config']['mappings'][$name]['_routing'] = $type['_routing'];
}
if (isset($type['mappings']) && !empty($type['mappings'])) {
+ $this->cleanUpMapping($type['mappings']);
$this->indexConfigs[$indexName]['config']['mappings'][$name]['properties'] = $type['mappings'];
$typeName = sprintf('%s/%s', $indexName, $name);
$this->typeFields[$typeName] = $type['mappings'];
@@ -570,4 +571,14 @@ class FOSElasticaExtension extends Extension
$container->setAlias('fos_elastica.manager', sprintf('fos_elastica.manager.%s', $defaultManagerService));
}
+
+ protected function cleanUpMapping(&$mappings)
+ {
+ foreach ($mappings as &$fieldProperties)
+ if (empty($fieldProperties['fields'])) {
+ unset($fieldProperties['fields']);
+ } else {
+ $this->cleanUpMapping($fieldProperties['fields']);
+ }
+ }
}
From b1d64e358d2e4070668c4af158c9573daf33bda5 Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Mon, 5 May 2014 12:01:05 +0200
Subject: [PATCH 225/447] Also cleanup fields in properties of objects
---
DependencyInjection/FOSElasticaExtension.php | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 2019d5e..ede7c21 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -574,11 +574,16 @@ class FOSElasticaExtension extends Extension
protected function cleanUpMapping(&$mappings)
{
- foreach ($mappings as &$fieldProperties)
- if (empty($fieldProperties['fields'])) {
- unset($fieldProperties['fields']);
- } else {
- $this->cleanUpMapping($fieldProperties['fields']);
+ foreach ($mappings as &$fieldProperties) {
+ if (empty($fieldProperties['fields'])) {
+ unset($fieldProperties['fields']);
+ } else {
+ $this->cleanUpMapping($fieldProperties['fields']);
+ }
+
+ if (!empty($fieldProperties['properties'])) {
+ $this->cleanUpMapping($fieldProperties['properties']);
+ }
}
}
}
From 5da8ee1a1655e8bd44c2db4e354b529dcf6c98f5 Mon Sep 17 00:00:00 2001
From: Lea Haensenberger
Date: Tue, 6 May 2014 08:18:37 +0200
Subject: [PATCH 226/447] still supporting 0.9 versions of elastica
---
composer.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/composer.json b/composer.json
index 580785d..a991d38 100644
--- a/composer.json
+++ b/composer.json
@@ -16,7 +16,7 @@
"symfony/console": "~2.1",
"symfony/form": "~2.1",
"symfony/property-access": "~2.2",
- "ruflin/elastica": ">=1.1-dev",
+ "ruflin/elastica": ">=0.90.10.0, <1.2-dev",
"psr/log": "~1.0"
},
"require-dev":{
From b0841c18ecb89a3ce3e2b8192411e9e9fdec3c00 Mon Sep 17 00:00:00 2001
From: caponica
Date: Thu, 8 May 2014 00:26:30 +0100
Subject: [PATCH 227/447] Changed QueryBuilder method from ->where() to
->andWhere() so it works with customised QueryBuilders which have an existing
where clause (instead of over-writing any existing DQL 'where' part)
---
Doctrine/ORM/ElasticaToModelTransformer.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Doctrine/ORM/ElasticaToModelTransformer.php b/Doctrine/ORM/ElasticaToModelTransformer.php
index 20ec6e8..a57a84c 100644
--- a/Doctrine/ORM/ElasticaToModelTransformer.php
+++ b/Doctrine/ORM/ElasticaToModelTransformer.php
@@ -29,7 +29,7 @@ class ElasticaToModelTransformer extends AbstractElasticaToModelTransformer
$hydrationMode = $hydrate ? Query::HYDRATE_OBJECT : Query::HYDRATE_ARRAY;
$qb = $this->getEntityQueryBuilder();
- $qb->where($qb->expr()->in(static::ENTITY_ALIAS.'.'.$this->options['identifier'], ':values'))
+ $qb->andWhere($qb->expr()->in(static::ENTITY_ALIAS.'.'.$this->options['identifier'], ':values'))
->setParameter('values', $identifierValues);
return $qb->getQuery()->setHydrationMode($hydrationMode)->execute();
From e5754ef5fcc67bc3bc0815696a405e7e5770e814 Mon Sep 17 00:00:00 2001
From: Thomas Ploch
Date: Tue, 13 May 2014 13:13:06 +0200
Subject: [PATCH 228/447] Make it possible to disable flush event through
configuration
---
DependencyInjection/Configuration.php | 1 +
DependencyInjection/FOSElasticaExtension.php | 3 ---
2 files changed, 1 insertion(+), 3 deletions(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index b0a7b59..cb813a5 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -288,6 +288,7 @@ class Configuration implements ConfigurationInterface
->scalarNode('insert')->defaultTrue()->end()
->scalarNode('update')->defaultTrue()->end()
->scalarNode('delete')->defaultTrue()->end()
+ ->scalarNode('flush')->defaultTrue()->end()
->booleanNode('immediate')->defaultFalse()->end()
->scalarNode('logger')
->defaultFalse()
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index ede7c21..7d754f1 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -465,9 +465,6 @@ class FOSElasticaExtension extends Extension
*/
private function getDoctrineEvents(array $typeConfig)
{
- // Flush always calls depending on actions scheduled in lifecycle listeners
- $typeConfig['listener']['flush'] = true;
-
switch ($typeConfig['driver']) {
case 'orm':
$eventsClass = '\Doctrine\ORM\Events';
From e1bbb87cfe011c0277a03e9ad66cdde2e521d86b Mon Sep 17 00:00:00 2001
From: Milan Magudia
Date: Fri, 16 May 2014 16:24:37 +0100
Subject: [PATCH 229/447] Fix for Issue #543 Client has a dependency on a
non-existent service "%kernel.debug%"
---
DependencyInjection/Configuration.php | 7 +++++--
DependencyInjection/FOSElasticaExtension.php | 2 +-
Tests/DependencyInjection/ConfigurationTest.php | 6 +++---
3 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 3c57558..fbdba94 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -16,10 +16,13 @@ class Configuration implements ConfigurationInterface
private $supportedDrivers = array('orm', 'mongodb', 'propel');
private $configArray = array();
+ private $debug;
- public function __construct($configArray)
+ public function __construct($configArray, $debug)
{
+
$this->configArray = $configArray;
+ $this->debug = $debug;
}
/**
@@ -121,7 +124,7 @@ class Configuration implements ConfigurationInterface
->scalarNode('host')->end()
->scalarNode('port')->end()
->scalarNode('logger')
- ->defaultValue('%kernel.debug%')
+ ->defaultValue(($this->debug) ? 'fos_elastica.logger' : false)
->treatNullLike('fos_elastica.logger')
->treatTrueLike('fos_elastica.logger')
->end()
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 7d754f1..f58cd5b 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -61,7 +61,7 @@ class FOSElasticaExtension extends Extension
public function getConfiguration(array $config, ContainerBuilder $container)
{
- return new Configuration($config);
+ return new Configuration($config, $container->getParameter('kernel.debug'));
}
/**
diff --git a/Tests/DependencyInjection/ConfigurationTest.php b/Tests/DependencyInjection/ConfigurationTest.php
index 08ada08..38ffc58 100644
--- a/Tests/DependencyInjection/ConfigurationTest.php
+++ b/Tests/DependencyInjection/ConfigurationTest.php
@@ -17,7 +17,7 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
public function setUp()
{
- $this->configuration = new Configuration(array());
+ $this->configuration = new Configuration(array(), false);
}
public function testEmptyConfigContainsFormatMappingOptionNode()
@@ -140,7 +140,7 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
$processor = new Processor();
- $configuration = $processor->processConfiguration(new Configuration(array($config)), array($config));
+ $configuration = $processor->processConfiguration(new Configuration(array($config), false), array($config));
$this->assertArrayNotHasKey('fields', $configuration['indexes']['test']['types']['test']['mappings']['content']);
$this->assertArrayHasKey('fields', $configuration['indexes']['test']['types']['test']['mappings']['title']);
@@ -192,7 +192,7 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
$processor = new Processor();
- $configuration = $processor->processConfiguration(new Configuration(array($config)), array($config));
+ $configuration = $processor->processConfiguration(new Configuration(array($config), false), array($config));
$mapping = $configuration['indexes']['test']['types']['test']['mappings'];
$this->assertArrayNotHasKey('properties', $mapping['content']);
From 2c208a4f103446bd2e4bca15846d43d43ebd11ae Mon Sep 17 00:00:00 2001
From: Milan Magudia
Date: Thu, 22 May 2014 16:18:08 +0100
Subject: [PATCH 230/447] Allow other transport options to be used i.e. Http,
Https, Guzzle etc...
---
DependencyInjection/Configuration.php | 2 ++
1 file changed, 2 insertions(+)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index fbdba94..3dfe5ae 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -92,6 +92,7 @@ class Configuration implements ConfigurationInterface
'port' => $v['port'],
'logger' => isset($v['logger']) ? $v['logger'] : null,
'headers' => isset($v['headers']) ? $v['headers'] : null,
+ 'transport' => isset($v['transport']) ? $v['transport'] : null,
)
)
);
@@ -132,6 +133,7 @@ class Configuration implements ConfigurationInterface
->useAttributeAsKey('name')
->prototype('scalar')->end()
->end()
+ ->scalarNode('transport')->end()
->scalarNode('timeout')->end()
->end()
->end()
From 28d0ee925d1eb8369944985ae246d40bc3025034 Mon Sep 17 00:00:00 2001
From: Darius Staisiunas
Date: Fri, 23 May 2014 12:55:33 +0300
Subject: [PATCH 231/447] added support for geohash
---
DependencyInjection/Configuration.php | 1 +
1 file changed, 1 insertion(+)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index fbdba94..215f4a2 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -435,6 +435,7 @@ class Configuration implements ConfigurationInterface
->booleanNode('include_in_all')->defaultValue(true)->end()
->booleanNode('enabled')->defaultValue(true)->end()
->scalarNode('lat_lon')->end()
+ ->scalarNode('geohash')->end()
->scalarNode('index_name')->end()
->booleanNode('omit_norms')->end()
->scalarNode('index_options')->end()
From 2029aba76a92d5eaffddb7998c1ef98aa264b318 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Mon, 31 Mar 2014 16:45:31 +1100
Subject: [PATCH 232/447] Ability for FOSElasticaBundle to disable persistence
backend logging for population
Update documentation and changelog
---
CHANGELOG-3.0.md | 1 +
DependencyInjection/Configuration.php | 3 ++-
Doctrine/AbstractProvider.php | 27 ++++++++++++++++++++-
Doctrine/MongoDB/Provider.php | 34 ++++++++++++++++++++++++++
Doctrine/ORM/Provider.php | 35 +++++++++++++++++++++++++++
Resources/doc/types.md | 15 ++++++++++++
6 files changed, 113 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG-3.0.md b/CHANGELOG-3.0.md
index abd05cd..9d74640 100644
--- a/CHANGELOG-3.0.md
+++ b/CHANGELOG-3.0.md
@@ -19,6 +19,7 @@ To generate a changelog summary since the last version, run
* #415: BC BREAK: document indexing occurs in postFlush rather than the pre* events previously.
* 7d13823: Dropped (broken) support for Symfony <2.3
* #496: Added support for HTTP headers
+ * #528: FOSElasticaBundle will disable Doctrine logging when populating for a large increase in speed
* 3.0.0-ALPHA2 (2014-03-17)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index d26a516..dff773e 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -187,9 +187,10 @@ class Configuration implements ConfigurationInterface
->scalarNode('identifier')->defaultValue('id')->end()
->arrayNode('provider')
->children()
- ->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
->scalarNode('batch_size')->defaultValue(100)->end()
->scalarNode('clear_object_manager')->defaultTrue()->end()
+ ->scalarNode('disable_logger')->defaultValue('%kernel.debug%')->end()
+ ->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
->scalarNode('service')->end()
->end()
->end()
diff --git a/Doctrine/AbstractProvider.php b/Doctrine/AbstractProvider.php
index 3fafe50..1c3f853 100644
--- a/Doctrine/AbstractProvider.php
+++ b/Doctrine/AbstractProvider.php
@@ -23,6 +23,7 @@ abstract class AbstractProvider extends BaseAbstractProvider
{
parent::__construct($objectPersister, $objectClass, array_merge(array(
'clear_object_manager' => true,
+ 'disable_logging' => false,
'ignore_errors' => false,
'query_builder_method' => 'createQueryBuilder',
), $options));
@@ -35,12 +36,17 @@ abstract class AbstractProvider extends BaseAbstractProvider
*/
public function populate(\Closure $loggerClosure = null, array $options = array())
{
+ if (!$this->options['disable_logging']) {
+ $logger = $this->disableLogging();
+ }
+
$queryBuilder = $this->createQueryBuilder();
$nbObjects = $this->countObjects($queryBuilder);
$offset = isset($options['offset']) ? intval($options['offset']) : 0;
$sleep = isset($options['sleep']) ? intval($options['sleep']) : 0;
$batchSize = isset($options['batch-size']) ? intval($options['batch-size']) : $this->options['batch_size'];
$ignoreErrors = isset($options['ignore-errors']) ? $options['ignore-errors'] : $this->options['ignore_errors'];
+ $manager = $this->managerRegistry->getManagerForClass($this->objectClass);
for (; $offset < $nbObjects; $offset += $batchSize) {
if ($loggerClosure) {
@@ -61,7 +67,7 @@ abstract class AbstractProvider extends BaseAbstractProvider
}
if ($this->options['clear_object_manager']) {
- $this->managerRegistry->getManagerForClass($this->objectClass)->clear();
+ $manager->clear();
}
usleep($sleep);
@@ -75,6 +81,10 @@ abstract class AbstractProvider extends BaseAbstractProvider
$loggerClosure(sprintf('%0.1f%% (%d/%d), %d objects/s %s', $percentComplete, $stepCount, $nbObjects, $objectsPerSecond, $this->getMemoryUsage()));
}
}
+
+ if (!$this->options['disable_logging']) {
+ $this->enableLogging($logger);
+ }
}
/**
@@ -85,6 +95,21 @@ abstract class AbstractProvider extends BaseAbstractProvider
*/
protected abstract function countObjects($queryBuilder);
+ /**
+ * Disables logging and returns the logger that was previously set.
+ *
+ * @return mixed
+ */
+ protected abstract function disableLogging();
+
+ /**
+ * Reenables the logger with the previously returned logger from disableLogging();
+ *
+ * @param mixed $logger
+ * @return mixed
+ */
+ protected abstract function enableLogging($logger);
+
/**
* Fetches a slice of objects using the query builder.
*
diff --git a/Doctrine/MongoDB/Provider.php b/Doctrine/MongoDB/Provider.php
index 16d9f76..9e1c5dd 100644
--- a/Doctrine/MongoDB/Provider.php
+++ b/Doctrine/MongoDB/Provider.php
@@ -8,6 +8,40 @@ use FOS\ElasticaBundle\Exception\InvalidArgumentTypeException;
class Provider extends AbstractProvider
{
+ /**
+ * Disables logging and returns the logger that was previously set.
+ *
+ * @return mixed
+ */
+ protected function disableLogging()
+ {
+ $configuration = $this->managerRegistry
+ ->getManagerForClass($this->objectClass)
+ ->getConnection()
+ ->getConfiguration();
+
+ $logger = $configuration->getLoggerCallable();
+ $configuration->setLoggerCallable(null);
+
+ return $logger;
+ }
+
+ /**
+ * Reenables the logger with the previously returned logger from disableLogging();
+ *
+ * @param mixed $logger
+ * @return mixed
+ */
+ protected function enableLogging($logger)
+ {
+ $configuration = $this->managerRegistry
+ ->getManagerForClass($this->objectClass)
+ ->getConnection()
+ ->getConfiguration();
+
+ $configuration->setLoggerCallable($logger);
+ }
+
/**
* @see FOS\ElasticaBundle\Doctrine\AbstractProvider::countObjects()
*/
diff --git a/Doctrine/ORM/Provider.php b/Doctrine/ORM/Provider.php
index 5d0164f..dfd6700 100644
--- a/Doctrine/ORM/Provider.php
+++ b/Doctrine/ORM/Provider.php
@@ -3,6 +3,7 @@
namespace FOS\ElasticaBundle\Doctrine\ORM;
use Doctrine\ORM\QueryBuilder;
+use Elastica\Exception\Bulk\ResponseException as BulkResponseException;
use FOS\ElasticaBundle\Doctrine\AbstractProvider;
use FOS\ElasticaBundle\Exception\InvalidArgumentTypeException;
@@ -10,6 +11,40 @@ class Provider extends AbstractProvider
{
const ENTITY_ALIAS = 'a';
+ /**
+ * Disables logging and returns the logger that was previously set.
+ *
+ * @return mixed
+ */
+ protected function disableLogging()
+ {
+ $configuration = $this->managerRegistry
+ ->getManagerForClass($this->objectClass)
+ ->getConnection()
+ ->getConfiguration();
+
+ $logger = $configuration->getSQLLogger();
+ $configuration->setSQLLogger(null);
+
+ return $logger;
+ }
+
+ /**
+ * Reenables the logger with the previously returned logger from disableLogging();
+ *
+ * @param mixed $logger
+ * @return mixed
+ */
+ protected function enableLogging($logger)
+ {
+ $configuration = $this->managerRegistry
+ ->getManagerForClass($this->objectClass)
+ ->getConnection()
+ ->getConfiguration();
+
+ $configuration->setSQLLogger($logger);
+ }
+
/**
* @see FOS\ElasticaBundle\Doctrine\AbstractProvider::countObjects()
*/
diff --git a/Resources/doc/types.md b/Resources/doc/types.md
index e55df5a..aa76a43 100644
--- a/Resources/doc/types.md
+++ b/Resources/doc/types.md
@@ -188,6 +188,21 @@ persistence configuration.
identifier: searchId
```
+### Turning on the persistence backend logger in production
+
+FOSElasticaBundle will turn of your persistence backend's logging configuration by default
+when Symfony2 is not in debug mode.
+
+To enable the logger (turn off this behaviour) set disable_logger to false for the
+provider
+
+```yaml
+ user:
+ persistence:
+ provider:
+ disable_logger: false
+```
+
Listener Configuration
----------------------
From 6d2b7a836790dcb9ebe51e8f7ed606d560ef78bf Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Fri, 23 May 2014 20:36:19 +1000
Subject: [PATCH 233/447] Combine client normalisation into a single method
---
DependencyInjection/Configuration.php | 31 +++++----------------------
1 file changed, 5 insertions(+), 26 deletions(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index dff773e..b420143 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -60,16 +60,6 @@ class Configuration implements ConfigurationInterface
return $treeBuilder;
}
- /**
- * Generates the configuration tree.
- *
- * @return \Symfony\Component\DependencyInjection\Configuration\NodeInterface
- */
- public function getConfigTree()
- {
- return $this->getConfigTreeBuilder()->buildTree();
- }
-
/**
* Adds the configuration for the "clients" key
*/
@@ -83,28 +73,17 @@ class Configuration implements ConfigurationInterface
->prototype('array')
->performNoDeepMerging()
->beforeNormalization()
- ->ifTrue(function($v) { return isset($v['host']) && isset($v['port']); })
+ ->ifTrue(function($v) { return (isset($v['host']) && isset($v['port'])) || isset($v['url']); })
->then(function($v) {
return array(
'servers' => array(
array(
- 'host' => $v['host'],
- 'port' => $v['port'],
+ 'host' => isset($v['host']) ? $v['host'] : null,
+ 'port' => isset($v['port']) ? $v['port'] : null,
+ 'url' => isset($v['url']) ? $v['url'] : null,
'logger' => isset($v['logger']) ? $v['logger'] : null,
'headers' => isset($v['headers']) ? $v['headers'] : null,
- )
- )
- );
- })
- ->end()
- ->beforeNormalization()
- ->ifTrue(function($v) { return isset($v['url']); })
- ->then(function($v) {
- return array(
- 'servers' => array(
- array(
- 'url' => $v['url'],
- 'logger' => isset($v['logger']) ? $v['logger'] : null
+ 'timeout' => isset($v['timeout']) ? $v['timeout'] : null,
)
)
);
From 843c76b6cabd0fb71ef03cd95b9702e9dd41b2fc Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Fri, 23 May 2014 20:39:37 +1000
Subject: [PATCH 234/447] Move persistence node to its own method
---
DependencyInjection/Configuration.php | 194 ++++++++++----------------
1 file changed, 75 insertions(+), 119 deletions(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index b420143..c736b9a 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -149,62 +149,7 @@ class Configuration implements ConfigurationInterface
->children()
->scalarNode('index_analyzer')->end()
->scalarNode('search_analyzer')->end()
- ->arrayNode('persistence')
- ->validate()
- ->ifTrue(function($v) { return isset($v['driver']) && 'propel' === $v['driver'] && isset($v['listener']); })
- ->thenInvalid('Propel doesn\'t support listeners')
- ->ifTrue(function($v) { return isset($v['driver']) && 'propel' === $v['driver'] && isset($v['repository']); })
- ->thenInvalid('Propel doesn\'t support the "repository" parameter')
- ->end()
- ->children()
- ->scalarNode('driver')
- ->validate()
- ->ifNotInArray($this->supportedDrivers)
- ->thenInvalid('The driver %s is not supported. Please choose one of '.json_encode($this->supportedDrivers))
- ->end()
- ->end()
- ->scalarNode('identifier')->defaultValue('id')->end()
- ->arrayNode('provider')
- ->children()
- ->scalarNode('batch_size')->defaultValue(100)->end()
- ->scalarNode('clear_object_manager')->defaultTrue()->end()
- ->scalarNode('disable_logger')->defaultValue('%kernel.debug%')->end()
- ->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
- ->scalarNode('service')->end()
- ->end()
- ->end()
- ->arrayNode('listener')
- ->children()
- ->scalarNode('insert')->defaultTrue()->end()
- ->scalarNode('update')->defaultTrue()->end()
- ->scalarNode('delete')->defaultTrue()->end()
- ->scalarNode('persist')->defaultValue('postFlush')->end()
- ->scalarNode('service')->end()
- ->variableNode('is_indexable_callback')->defaultNull()->end()
- ->end()
- ->end()
- ->arrayNode('finder')
- ->children()
- ->scalarNode('service')->end()
- ->end()
- ->end()
- ->arrayNode('elastica_to_model_transformer')
- ->addDefaultsIfNotSet()
- ->children()
- ->scalarNode('hydrate')->defaultTrue()->end()
- ->scalarNode('ignore_missing')->defaultFalse()->end()
- ->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
- ->scalarNode('service')->end()
- ->end()
- ->end()
- ->arrayNode('model_to_elastica_transformer')
- ->addDefaultsIfNotSet()
- ->children()
- ->scalarNode('service')->end()
- ->end()
- ->end()
- ->end()
- ->end()
+ ->append($this->getPersistenceNode())
->end()
->end()
->variableNode('settings')->defaultValue(array())->end()
@@ -241,69 +186,7 @@ class Configuration implements ConfigurationInterface
->end()
->scalarNode('index_analyzer')->end()
->scalarNode('search_analyzer')->end()
- ->arrayNode('persistence')
- ->validate()
- ->ifTrue(function($v) { return isset($v['driver']) && 'propel' === $v['driver'] && isset($v['listener']); })
- ->thenInvalid('Propel doesn\'t support listeners')
- ->ifTrue(function($v) { return isset($v['driver']) && 'propel' === $v['driver'] && isset($v['repository']); })
- ->thenInvalid('Propel doesn\'t support the "repository" parameter')
- ->end()
- ->children()
- ->scalarNode('driver')
- ->validate()
- ->ifNotInArray($this->supportedDrivers)
- ->thenInvalid('The driver %s is not supported. Please choose one of '.json_encode($this->supportedDrivers))
- ->end()
- ->end()
- ->scalarNode('model')->end()
- ->scalarNode('repository')->end()
- ->scalarNode('identifier')->defaultValue('id')->end()
- ->arrayNode('provider')
- ->children()
- ->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
- ->scalarNode('batch_size')->defaultValue(100)->end()
- ->scalarNode('clear_object_manager')->defaultTrue()->end()
- ->scalarNode('service')->end()
- ->end()
- ->end()
- ->arrayNode('listener')
- ->children()
- ->scalarNode('insert')->defaultTrue()->end()
- ->scalarNode('update')->defaultTrue()->end()
- ->scalarNode('delete')->defaultTrue()->end()
- ->scalarNode('flush')->defaultTrue()->end()
- ->booleanNode('immediate')->defaultFalse()->end()
- ->scalarNode('logger')
- ->defaultFalse()
- ->treatNullLike('fos_elastica.logger')
- ->treatTrueLike('fos_elastica.logger')
- ->end()
- ->scalarNode('service')->end()
- ->variableNode('is_indexable_callback')->defaultNull()->end()
- ->end()
- ->end()
- ->arrayNode('finder')
- ->children()
- ->scalarNode('service')->end()
- ->end()
- ->end()
- ->arrayNode('elastica_to_model_transformer')
- ->addDefaultsIfNotSet()
- ->children()
- ->scalarNode('hydrate')->defaultTrue()->end()
- ->scalarNode('ignore_missing')->defaultFalse()->end()
- ->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
- ->scalarNode('service')->end()
- ->end()
- ->end()
- ->arrayNode('model_to_elastica_transformer')
- ->addDefaultsIfNotSet()
- ->children()
- ->scalarNode('service')->end()
- ->end()
- ->end()
- ->end()
- ->end()
+ ->append($this->getPersistenceNode())
->end()
->append($this->getIdNode())
->append($this->getMappingsNode())
@@ -738,4 +621,77 @@ class Configuration implements ConfigurationInterface
return $node;
}
+
+ /**
+ * @return ArrayNodeDefinition|\Symfony\Component\Config\Definition\Builder\NodeDefinition
+ */
+ protected function getPersistenceNode()
+ {
+ $builder = new TreeBuilder();
+ $node = $builder->root('persistence');
+
+ $node
+ ->validate()
+ ->ifTrue(function($v) { return isset($v['driver']) && 'propel' === $v['driver'] && isset($v['listener']); })
+ ->thenInvalid('Propel doesn\'t support listeners')
+ ->ifTrue(function($v) { return isset($v['driver']) && 'propel' === $v['driver'] && isset($v['repository']); })
+ ->thenInvalid('Propel doesn\'t support the "repository" parameter')
+ ->end()
+ ->children()
+ ->scalarNode('driver')
+ ->validate()
+ ->ifNotInArray($this->supportedDrivers)
+ ->thenInvalid('The driver %s is not supported. Please choose one of '.json_encode($this->supportedDrivers))
+ ->end()
+ ->end()
+ ->scalarNode('model')->end()
+ ->scalarNode('repository')->end()
+ ->scalarNode('identifier')->defaultValue('id')->end()
+ ->arrayNode('provider')
+ ->children()
+ ->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
+ ->scalarNode('batch_size')->defaultValue(100)->end()
+ ->scalarNode('clear_object_manager')->defaultTrue()->end()
+ ->scalarNode('service')->end()
+ ->end()
+ ->end()
+ ->arrayNode('listener')
+ ->children()
+ ->scalarNode('insert')->defaultTrue()->end()
+ ->scalarNode('update')->defaultTrue()->end()
+ ->scalarNode('delete')->defaultTrue()->end()
+ ->booleanNode('immediate')->defaultFalse()->end()
+ ->scalarNode('logger')
+ ->defaultFalse()
+ ->treatNullLike('fos_elastica.logger')
+ ->treatTrueLike('fos_elastica.logger')
+ ->end()
+ ->scalarNode('service')->end()
+ ->variableNode('is_indexable_callback')->defaultNull()->end()
+ ->end()
+ ->end()
+ ->arrayNode('finder')
+ ->children()
+ ->scalarNode('service')->end()
+ ->end()
+ ->end()
+ ->arrayNode('elastica_to_model_transformer')
+ ->addDefaultsIfNotSet()
+ ->children()
+ ->scalarNode('hydrate')->defaultTrue()->end()
+ ->scalarNode('ignore_missing')->defaultFalse()->end()
+ ->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
+ ->scalarNode('service')->end()
+ ->end()
+ ->end()
+ ->arrayNode('model_to_elastica_transformer')
+ ->addDefaultsIfNotSet()
+ ->children()
+ ->scalarNode('service')->end()
+ ->end()
+ ->end()
+ ->end();
+
+ return $node;
+ }
}
From 41c4d77b20b0876561eeab1a381a0f11ca9c8941 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Fri, 23 May 2014 20:41:09 +1000
Subject: [PATCH 235/447] Move serializer node to its own method, add
serializer to type_prototype
---
DependencyInjection/Configuration.php | 33 +++++++++++++++++++--------
1 file changed, 23 insertions(+), 10 deletions(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index c736b9a..a8b1d2f 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -150,6 +150,7 @@ class Configuration implements ConfigurationInterface
->scalarNode('index_analyzer')->end()
->scalarNode('search_analyzer')->end()
->append($this->getPersistenceNode())
+ ->append($this->getSerializerNode())
->end()
->end()
->variableNode('settings')->defaultValue(array())->end()
@@ -174,19 +175,10 @@ class Configuration implements ConfigurationInterface
->prototype('array')
->treatNullLike(array())
->children()
- ->arrayNode('serializer')
- ->addDefaultsIfNotSet()
- ->children()
- ->arrayNode('groups')
- ->treatNullLike(array())
- ->prototype('scalar')->end()
- ->end()
- ->scalarNode('version')->end()
- ->end()
- ->end()
->scalarNode('index_analyzer')->end()
->scalarNode('search_analyzer')->end()
->append($this->getPersistenceNode())
+ ->append($this->getSerializerNode())
->end()
->append($this->getIdNode())
->append($this->getMappingsNode())
@@ -694,4 +686,25 @@ class Configuration implements ConfigurationInterface
return $node;
}
+
+ /**
+ * @return ArrayNodeDefinition|\Symfony\Component\Config\Definition\Builder\NodeDefinition
+ */
+ protected function getSerializerNode()
+ {
+ $builder = new TreeBuilder();
+ $node = $builder->root('serializer');
+
+ $node
+ ->addDefaultsIfNotSet()
+ ->children()
+ ->arrayNode('groups')
+ ->treatNullLike(array())
+ ->prototype('scalar')->end()
+ ->end()
+ ->scalarNode('version')->end()
+ ->end();
+
+ return $node;
+ }
}
From 352e3b68ac26da2faf73125613619c30fa0b6590 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Fri, 23 May 2014 22:24:11 +1000
Subject: [PATCH 236/447] Add configuration tests
---
.../DependencyInjection/ConfigurationTest.php | 200 ++++++++++--------
1 file changed, 108 insertions(+), 92 deletions(-)
diff --git a/Tests/DependencyInjection/ConfigurationTest.php b/Tests/DependencyInjection/ConfigurationTest.php
index 38ffc58..e2fba93 100644
--- a/Tests/DependencyInjection/ConfigurationTest.php
+++ b/Tests/DependencyInjection/ConfigurationTest.php
@@ -11,141 +11,157 @@ use Symfony\Component\Config\Definition\Processor;
class ConfigurationTest extends \PHPUnit_Framework_TestCase
{
/**
- * @var Configuration
+ * @var Processor
*/
- private $configuration;
+ private $processor;
public function setUp()
{
- $this->configuration = new Configuration(array(), false);
+ $this->processor = new Processor();
}
- public function testEmptyConfigContainsFormatMappingOptionNode()
+ private function getConfigs(array $configArray)
{
- $tree = $this->configuration->getConfigTree();
- $children = $tree->getChildren();
- $children = $children['indexes']->getPrototype()->getChildren();
- $typeNodes = $children['types']->getPrototype()->getChildren();
- $mappings = $typeNodes['mappings']->getPrototype()->getChildren();
+ $configuration = new Configuration($configArray, true);
- $this->assertArrayHasKey('format', $mappings);
- $this->assertInstanceOf('Symfony\Component\Config\Definition\ScalarNode', $mappings['format']);
- $this->assertNull($mappings['format']->getDefaultValue());
+ return $this->processor->processConfiguration($configuration, array($configArray));
}
- public function testDynamicTemplateNodes()
+ public function testUnconfiguredConfiguration()
{
- $tree = $this->configuration->getConfigTree();
- $children = $tree->getChildren();
- $children = $children['indexes']->getPrototype()->getChildren();
- $typeNodes = $children['types']->getPrototype()->getChildren();
- $dynamicTemplates = $typeNodes['dynamic_templates']->getPrototype()->getChildren();
+ $configuration = $this->getConfigs(array());
- $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('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']);
+ $this->assertSame(array(
+ 'clients' => array(),
+ 'indexes' => array(),
+ 'default_manager' => 'orm'
+ ), $configuration);
}
- public function testDynamicTemplateMappingNodes()
+ public function testClientConfiguration()
{
- $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();
+ $configuration = $this->getConfigs(array(
+ 'clients' => array(
+ 'default' => array(
+ 'url' => 'http://localhost:9200',
+ ),
+ 'clustered' => array(
+ 'servers' => array(
+ array(
+ 'url' => 'http://es1:9200',
+ 'headers' => array(
+ 'Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=='
+ )
+ ),
+ array(
+ 'url' => 'http://es2:9200',
+ 'headers' => array(
+ 'Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=='
+ )
+ ),
+ )
+ )
+ )
+ ));
- $this->assertArrayHasKey('type', $mapping);
- $this->assertInstanceOf('Symfony\Component\Config\Definition\ScalarNode', $mapping['type']);
- $this->assertSame('string', $mapping['type']->getDefaultValue());
+ $this->assertCount(2, $configuration['clients']);
+ $this->assertCount(1, $configuration['clients']['default']['servers']);
+ $this->assertCount(0, $configuration['clients']['default']['servers'][0]['headers']);
- $this->assertArrayHasKey('index', $mapping);
- $this->assertInstanceOf('Symfony\Component\Config\Definition\ScalarNode', $mapping['index']);
- $this->assertNull($mapping['index']->getDefaultValue());
+ $this->assertCount(2, $configuration['clients']['clustered']['servers']);
+ $this->assertEquals('http://es2:9200/', $configuration['clients']['clustered']['servers'][1]['url']);
+ $this->assertCount(1, $configuration['clients']['clustered']['servers'][1]['headers']);
+ $this->assertEquals('Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==', $configuration['clients']['clustered']['servers'][0]['headers'][0]);
+ }
+
+ public function testLogging()
+ {
+ $configuration = $this->getConfigs(array(
+ 'clients' => array(
+ 'logging_enabled' => array(
+ 'url' => 'http://localhost:9200',
+ 'logger' => true,
+ ),
+ 'logging_disabled' => array(
+ 'url' => 'http://localhost:9200',
+ 'logger' => false,
+ ),
+ 'logging_not_mentioned' => array(
+ 'url' => 'http://localhost:9200',
+ ),
+ 'logging_custom' => array(
+ 'url' => 'http://localhost:9200',
+ 'logger' => 'custom.service'
+ ),
+ )
+ ));
+
+ $this->assertCount(4, $configuration['clients']);
+
+ $this->assertEquals('fos_elastica.logger', $configuration['clients']['logging_enabled']['servers'][0]['logger']);
+ $this->assertFalse($configuration['clients']['logging_disabled']['servers'][0]['logger']);
+ $this->assertEquals('fos_elastica.logger', $configuration['clients']['logging_not_mentioned']['servers'][0]['logger']);
+ $this->assertEquals('custom.service', $configuration['clients']['logging_custom']['servers'][0]['logger']);
}
public function testSlashIsAddedAtTheEndOfServerUrl()
{
$config = array(
'clients' => array(
- 'default' => array(
- 'url' => 'http://www.github.com',
- ),
+ 'default' => array('url' => 'http://www.github.com'),
),
- );
-
- $processor = new Processor();
-
- $configuration = $processor->processConfiguration($this->configuration, array($config));
+ );
+ $configuration = $this->getConfigs($config);
$this->assertEquals('http://www.github.com/', $configuration['clients']['default']['servers'][0]['url']);
}
- public function testEmptyFieldsIndexIsUnset()
+ public function testTypeConfig()
{
- $config = array(
+ $configuration = $this->getConfigs(array(
+ 'clients' => array(
+ 'default' => array('url' => 'http://localhost:9200'),
+ ),
'indexes' => array(
'test' => array(
+ 'type_prototype' => array(
+ 'index_analyzer' => 'custom_analyzer',
+ 'persistence' => array(
+ 'identifier' => 'ID',
+ ),
+ 'serializer' => array(
+ 'groups' => array('Search'),
+ 'version' => 1
+ )
+ ),
'types' => array(
'test' => array(
'mappings' => array(
- 'title' => array(
- 'type' => 'string',
- 'fields' => array(
- 'autocomplete' => null
- )
- ),
- 'content' => null,
+ 'title' => array(),
+ 'published' => array('type' => 'datetime'),
+ 'body' => null,
+ ),
+ 'persistence' => array(
+ 'listener' => array(
+ 'logger' => true,
+ )
+ )
+ ),
+ 'test2' => array(
+ 'mappings' => array(
+ 'title' => null,
'children' => array(
'type' => 'nested',
- 'properties' => array(
- 'title' => array(
- 'type' => 'string',
- 'fields' => array(
- 'autocomplete' => null
- )
- ),
- 'content' => null
- )
)
)
)
)
)
)
- );
+ ));
- $processor = new Processor();
-
- $configuration = $processor->processConfiguration(new Configuration(array($config), false), array($config));
-
- $this->assertArrayNotHasKey('fields', $configuration['indexes']['test']['types']['test']['mappings']['content']);
- $this->assertArrayHasKey('fields', $configuration['indexes']['test']['types']['test']['mappings']['title']);
- $this->assertArrayNotHasKey('fields', $configuration['indexes']['test']['types']['test']['mappings']['children']['properties']['content']);
- $this->assertArrayHasKey('fields', $configuration['indexes']['test']['types']['test']['mappings']['children']['properties']['title']);
+ $this->assertEquals('string', $configuration['indexes']['test']['types']['test']['mappings']['title']['type']);
+ $this->assertTrue($configuration['indexes']['test']['types']['test']['mappings']['title']['include_in_all']);
}
public function testEmptyPropertiesIndexIsUnset()
From 3addfffc916f4ed09d774537a4f77728e6fd1ddb Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Fri, 23 May 2014 22:57:57 +1000
Subject: [PATCH 237/447] Added logging of server errors to example
---
.../doc/cookbook/suppress-server-errors.md | 26 +++++++++++--------
1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/Resources/doc/cookbook/suppress-server-errors.md b/Resources/doc/cookbook/suppress-server-errors.md
index d89ffd6..e4e371e 100644
--- a/Resources/doc/cookbook/suppress-server-errors.md
+++ b/Resources/doc/cookbook/suppress-server-errors.md
@@ -32,6 +32,16 @@ class Client extends BaseClient
try {
return parent::request($path, $method, $data, $query);
} catch (ExceptionInterface $e) {
+ if ($this->_logger) {
+ $this->_logger->warning('Failed to send a request to ElasticSearch', array(
+ 'exception' => $e->getMessage(),
+ 'path' => $path,
+ 'method' => $method,
+ 'data' => $data,
+ 'query' => $query
+ ));
+ }
+
return new Response('{"took":0,"timed_out":false,"hits":{"total":0,"max_score":0,"hits":[]}}');
}
}
@@ -41,15 +51,9 @@ class Client extends BaseClient
Configuration change:
---------------------
-```xml
-
+You must update a parameter in your `app/config/config.yml` file to point to your overridden client:
-
-
-
- Acme\ElasticaBundle\Client
-
-
-
+```yaml
+parameters:
+ fos_elastica.client.class: Acme\ElasticaBundle\Client
+```
From f8a445b46c939f04bc06a7f1d7631aca12ac618b Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Fri, 23 May 2014 23:11:45 +1000
Subject: [PATCH 238/447] Fix disabling of logger in DoctrineProvider
---
DependencyInjection/Configuration.php | 5 ++++-
Doctrine/AbstractProvider.php | 6 +++---
Resources/doc/types.md | 9 ++++-----
3 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 154abcc..d84cd3c 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -189,7 +189,10 @@ class Configuration implements ConfigurationInterface
->children()
->scalarNode('batch_size')->defaultValue(100)->end()
->scalarNode('clear_object_manager')->defaultTrue()->end()
- ->scalarNode('disable_logger')->defaultValue('%kernel.debug%')->end()
+ ->booleanNode('debug_logging')
+ ->defaultValue($this->debug)
+ ->treatNullLike($this->debug)
+ ->end()
->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
->scalarNode('service')->end()
->end()
diff --git a/Doctrine/AbstractProvider.php b/Doctrine/AbstractProvider.php
index 1c3f853..b9ffda5 100644
--- a/Doctrine/AbstractProvider.php
+++ b/Doctrine/AbstractProvider.php
@@ -23,7 +23,7 @@ abstract class AbstractProvider extends BaseAbstractProvider
{
parent::__construct($objectPersister, $objectClass, array_merge(array(
'clear_object_manager' => true,
- 'disable_logging' => false,
+ 'debug_logging' => false,
'ignore_errors' => false,
'query_builder_method' => 'createQueryBuilder',
), $options));
@@ -36,7 +36,7 @@ abstract class AbstractProvider extends BaseAbstractProvider
*/
public function populate(\Closure $loggerClosure = null, array $options = array())
{
- if (!$this->options['disable_logging']) {
+ if (!$this->options['debug_logging']) {
$logger = $this->disableLogging();
}
@@ -82,7 +82,7 @@ abstract class AbstractProvider extends BaseAbstractProvider
}
}
- if (!$this->options['disable_logging']) {
+ if (!$this->options['debug_logging']) {
$this->enableLogging($logger);
}
}
diff --git a/Resources/doc/types.md b/Resources/doc/types.md
index aa76a43..aacb09e 100644
--- a/Resources/doc/types.md
+++ b/Resources/doc/types.md
@@ -191,16 +191,15 @@ persistence configuration.
### Turning on the persistence backend logger in production
FOSElasticaBundle will turn of your persistence backend's logging configuration by default
-when Symfony2 is not in debug mode.
-
-To enable the logger (turn off this behaviour) set disable_logger to false for the
-provider
+when Symfony2 is not in debug mode. You can force FOSElasticaBundle to always disable
+logging by setting debug_logging to false, to leave logging alone by setting it to true,
+or leave it set to its default value which will mirror %kernel.debug%.
```yaml
user:
persistence:
provider:
- disable_logger: false
+ debug_logging: false
```
Listener Configuration
From f20392d78b912e4a50be9b9e1c87c95e9e3560dc Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Fri, 23 May 2014 23:19:55 +1000
Subject: [PATCH 239/447] Fix test failures for DoctrineProvider
---
Tests/Doctrine/AbstractProviderTest.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Tests/Doctrine/AbstractProviderTest.php b/Tests/Doctrine/AbstractProviderTest.php
index 2492eed..dcceccf 100644
--- a/Tests/Doctrine/AbstractProviderTest.php
+++ b/Tests/Doctrine/AbstractProviderTest.php
@@ -17,7 +17,7 @@ class AbstractProviderTest extends \PHPUnit_Framework_TestCase
}
$this->objectClass = 'objectClass';
- $this->options = array();
+ $this->options = array('debug_logging' => true);
$this->objectPersister = $this->getMockObjectPersister();
$this->managerRegistry = $this->getMockManagerRegistry();
From e77aa0c180d662ecf99fafed8bca23ccee6400b2 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Fri, 23 May 2014 23:20:52 +1000
Subject: [PATCH 240/447] Test on php 5.5
---
.travis.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.travis.yml b/.travis.yml
index 8f6a9d8..72632de 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,6 +3,7 @@ language: php
php:
- 5.3
- 5.4
+ - 5.5
before_script:
- echo "extension = mongo.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
From a9ea78443fbed12b78cd5767829eb1f6f766f523 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Sat, 24 May 2014 00:17:59 +1000
Subject: [PATCH 241/447] Support Elastica proxy option
---
DependencyInjection/Configuration.php | 1 +
1 file changed, 1 insertion(+)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index d0ec09f..9b2bc89 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -102,6 +102,7 @@ class Configuration implements ConfigurationInterface
->end()
->scalarNode('host')->end()
->scalarNode('port')->end()
+ ->scalarNode('proxy')->end()
->scalarNode('logger')
->defaultValue(($this->debug) ? 'fos_elastica.logger' : false)
->treatNullLike('fos_elastica.logger')
From f9745c8d21895ecac980a1b4160fc6780cea2716 Mon Sep 17 00:00:00 2001
From: Delf Tonder
Date: Sat, 24 May 2014 12:49:12 +0200
Subject: [PATCH 242/447] update setup.md - immediate is an listener option
fixed yml config example (having immediate as an persistence option will result in parsing error)
---
Resources/doc/setup.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Resources/doc/setup.md b/Resources/doc/setup.md
index 4ae40af..9a39b95 100644
--- a/Resources/doc/setup.md
+++ b/Resources/doc/setup.md
@@ -114,9 +114,9 @@ Below is an example for the Doctrine ORM.
driver: orm
model: Acme\ApplicationBundle\Entity\User
provider: ~
- listener: ~
+ listener:
+ immediate: ~
finder: ~
- immediate: ~
```
There are a significant number of options available for types, that can be
From f97e66712a861067263567021f402c2ff04100fe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tobias=20Sj=C3=B6sten?=
Date: Sun, 25 May 2014 00:31:40 +0100
Subject: [PATCH 243/447] Don't default url
---
DependencyInjection/Configuration.php | 2 +-
Tests/DependencyInjection/ConfigurationTest.php | 14 ++++++++++++++
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 9b2bc89..275b23d 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -96,7 +96,7 @@ class Configuration implements ConfigurationInterface
->children()
->scalarNode('url')
->validate()
- ->ifTrue(function($url) { return substr($url, -1) !== '/'; })
+ ->ifTrue(function($url) { return $url && substr($url, -1) !== '/'; })
->then(function($url) { return $url.'/'; })
->end()
->end()
diff --git a/Tests/DependencyInjection/ConfigurationTest.php b/Tests/DependencyInjection/ConfigurationTest.php
index e2fba93..bddd62e 100644
--- a/Tests/DependencyInjection/ConfigurationTest.php
+++ b/Tests/DependencyInjection/ConfigurationTest.php
@@ -219,4 +219,18 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
$this->assertArrayHasKey('properties', $mapping['children']['properties']['tags']);
$this->assertArrayNotHasKey('properties', $mapping['children']['properties']['tags']['properties']['tag']);
}
+
+ public function testClientConfigurationNoUrl()
+ {
+ $configuration = $this->getConfigs(array(
+ 'clients' => array(
+ 'default' => array(
+ 'host' => 'localhost',
+ 'port' => 9200,
+ ),
+ )
+ ));
+
+ $this->assertTrue(empty($configuration['clients']['default']['servers'][0]['url']));
+ }
}
From c38dc107e766ac100e2145db64d4fa7277ef517d Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Sun, 25 May 2014 17:34:44 +1000
Subject: [PATCH 244/447] Rename mappings to properties maintaining BC
Fixes #407
---
DependencyInjection/Configuration.php | 18 +++++--
DependencyInjection/FOSElasticaExtension.php | 47 +++++++++----------
Resetter.php | 4 +-
.../DependencyInjection/ConfigurationTest.php | 30 ++++++++++--
Tests/ResetterTest.php | 16 +++----
5 files changed, 74 insertions(+), 41 deletions(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 275b23d..ac7d3a2 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -175,6 +175,16 @@ class Configuration implements ConfigurationInterface
->useAttributeAsKey('name')
->prototype('array')
->treatNullLike(array())
+ // BC - Renaming 'mappings' node to 'properties'
+ ->beforeNormalization()
+ ->ifTrue(function($v) { return isset($v['mappings']); })
+ ->then(function($v) {
+ $v['properties'] = $v['mappings'];
+ unset($v['mappings']);
+
+ return $v;
+ })
+ ->end()
->children()
->scalarNode('index_analyzer')->end()
->scalarNode('search_analyzer')->end()
@@ -182,7 +192,7 @@ class Configuration implements ConfigurationInterface
->append($this->getSerializerNode())
->end()
->append($this->getIdNode())
- ->append($this->getMappingsNode())
+ ->append($this->getPropertiesNode())
->append($this->getDynamicTemplateNode())
->append($this->getSourceNode())
->append($this->getBoostNode())
@@ -198,12 +208,12 @@ class Configuration implements ConfigurationInterface
}
/**
- * Returns the array node used for "mappings".
+ * Returns the array node used for "properties".
*/
- protected function getMappingsNode()
+ protected function getPropertiesNode()
{
$builder = new TreeBuilder();
- $node = $builder->root('mappings');
+ $node = $builder->root('properties');
$nestings = $this->getNestings();
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index f58cd5b..1529544 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -4,7 +4,6 @@ namespace FOS\ElasticaBundle\DependencyInjection;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
-use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
@@ -129,7 +128,7 @@ class FOSElasticaExtension extends Extension
'index' => new Reference($indexId),
'name_or_alias' => $indexName,
'config' => array(
- 'mappings' => array()
+ 'properties' => array()
)
);
if ($index['finder']) {
@@ -217,30 +216,30 @@ class FOSElasticaExtension extends Extension
}
$container->setDefinition($typeId, $typeDef);
- $this->indexConfigs[$indexName]['config']['mappings'][$name] = array(
+ $this->indexConfigs[$indexName]['config']['properties'][$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'];
+ $this->indexConfigs[$indexName]['config']['properties'][$name]['_id'] = $type['_id'];
}
if (isset($type['_source'])) {
- $this->indexConfigs[$indexName]['config']['mappings'][$name]['_source'] = $type['_source'];
+ $this->indexConfigs[$indexName]['config']['properties'][$name]['_source'] = $type['_source'];
}
if (isset($type['_boost'])) {
- $this->indexConfigs[$indexName]['config']['mappings'][$name]['_boost'] = $type['_boost'];
+ $this->indexConfigs[$indexName]['config']['properties'][$name]['_boost'] = $type['_boost'];
}
if (isset($type['_routing'])) {
- $this->indexConfigs[$indexName]['config']['mappings'][$name]['_routing'] = $type['_routing'];
+ $this->indexConfigs[$indexName]['config']['properties'][$name]['_routing'] = $type['_routing'];
}
- if (isset($type['mappings']) && !empty($type['mappings'])) {
- $this->cleanUpMapping($type['mappings']);
- $this->indexConfigs[$indexName]['config']['mappings'][$name]['properties'] = $type['mappings'];
+ if (isset($type['properties']) && !empty($type['properties'])) {
+ $this->cleanUpProperties($type['properties']);
+ $this->indexConfigs[$indexName]['config']['properties'][$name]['properties'] = $type['properties'];
$typeName = sprintf('%s/%s', $indexName, $name);
- $this->typeFields[$typeName] = $type['mappings'];
+ $this->typeFields[$typeName] = $type['properties'];
}
if (isset($type['_parent'])) {
- $this->indexConfigs[$indexName]['config']['mappings'][$name]['_parent'] = array('type' => $type['_parent']['type']);
+ $this->indexConfigs[$indexName]['config']['properties'][$name]['_parent'] = array('type' => $type['_parent']['type']);
$typeName = sprintf('%s/%s', $indexName, $name);
$this->typeFields[$typeName]['_parent'] = $type['_parent'];
}
@@ -248,27 +247,27 @@ class FOSElasticaExtension extends Extension
$this->loadTypePersistenceIntegration($type['persistence'], $container, $typeDef, $indexName, $name);
}
if (isset($type['index_analyzer'])) {
- $this->indexConfigs[$indexName]['config']['mappings'][$name]['index_analyzer'] = $type['index_analyzer'];
+ $this->indexConfigs[$indexName]['config']['properties'][$name]['index_analyzer'] = $type['index_analyzer'];
}
if (isset($type['search_analyzer'])) {
- $this->indexConfigs[$indexName]['config']['mappings'][$name]['search_analyzer'] = $type['search_analyzer'];
+ $this->indexConfigs[$indexName]['config']['properties'][$name]['search_analyzer'] = $type['search_analyzer'];
}
if (isset($type['index'])) {
- $this->indexConfigs[$indexName]['config']['mappings'][$name]['index'] = $type['index'];
+ $this->indexConfigs[$indexName]['config']['properties'][$name]['index'] = $type['index'];
}
if (isset($type['_all'])) {
- $this->indexConfigs[$indexName]['config']['mappings'][$name]['_all'] = $type['_all'];
+ $this->indexConfigs[$indexName]['config']['properties'][$name]['_all'] = $type['_all'];
}
if (isset($type['_timestamp'])) {
- $this->indexConfigs[$indexName]['config']['mappings'][$name]['_timestamp'] = $type['_timestamp'];
+ $this->indexConfigs[$indexName]['config']['properties'][$name]['_timestamp'] = $type['_timestamp'];
}
if (isset($type['_ttl'])) {
- $this->indexConfigs[$indexName]['config']['mappings'][$name]['_ttl'] = $type['_ttl'];
+ $this->indexConfigs[$indexName]['config']['properties'][$name]['_ttl'] = $type['_ttl'];
}
if (!empty($type['dynamic_templates'])) {
- $this->indexConfigs[$indexName]['config']['mappings'][$name]['dynamic_templates'] = array();
+ $this->indexConfigs[$indexName]['config']['properties'][$name]['dynamic_templates'] = array();
foreach ($type['dynamic_templates'] as $templateName => $templateData) {
- $this->indexConfigs[$indexName]['config']['mappings'][$name]['dynamic_templates'][] = array($templateName => $templateData);
+ $this->indexConfigs[$indexName]['config']['properties'][$name]['dynamic_templates'][] = array($templateName => $templateData);
}
}
}
@@ -569,17 +568,17 @@ class FOSElasticaExtension extends Extension
$container->setAlias('fos_elastica.manager', sprintf('fos_elastica.manager.%s', $defaultManagerService));
}
- protected function cleanUpMapping(&$mappings)
+ protected function cleanUpProperties(&$properties)
{
- foreach ($mappings as &$fieldProperties) {
+ foreach ($properties as &$fieldProperties) {
if (empty($fieldProperties['fields'])) {
unset($fieldProperties['fields']);
} else {
- $this->cleanUpMapping($fieldProperties['fields']);
+ $this->cleanUpProperties($fieldProperties['fields']);
}
if (!empty($fieldProperties['properties'])) {
- $this->cleanUpMapping($fieldProperties['properties']);
+ $this->cleanUpProperties($fieldProperties['properties']);
}
}
}
diff --git a/Resetter.php b/Resetter.php
index fe963d0..d614f1b 100644
--- a/Resetter.php
+++ b/Resetter.php
@@ -68,7 +68,7 @@ class Resetter
{
$indexConfig = $this->getIndexConfig($indexName);
- if (!isset($indexConfig['config']['mappings'][$typeName]['properties'])) {
+ if (!isset($indexConfig['config']['properties'][$typeName]['properties'])) {
throw new \InvalidArgumentException(sprintf('The mapping for index "%s" and type "%s" does not exist.', $indexName, $typeName));
}
@@ -80,7 +80,7 @@ class Resetter
throw $e;
}
}
- $mapping = $this->createMapping($indexConfig['config']['mappings'][$typeName]);
+ $mapping = $this->createMapping($indexConfig['config']['properties'][$typeName]);
$type->setMapping($mapping);
}
diff --git a/Tests/DependencyInjection/ConfigurationTest.php b/Tests/DependencyInjection/ConfigurationTest.php
index bddd62e..efaaa52 100644
--- a/Tests/DependencyInjection/ConfigurationTest.php
+++ b/Tests/DependencyInjection/ConfigurationTest.php
@@ -160,8 +160,8 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
)
));
- $this->assertEquals('string', $configuration['indexes']['test']['types']['test']['mappings']['title']['type']);
- $this->assertTrue($configuration['indexes']['test']['types']['test']['mappings']['title']['include_in_all']);
+ $this->assertEquals('string', $configuration['indexes']['test']['types']['test']['properties']['title']['type']);
+ $this->assertTrue($configuration['indexes']['test']['types']['test']['properties']['title']['include_in_all']);
}
public function testEmptyPropertiesIndexIsUnset()
@@ -210,7 +210,7 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
$configuration = $processor->processConfiguration(new Configuration(array($config), false), array($config));
- $mapping = $configuration['indexes']['test']['types']['test']['mappings'];
+ $mapping = $configuration['indexes']['test']['types']['test']['properties'];
$this->assertArrayNotHasKey('properties', $mapping['content']);
$this->assertArrayNotHasKey('properties', $mapping['title']);
$this->assertArrayHasKey('properties', $mapping['children']);
@@ -233,4 +233,28 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
$this->assertTrue(empty($configuration['clients']['default']['servers'][0]['url']));
}
+
+ public function testMappingsRenamedToProperties()
+ {
+ $configuration = $this->getConfigs(array(
+ 'clients' => array(
+ 'default' => array('url' => 'http://localhost:9200'),
+ ),
+ 'indexes' => array(
+ 'test' => array(
+ 'types' => array(
+ 'test' => array(
+ 'mappings' => array(
+ 'title' => array(),
+ 'published' => array('type' => 'datetime'),
+ 'body' => null,
+ )
+ )
+ )
+ )
+ )
+ ));
+
+ $this->assertCount(3, $configuration['indexes']['test']['types']['test']['properties']);
+ }
}
diff --git a/Tests/ResetterTest.php b/Tests/ResetterTest.php
index b4e5649..e27770f 100644
--- a/Tests/ResetterTest.php
+++ b/Tests/ResetterTest.php
@@ -18,7 +18,7 @@ class ResetterTest extends \PHPUnit_Framework_TestCase
'foo' => array(
'index' => $this->getMockElasticaIndex(),
'config' => array(
- 'mappings' => array(
+ 'properties' => array(
'a' => array(
'dynamic_templates' => array(),
'properties' => array(),
@@ -30,7 +30,7 @@ class ResetterTest extends \PHPUnit_Framework_TestCase
'bar' => array(
'index' => $this->getMockElasticaIndex(),
'config' => array(
- 'mappings' => array(
+ 'properties' => array(
'a' => array('properties' => array()),
'b' => array('properties' => array()),
),
@@ -39,7 +39,7 @@ class ResetterTest extends \PHPUnit_Framework_TestCase
'parent' => array(
'index' => $this->getMockElasticaIndex(),
'config' => array(
- 'mappings' => array(
+ 'properties' => array(
'a' => array(
'properties' => array(
'field_2' => array()
@@ -105,8 +105,8 @@ class ResetterTest extends \PHPUnit_Framework_TestCase
$type->expects($this->once())
->method('delete');
- $mapping = Mapping::create($this->indexConfigsByName['foo']['config']['mappings']['a']['properties']);
- $mapping->setParam('dynamic_templates', $this->indexConfigsByName['foo']['config']['mappings']['a']['dynamic_templates']);
+ $mapping = Mapping::create($this->indexConfigsByName['foo']['config']['properties']['a']['properties']);
+ $mapping->setParam('dynamic_templates', $this->indexConfigsByName['foo']['config']['properties']['a']['dynamic_templates']);
$type->expects($this->once())
->method('setMapping')
->with($mapping);
@@ -149,8 +149,8 @@ class ResetterTest extends \PHPUnit_Framework_TestCase
new Response(array('error' => 'TypeMissingException[[de_20131022] type[bla] missing]', 'status' => 404)))
));
- $mapping = Mapping::create($this->indexConfigsByName['foo']['config']['mappings']['a']['properties']);
- $mapping->setParam('dynamic_templates', $this->indexConfigsByName['foo']['config']['mappings']['a']['dynamic_templates']);
+ $mapping = Mapping::create($this->indexConfigsByName['foo']['config']['properties']['a']['properties']);
+ $mapping->setParam('dynamic_templates', $this->indexConfigsByName['foo']['config']['properties']['a']['dynamic_templates']);
$type->expects($this->once())
->method('setMapping')
->with($mapping);
@@ -171,7 +171,7 @@ class ResetterTest extends \PHPUnit_Framework_TestCase
$type->expects($this->once())
->method('delete');
- $mapping = Mapping::create($this->indexConfigsByName['parent']['config']['mappings']['a']['properties']);
+ $mapping = Mapping::create($this->indexConfigsByName['parent']['config']['properties']['a']['properties']);
$mapping->setParam('_parent', array('type' => 'b'));
$type->expects($this->once())
->method('setMapping')
From a79fa0242e834449ff075285764f878c3e2f5321 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Sun, 25 May 2014 20:08:01 +1000
Subject: [PATCH 245/447] Simplified Configuration.php
---
DependencyInjection/Configuration.php | 238 +-----------------
DependencyInjection/FOSElasticaExtension.php | 4 +-
.../DependencyInjection/ConfigurationTest.php | 63 +----
3 files changed, 15 insertions(+), 290 deletions(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 275b23d..0d0d238 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -15,13 +15,15 @@ class Configuration implements ConfigurationInterface
*/
private $supportedDrivers = array('orm', 'mongodb', 'propel');
- private $configArray = array();
+ /**
+ * If the kernel is running in debug mode.
+ *
+ * @var bool
+ */
private $debug;
- public function __construct($configArray, $debug)
+ public function __construct($debug)
{
-
- $this->configArray = $configArray;
$this->debug = $debug;
}
@@ -104,7 +106,7 @@ class Configuration implements ConfigurationInterface
->scalarNode('port')->end()
->scalarNode('proxy')->end()
->scalarNode('logger')
- ->defaultValue(($this->debug) ? 'fos_elastica.logger' : false)
+ ->defaultValue($this->debug ? 'fos_elastica.logger' : false)
->treatNullLike('fos_elastica.logger')
->treatTrueLike('fos_elastica.logger')
->end()
@@ -205,28 +207,10 @@ class Configuration implements ConfigurationInterface
$builder = new TreeBuilder();
$node = $builder->root('mappings');
- $nestings = $this->getNestings();
-
- $childrenNode = $node
+ $node
->useAttributeAsKey('name')
- ->prototype('array')
- ->validate()
- ->always()
- ->then(function($v) {
- foreach (array('fields','properties') as $prop) {
- if (isset($v[$prop]) && empty($v[$prop])) {
- unset($v[$prop]);
- }
- }
-
- return $v;
- })
- ->end()
- ->treatNullLike(array())
- ->addDefaultsIfNotSet()
- ->children();
-
- $this->addFieldConfig($childrenNode, $nestings);
+ ->prototype('variable')
+ ->treatNullLike(array());
return $node;
}
@@ -249,7 +233,7 @@ class Configuration implements ConfigurationInterface
->scalarNode('path_match')->end()
->scalarNode('path_unmatch')->end()
->scalarNode('match_pattern')->end()
- ->append($this->getDynamicTemplateMapping())
+ ->append($this->getMappingsNode())
->end()
->end()
;
@@ -257,206 +241,6 @@ 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
- */
- protected function addFieldConfig($node, $nestings)
- {
- $node
- ->scalarNode('type')->defaultValue('string')->end()
- ->scalarNode('boost')->end()
- ->scalarNode('store')->end()
- ->scalarNode('index')->end()
- ->scalarNode('index_analyzer')->end()
- ->scalarNode('search_analyzer')->end()
- ->scalarNode('analyzer')->end()
- ->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('tree')->end()
- ->scalarNode('precision')->end()
- ->scalarNode('tree_levels')->end()
- ->scalarNode('geohash')->end()
- ->scalarNode('index_name')->end()
- ->booleanNode('omit_norms')->end()
- ->scalarNode('index_options')->end()
- ->scalarNode('ignore_above')->end()
- ->scalarNode('position_offset_gap')->end()
- ->arrayNode('_parent')
- ->treatNullLike(array())
- ->children()
- ->scalarNode('type')->end()
- ->scalarNode('identifier')->defaultValue('id')->end()
- ->end()
- ->end()
- ->scalarNode('format')->end()
- ->scalarNode('similarity')->end();
- ;
-
- if (isset($nestings['fields'])) {
- $this->addNestedFieldConfig($node, $nestings, 'fields');
- }
-
- if (isset($nestings['properties'])) {
- $node
- ->booleanNode('include_in_parent')->end()
- ->booleanNode('include_in_root')->end()
- ;
- $this->addNestedFieldConfig($node, $nestings, 'properties');
- }
- }
-
- /**
- * @param \Symfony\Component\Config\Definition\Builder\NodeBuilder $node The node to which to attach the nested config to
- * @param array $nestings The nestings for the current field level
- * @param string $property the name of the nested property ('fields' or 'properties')
- */
- protected function addNestedFieldConfig($node, $nestings, $property)
- {
- $childrenNode = $node
- ->arrayNode($property)
- ->useAttributeAsKey('name')
- ->prototype('array')
- ->validate()
- ->always()
- ->then(function($v) {
- foreach (array('fields','properties') as $prop) {
- if (isset($v[$prop]) && empty($v[$prop])) {
- unset($v[$prop]);
- }
- }
-
- return $v;
- })
- ->end()
- ->treatNullLike(array())
- ->addDefaultsIfNotSet()
- ->children();
-
- $this->addFieldConfig($childrenNode, $nestings[$property]);
-
- $childrenNode
- ->end()
- ->end()
- ->end()
- ;
- }
-
- /**
- * @return array The unique nested mappings for all types
- */
- protected function getNestings()
- {
- 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['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
- */
- protected function getNestingsForType(array $mappings = null)
- {
- if ($mappings === null) {
- return array();
- }
-
- $nestings = array();
-
- foreach ($mappings as $field) {
- if (isset($field['fields'])) {
- $this->addPropertyNesting($field, $nestings, 'fields');
- } else if (isset($field['properties'])) {
- $this->addPropertyNesting($field, $nestings, 'properties');
- }
- }
-
- return $nestings;
- }
-
- /**
- * @param array $field The field mapping definition
- * @param array $nestings The nestings array
- * @param string $property The nested property name ('fields' or 'properties')
- */
- protected function addPropertyNesting($field, &$nestings, $property)
- {
- if (!isset($nestings[$property])) {
- $nestings[$property] = array();
- }
- $nestings[$property] = array_merge_recursive($nestings[$property], $this->getNestingsForType($field[$property]));
- }
-
/**
* Returns the array node used for "_id".
*/
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index f58cd5b..806c273 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -22,7 +22,7 @@ class FOSElasticaExtension extends Extension
public function load(array $configs, ContainerBuilder $container)
{
$configuration = $this->getConfiguration($configs, $container);
- $config = $this->processConfiguration($configuration, $configs);
+ $config = $this->processConfiguration($configuration, $configs);
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
@@ -61,7 +61,7 @@ class FOSElasticaExtension extends Extension
public function getConfiguration(array $config, ContainerBuilder $container)
{
- return new Configuration($config, $container->getParameter('kernel.debug'));
+ return new Configuration($container->getParameter('kernel.debug'));
}
/**
diff --git a/Tests/DependencyInjection/ConfigurationTest.php b/Tests/DependencyInjection/ConfigurationTest.php
index bddd62e..4a4da67 100644
--- a/Tests/DependencyInjection/ConfigurationTest.php
+++ b/Tests/DependencyInjection/ConfigurationTest.php
@@ -22,7 +22,7 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
private function getConfigs(array $configArray)
{
- $configuration = new Configuration($configArray, true);
+ $configuration = new Configuration(true);
return $this->processor->processConfiguration($configuration, array($configArray));
}
@@ -118,7 +118,7 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
public function testTypeConfig()
{
- $configuration = $this->getConfigs(array(
+ $this->getConfigs(array(
'clients' => array(
'default' => array('url' => 'http://localhost:9200'),
),
@@ -159,65 +159,6 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
)
)
));
-
- $this->assertEquals('string', $configuration['indexes']['test']['types']['test']['mappings']['title']['type']);
- $this->assertTrue($configuration['indexes']['test']['types']['test']['mappings']['title']['include_in_all']);
- }
-
- public function testEmptyPropertiesIndexIsUnset()
- {
- $config = array(
- 'indexes' => array(
- 'test' => array(
- 'types' => array(
- 'test' => array(
- 'mappings' => array(
- 'title' => array(
- 'type' => 'string',
- 'fields' => array(
- 'autocomplete' => null
- )
- ),
- 'content' => null,
- 'children' => array(
- 'type' => 'object',
- 'properties' => array(
- 'title' => array(
- 'type' => 'string',
- 'fields' => array(
- 'autocomplete' => null
- )
- ),
- 'content' => null,
- 'tags' => array(
- 'properties' => array(
- 'tag' => array(
- 'type' => 'string',
- 'index' => 'not_analyzed'
- )
- )
- )
- )
- ),
- )
- )
- )
- )
- )
- );
-
- $processor = new Processor();
-
- $configuration = $processor->processConfiguration(new Configuration(array($config), false), array($config));
-
- $mapping = $configuration['indexes']['test']['types']['test']['mappings'];
- $this->assertArrayNotHasKey('properties', $mapping['content']);
- $this->assertArrayNotHasKey('properties', $mapping['title']);
- $this->assertArrayHasKey('properties', $mapping['children']);
- $this->assertArrayNotHasKey('properties', $mapping['children']['properties']['title']);
- $this->assertArrayNotHasKey('properties', $mapping['children']['properties']['content']);
- $this->assertArrayHasKey('properties', $mapping['children']['properties']['tags']);
- $this->assertArrayNotHasKey('properties', $mapping['children']['properties']['tags']['properties']['tag']);
}
public function testClientConfigurationNoUrl()
From 53180e281041f7168943f54b6480582b536221ce Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Sun, 25 May 2014 20:14:51 +1000
Subject: [PATCH 246/447] Bring tidy in line with property renaming
---
DependencyInjection/Configuration.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 208026b..60b0684 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -243,7 +243,7 @@ class Configuration implements ConfigurationInterface
->scalarNode('path_match')->end()
->scalarNode('path_unmatch')->end()
->scalarNode('match_pattern')->end()
- ->append($this->getMappingsNode())
+ ->append($this->getPropertiesNode())
->end()
->end()
;
From dad15d0b387cab71ca1fa68dc70f85ad4310ad38 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Mon, 21 Apr 2014 09:21:50 +1000
Subject: [PATCH 247/447] Deprecate top level classes
---
CHANGELOG-3.0.md | 20 +-
Client.php | 38 +--
DynamicIndex.php | 20 +-
Elastica/Client.php | 47 ++++
Elastica/Index.php | 28 ++
Index/IndexManager.php | 63 +++++
Index/Resetter.php | 246 ++++++++++++++++++
IndexManager.php | 61 +----
Resetter.php | 240 +----------------
Resources/config/config.xml | 4 +-
.../LoggingClientTest.php} | 6 +-
Tests/{ => Index}/IndexManagerTest.php | 4 +-
Tests/{ => Index}/ResetterTest.php | 4 +-
13 files changed, 425 insertions(+), 356 deletions(-)
create mode 100644 Elastica/Client.php
create mode 100644 Elastica/Index.php
create mode 100644 Index/IndexManager.php
create mode 100644 Index/Resetter.php
rename Tests/{ClientTest.php => Elastica/LoggingClientTest.php} (86%)
rename Tests/{ => Index}/IndexManagerTest.php (95%)
rename Tests/{ => Index}/ResetterTest.php (98%)
diff --git a/CHANGELOG-3.0.md b/CHANGELOG-3.0.md
index 9d74640..095c268 100644
--- a/CHANGELOG-3.0.md
+++ b/CHANGELOG-3.0.md
@@ -12,7 +12,25 @@ https://github.com/FriendsOfSymfony/FOSElasticaBundle/compare/v3.0.0...v3.0.1
To generate a changelog summary since the last version, run
`git log --no-merges --oneline v3.0.0...3.0.x`
-* 3.0.0-ALPHA3 (xxxx-xx-xx)
+* 3.0.0-ALPHA6
+
+ * Deprecated FOS\ElasticaBundle\Client in favour of FOS\ElasticaBundle\Elastica\Client
+ * Deprecated FOS\ElasticaBundle\DynamicIndex in favour of FOS\ElasticaBundle\Elastica\Index
+ * Deprecated FOS\ElasticaBundle\IndexManager in favour of FOS\ElasticaBundle\Index\IndexManager
+ * Deprecated FOS\ElasticaBundle\Resetter in favour of FOS\ElasticaBundle\Index\Resetter
+
+* 3.0.0-ALPHA5 (2014-05-23)
+
+* Doctrine Provider speed up by disabling persistence logging while populating documents
+
+* 3.0.0-ALPHA4 (2014-04-10)
+
+ * Indexes are now capable of logging errors with Elastica
+ * Fixed deferred indexing of deleted documents
+ * Resetting an index will now create it even if it doesn't exist
+ * Bulk upserting of documents is now supported when populating
+
+* 3.0.0-ALPHA3 (2014-04-01)
* a9c4c93: Logger is now only enabled in debug mode by default
* #463: allowing hot swappable reindexing
diff --git a/Client.php b/Client.php
index 3eb98fe..f85756d 100644
--- a/Client.php
+++ b/Client.php
@@ -2,43 +2,11 @@
namespace FOS\ElasticaBundle;
-use Elastica\Client as ElasticaClient;
-use Elastica\Request;
-use FOS\ElasticaBundle\Logger\ElasticaLogger;
+use FOS\ElasticaBundle\Elastica\LoggingClient;
/**
- * @author Gordon Franke
+ * @deprecated Use \FOS\ElasticaBundle\Elastica\LoggingClient
*/
-class Client extends ElasticaClient
+class Client extends LoggingClient
{
- /**
- * {@inheritdoc}
- */
- public function request($path, $method = Request::GET, $data = array(), array $query = array())
- {
- $start = microtime(true);
- $response = parent::request($path, $method, $data, $query);
-
- if (null !== $this->_logger and $this->_logger instanceof ElasticaLogger) {
- $time = microtime(true) - $start;
-
- $connection = $this->getLastRequest()->getConnection();
-
- $connection_array = array(
- 'host' => $connection->getHost(),
- 'port' => $connection->getPort(),
- 'transport' => $connection->getTransport(),
- 'headers' => $connection->getConfig('headers'),
- );
-
- $this->_logger->logQuery($path, $method, $data, $time, $connection_array, $query);
- }
-
- return $response;
- }
-
- public function getIndex($name)
- {
- return new DynamicIndex($this, $name);
- }
}
diff --git a/DynamicIndex.php b/DynamicIndex.php
index cbec8e9..484a0d6 100644
--- a/DynamicIndex.php
+++ b/DynamicIndex.php
@@ -2,27 +2,11 @@
namespace FOS\ElasticaBundle;
-use Elastica\Index;
+use FOS\ElasticaBundle\Elastica\Index;
/**
- * Elastica index capable of reassigning name dynamically
- *
- * @author Konstantin Tjuterev
+ * @deprecated Use \FOS\ElasticaBundle\Elastica\TransformingIndex
*/
class DynamicIndex extends Index
{
- /**
- * Reassign index name
- *
- * While it's technically a regular setter for name property, it's specifically named overrideName, but not setName
- * since it's used for a very specific case and normally should not be used
- *
- * @param string $name Index name
- *
- * @return void
- */
- public function overrideName($name)
- {
- $this->_name = $name;
- }
}
diff --git a/Elastica/Client.php b/Elastica/Client.php
new file mode 100644
index 0000000..64a7d3d
--- /dev/null
+++ b/Elastica/Client.php
@@ -0,0 +1,47 @@
+
+ */
+class Client extends BaseClient
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function request($path, $method = Request::GET, $data = array(), array $query = array())
+ {
+ $start = microtime(true);
+ $response = parent::request($path, $method, $data, $query);
+
+ if ($this->_logger and $this->_logger instanceof ElasticaLogger) {
+ $time = microtime(true) - $start;
+
+ $connection = $this->getLastRequest()->getConnection();
+
+ $connection_array = array(
+ 'host' => $connection->getHost(),
+ 'port' => $connection->getPort(),
+ 'transport' => $connection->getTransport(),
+ 'headers' => $connection->getConfig('headers'),
+ );
+
+ $this->_logger->logQuery($path, $method, $data, $time, $connection_array, $query);
+ }
+
+ return $response;
+ }
+
+ public function getIndex($name)
+ {
+ return new Index($this, $name);
+ }
+}
diff --git a/Elastica/Index.php b/Elastica/Index.php
new file mode 100644
index 0000000..35d49f9
--- /dev/null
+++ b/Elastica/Index.php
@@ -0,0 +1,28 @@
+
+ */
+class Index extends BaseIndex
+{
+ /**
+ * Reassign index name
+ *
+ * While it's technically a regular setter for name property, it's specifically named overrideName, but not setName
+ * since it's used for a very specific case and normally should not be used
+ *
+ * @param string $name Index name
+ *
+ * @return void
+ */
+ public function overrideName($name)
+ {
+ $this->_name = $name;
+ }
+}
diff --git a/Index/IndexManager.php b/Index/IndexManager.php
new file mode 100644
index 0000000..543ccae
--- /dev/null
+++ b/Index/IndexManager.php
@@ -0,0 +1,63 @@
+indexesByName = $indexesByName;
+ $this->defaultIndexName = $defaultIndex->getName();
+ }
+
+ /**
+ * Gets all registered indexes
+ *
+ * @return array
+ */
+ public function getAllIndexes()
+ {
+ return $this->indexesByName;
+ }
+
+ /**
+ * Gets an index by its name
+ *
+ * @param string $name Index to return, or the default index if null
+ * @return Index
+ * @throws \InvalidArgumentException if no index exists for the given name
+ */
+ public function getIndex($name = null)
+ {
+ if (null === $name) {
+ $name = $this->defaultIndexName;
+ }
+
+ if (!isset($this->indexesByName[$name])) {
+ throw new \InvalidArgumentException(sprintf('The index "%s" does not exist', $name));
+ }
+
+ return $this->indexesByName[$name];
+ }
+
+ /**
+ * Gets the default index
+ *
+ * @return Index
+ */
+ public function getDefaultIndex()
+ {
+ return $this->getIndex($this->defaultIndexName);
+ }
+}
diff --git a/Index/Resetter.php b/Index/Resetter.php
new file mode 100644
index 0000000..99ae75e
--- /dev/null
+++ b/Index/Resetter.php
@@ -0,0 +1,246 @@
+indexConfigsByName = $indexConfigsByName;
+ }
+
+ /**
+ * Deletes and recreates all indexes
+ */
+ public function resetAllIndexes()
+ {
+ foreach (array_keys($this->indexConfigsByName) as $name) {
+ $this->resetIndex($name);
+ }
+ }
+
+ /**
+ * Deletes and recreates the named index
+ *
+ * @param string $indexName
+ * @throws \InvalidArgumentException if no index exists for the given name
+ */
+ public function resetIndex($indexName)
+ {
+ $indexConfig = $this->getIndexConfig($indexName);
+ $esIndex = $indexConfig['index'];
+ if (isset($indexConfig['use_alias']) && $indexConfig['use_alias']) {
+ $name = $indexConfig['name_or_alias'];
+ $name .= uniqid();
+ $esIndex->overrideName($name);
+ $esIndex->create($indexConfig['config']);
+
+ return;
+ }
+
+ $esIndex->create($indexConfig['config'], true);
+ }
+
+ /**
+ * Deletes and recreates a mapping type for the named index
+ *
+ * @param string $indexName
+ * @param string $typeName
+ * @throws \InvalidArgumentException if no index or type mapping exists for the given names
+ * @throws ResponseException
+ */
+ public function resetIndexType($indexName, $typeName)
+ {
+ $indexConfig = $this->getIndexConfig($indexName);
+
+ if (!isset($indexConfig['config']['properties'][$typeName]['properties'])) {
+ throw new \InvalidArgumentException(sprintf('The mapping for index "%s" and type "%s" does not exist.', $indexName, $typeName));
+ }
+
+ $type = $indexConfig['index']->getType($typeName);
+ try {
+ $type->delete();
+ } catch (ResponseException $e) {
+ if (strpos($e->getMessage(), 'TypeMissingException') === false) {
+ throw $e;
+ }
+ }
+ $mapping = $this->createMapping($indexConfig['config']['properties'][$typeName]);
+ $type->setMapping($mapping);
+ }
+
+ /**
+ * create type mapping object
+ *
+ * @param array $indexConfig
+ * @return Mapping
+ */
+ protected function createMapping($indexConfig)
+ {
+ $mapping = Mapping::create($indexConfig['properties']);
+
+ $mappingSpecialFields = array('_uid', '_id', '_source', '_all', '_analyzer', '_boost', '_routing', '_index', '_size', '_timestamp', '_ttl', 'dynamic_templates');
+ foreach ($mappingSpecialFields as $specialField) {
+ if (isset($indexConfig[$specialField])) {
+ $mapping->setParam($specialField, $indexConfig[$specialField]);
+ }
+ }
+
+ if (isset($indexConfig['_parent'])) {
+ $mapping->setParam('_parent', array('type' => $indexConfig['_parent']['type']));
+ }
+
+ return $mapping;
+ }
+
+ /**
+ * Gets an index config by its name
+ *
+ * @param string $indexName Index name
+ *
+ * @param $indexName
+ * @return array
+ * @throws \InvalidArgumentException if no index config exists for the given name
+ */
+ protected function getIndexConfig($indexName)
+ {
+ if (!isset($this->indexConfigsByName[$indexName])) {
+ throw new \InvalidArgumentException(sprintf('The configuration for index "%s" does not exist.', $indexName));
+ }
+
+ return $this->indexConfigsByName[$indexName];
+ }
+
+ public function postPopulate($indexName)
+ {
+ $indexConfig = $this->getIndexConfig($indexName);
+ if (isset($indexConfig['use_alias']) && $indexConfig['use_alias']) {
+ $this->switchIndexAlias($indexName);
+ }
+ }
+
+ /**
+ * Switches the alias for given index (by key) to the newly populated index
+ * and deletes the old index
+ *
+ * @param string $indexName Index name
+ *
+ * @throws \RuntimeException
+ */
+ private function switchIndexAlias($indexName)
+ {
+ $indexConfig = $this->getIndexConfig($indexName);
+ $esIndex = $indexConfig['index'];
+ $aliasName = $indexConfig['name_or_alias'];
+ $oldIndexName = false;
+ $newIndexName = $esIndex->getName();
+
+ $aliasedIndexes = $this->getAliasedIndexes($esIndex, $aliasName);
+
+ if (count($aliasedIndexes) > 1) {
+ throw new \RuntimeException(
+ sprintf(
+ 'Alias %s is used for multiple indexes: [%s].
+ Make sure it\'s either not used or is assigned to one index only',
+ $aliasName,
+ join(', ', $aliasedIndexes)
+ )
+ );
+ }
+
+ // Change the alias to point to the new index
+ // Elastica's addAlias can't be used directly, because in current (0.19.x) version it's not atomic
+ // In 0.20.x it's atomic, but it doesn't return the old index name
+ $aliasUpdateRequest = array('actions' => array());
+ if (count($aliasedIndexes) == 1) {
+ // if the alias is set - add an action to remove it
+ $oldIndexName = $aliasedIndexes[0];
+ $aliasUpdateRequest['actions'][] = array(
+ 'remove' => array('index' => $oldIndexName, 'alias' => $aliasName)
+ );
+ }
+
+ // add an action to point the alias to the new index
+ $aliasUpdateRequest['actions'][] = array(
+ 'add' => array('index' => $newIndexName, 'alias' => $aliasName)
+ );
+
+ try {
+ $esIndex->getClient()->request('_aliases', 'POST', $aliasUpdateRequest);
+ } catch (ExceptionInterface $renameAliasException) {
+ $additionalError = '';
+ // if we failed to move the alias, delete the newly built index
+ try {
+ $esIndex->delete();
+ } catch (ExceptionInterface $deleteNewIndexException) {
+ $additionalError = sprintf(
+ 'Tried to delete newly built index %s, but also failed: %s',
+ $newIndexName,
+ $deleteNewIndexException->getError()
+ );
+ }
+
+ throw new \RuntimeException(
+ sprintf(
+ 'Failed to updated index alias: %s. %s',
+ $renameAliasException->getMessage(),
+ $additionalError ?: sprintf('Newly built index %s was deleted', $newIndexName)
+ )
+ );
+ }
+
+ // Delete the old index after the alias has been switched
+ if ($oldIndexName) {
+ $oldIndex = new Index($esIndex->getClient(), $oldIndexName);
+ try {
+ $oldIndex->delete();
+ } catch (ExceptionInterface $deleteOldIndexException) {
+ throw new \RuntimeException(
+ sprintf(
+ 'Failed to delete old index %s with message: %s',
+ $oldIndexName,
+ $deleteOldIndexException->getMessage()
+ )
+ );
+ }
+ }
+ }
+
+ /**
+ * Returns array of indexes which are mapped to given alias
+ *
+ * @param Index $esIndex ES Index
+ * @param string $aliasName Alias name
+ *
+ * @return array
+ */
+ private function getAliasedIndexes(Index $esIndex, $aliasName)
+ {
+ $aliasesInfo = $esIndex->getClient()->request('_aliases', 'GET')->getData();
+ $aliasedIndexes = array();
+
+ foreach ($aliasesInfo as $indexName => $indexInfo) {
+ $aliases = array_keys($indexInfo['aliases']);
+ if (in_array($aliasName, $aliases)) {
+ $aliasedIndexes[] = $indexName;
+ }
+ }
+
+ return $aliasedIndexes;
+ }
+}
diff --git a/IndexManager.php b/IndexManager.php
index e20a791..e7c74c8 100644
--- a/IndexManager.php
+++ b/IndexManager.php
@@ -2,62 +2,11 @@
namespace FOS\ElasticaBundle;
-use Elastica\Index;
+use FOS\ElasticaBundle\Index\IndexManager as BaseIndexManager;
-class IndexManager
+/**
+ * @deprecated Use \FOS\ElasticaBundle\Index\IndexManager
+ */
+class IndexManager extends BaseIndexManager
{
- protected $indexesByName;
- protected $defaultIndexName;
-
- /**
- * Constructor.
- *
- * @param array $indexesByName
- * @param Index $defaultIndex
- */
- public function __construct(array $indexesByName, Index $defaultIndex)
- {
- $this->indexesByName = $indexesByName;
- $this->defaultIndexName = $defaultIndex->getName();
- }
-
- /**
- * Gets all registered indexes
- *
- * @return array
- */
- public function getAllIndexes()
- {
- return $this->indexesByName;
- }
-
- /**
- * Gets an index by its name
- *
- * @param string $name Index to return, or the default index if null
- * @return Index
- * @throws \InvalidArgumentException if no index exists for the given name
- */
- public function getIndex($name = null)
- {
- if (null === $name) {
- $name = $this->defaultIndexName;
- }
-
- if (!isset($this->indexesByName[$name])) {
- throw new \InvalidArgumentException(sprintf('The index "%s" does not exist', $name));
- }
-
- return $this->indexesByName[$name];
- }
-
- /**
- * Gets the default index
- *
- * @return Index
- */
- public function getDefaultIndex()
- {
- return $this->getIndex($this->defaultIndexName);
- }
}
diff --git a/Resetter.php b/Resetter.php
index d614f1b..2067579 100644
--- a/Resetter.php
+++ b/Resetter.php
@@ -2,245 +2,11 @@
namespace FOS\ElasticaBundle;
-use Elastica\Exception\ExceptionInterface;
-use Elastica\Index;
-use Elastica\Exception\ResponseException;
-use Elastica\Type\Mapping;
+use FOS\ElasticaBundle\Index\Resetter as BaseResetter;
/**
- * Deletes and recreates indexes
+ * @deprecated Use \FOS\ElasticaBundle\Index\Resetter
*/
-class Resetter
+class Resetter extends BaseResetter
{
- protected $indexConfigsByName;
-
- /**
- * Constructor.
- *
- * @param array $indexConfigsByName
- */
- public function __construct(array $indexConfigsByName)
- {
- $this->indexConfigsByName = $indexConfigsByName;
- }
-
- /**
- * Deletes and recreates all indexes
- */
- public function resetAllIndexes()
- {
- foreach (array_keys($this->indexConfigsByName) as $name) {
- $this->resetIndex($name);
- }
- }
-
- /**
- * Deletes and recreates the named index
- *
- * @param string $indexName
- * @throws \InvalidArgumentException if no index exists for the given name
- */
- public function resetIndex($indexName)
- {
- $indexConfig = $this->getIndexConfig($indexName);
- $esIndex = $indexConfig['index'];
- if (isset($indexConfig['use_alias']) && $indexConfig['use_alias']) {
- $name = $indexConfig['name_or_alias'];
- $name .= uniqid();
- $esIndex->overrideName($name);
- $esIndex->create($indexConfig['config']);
-
- return;
- }
-
- $esIndex->create($indexConfig['config'], true);
- }
-
- /**
- * Deletes and recreates a mapping type for the named index
- *
- * @param string $indexName
- * @param string $typeName
- * @throws \InvalidArgumentException if no index or type mapping exists for the given names
- * @throws ResponseException
- */
- public function resetIndexType($indexName, $typeName)
- {
- $indexConfig = $this->getIndexConfig($indexName);
-
- if (!isset($indexConfig['config']['properties'][$typeName]['properties'])) {
- throw new \InvalidArgumentException(sprintf('The mapping for index "%s" and type "%s" does not exist.', $indexName, $typeName));
- }
-
- $type = $indexConfig['index']->getType($typeName);
- try {
- $type->delete();
- } catch (ResponseException $e) {
- if (strpos($e->getMessage(), 'TypeMissingException') === false) {
- throw $e;
- }
- }
- $mapping = $this->createMapping($indexConfig['config']['properties'][$typeName]);
- $type->setMapping($mapping);
- }
-
- /**
- * create type mapping object
- *
- * @param array $indexConfig
- * @return Mapping
- */
- protected function createMapping($indexConfig)
- {
- $mapping = Mapping::create($indexConfig['properties']);
-
- $mappingSpecialFields = array('_uid', '_id', '_source', '_all', '_analyzer', '_boost', '_routing', '_index', '_size', '_timestamp', '_ttl', 'dynamic_templates');
- foreach ($mappingSpecialFields as $specialField) {
- if (isset($indexConfig[$specialField])) {
- $mapping->setParam($specialField, $indexConfig[$specialField]);
- }
- }
-
- if (isset($indexConfig['_parent'])) {
- $mapping->setParam('_parent', array('type' => $indexConfig['_parent']['type']));
- }
-
- return $mapping;
- }
-
- /**
- * Gets an index config by its name
- *
- * @param string $indexName Index name
- *
- * @param $indexName
- * @return array
- * @throws \InvalidArgumentException if no index config exists for the given name
- */
- protected function getIndexConfig($indexName)
- {
- if (!isset($this->indexConfigsByName[$indexName])) {
- throw new \InvalidArgumentException(sprintf('The configuration for index "%s" does not exist.', $indexName));
- }
-
- return $this->indexConfigsByName[$indexName];
- }
-
- public function postPopulate($indexName)
- {
- $indexConfig = $this->getIndexConfig($indexName);
- if (isset($indexConfig['use_alias']) && $indexConfig['use_alias']) {
- $this->switchIndexAlias($indexName);
- }
- }
-
- /**
- * Switches the alias for given index (by key) to the newly populated index
- * and deletes the old index
- *
- * @param string $indexName Index name
- *
- * @throws \RuntimeException
- */
- private function switchIndexAlias($indexName)
- {
- $indexConfig = $this->getIndexConfig($indexName);
- $esIndex = $indexConfig['index'];
- $aliasName = $indexConfig['name_or_alias'];
- $oldIndexName = false;
- $newIndexName = $esIndex->getName();
-
- $aliasedIndexes = $this->getAliasedIndexes($esIndex, $aliasName);
-
- if (count($aliasedIndexes) > 1) {
- throw new \RuntimeException(
- sprintf(
- 'Alias %s is used for multiple indexes: [%s].
- Make sure it\'s either not used or is assigned to one index only',
- $aliasName,
- join(', ', $aliasedIndexes)
- )
- );
- }
-
- // Change the alias to point to the new index
- // Elastica's addAlias can't be used directly, because in current (0.19.x) version it's not atomic
- // In 0.20.x it's atomic, but it doesn't return the old index name
- $aliasUpdateRequest = array('actions' => array());
- if (count($aliasedIndexes) == 1) {
- // if the alias is set - add an action to remove it
- $oldIndexName = $aliasedIndexes[0];
- $aliasUpdateRequest['actions'][] = array(
- 'remove' => array('index' => $oldIndexName, 'alias' => $aliasName)
- );
- }
-
- // add an action to point the alias to the new index
- $aliasUpdateRequest['actions'][] = array(
- 'add' => array('index' => $newIndexName, 'alias' => $aliasName)
- );
-
- try {
- $esIndex->getClient()->request('_aliases', 'POST', $aliasUpdateRequest);
- } catch (ExceptionInterface $renameAliasException) {
- $additionalError = '';
- // if we failed to move the alias, delete the newly built index
- try {
- $esIndex->delete();
- } catch (ExceptionInterface $deleteNewIndexException) {
- $additionalError = sprintf(
- 'Tried to delete newly built index %s, but also failed: %s',
- $newIndexName,
- $deleteNewIndexException->getError()
- );
- }
-
- throw new \RuntimeException(
- sprintf(
- 'Failed to updated index alias: %s. %s',
- $renameAliasException->getMessage(),
- $additionalError ?: sprintf('Newly built index %s was deleted', $newIndexName)
- )
- );
- }
-
- // Delete the old index after the alias has been switched
- if ($oldIndexName) {
- $oldIndex = new Index($esIndex->getClient(), $oldIndexName);
- try {
- $oldIndex->delete();
- } catch (ExceptionInterface $deleteOldIndexException) {
- throw new \RuntimeException(
- sprintf(
- 'Failed to delete old index %s with message: %s',
- $oldIndexName,
- $deleteOldIndexException->getMessage()
- )
- );
- }
- }
- }
-
- /**
- * Returns array of indexes which are mapped to given alias
- *
- * @param Index $esIndex ES Index
- * @param string $aliasName Alias name
- *
- * @return array
- */
- private function getAliasedIndexes(Index $esIndex, $aliasName)
- {
- $aliasesInfo = $esIndex->getClient()->request('_aliases', 'GET')->getData();
- $aliasedIndexes = array();
-
- foreach ($aliasesInfo as $indexName => $indexInfo) {
- $aliases = array_keys($indexInfo['aliases']);
- if (in_array($aliasName, $aliases)) {
- $aliasedIndexes[] = $indexName;
- }
- }
-
- return $aliasedIndexes;
- }
}
diff --git a/Resources/config/config.xml b/Resources/config/config.xml
index 7687250..cff2b49 100644
--- a/Resources/config/config.xml
+++ b/Resources/config/config.xml
@@ -5,8 +5,8 @@
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
- FOS\ElasticaBundle\Client
- FOS\ElasticaBundle\DynamicIndex
+ FOS\ElasticaBundle\Elastica\Client
+ FOS\ElasticaBundle\Elastica\Index
Elastica\Type
FOS\ElasticaBundle\IndexManager
FOS\ElasticaBundle\Resetter
diff --git a/Tests/ClientTest.php b/Tests/Elastica/LoggingClientTest.php
similarity index 86%
rename from Tests/ClientTest.php
rename to Tests/Elastica/LoggingClientTest.php
index 8a9d91a..b08a2cf 100644
--- a/Tests/ClientTest.php
+++ b/Tests/Elastica/LoggingClientTest.php
@@ -1,11 +1,11 @@
isType('array')
);
- $client = $this->getMockBuilder('FOS\ElasticaBundle\Client')
+ $client = $this->getMockBuilder('FOS\ElasticaBundle\Elastica\LoggingClient')
->setMethods(array('getConnection'))
->getMock();
diff --git a/Tests/IndexManagerTest.php b/Tests/Index/IndexManagerTest.php
similarity index 95%
rename from Tests/IndexManagerTest.php
rename to Tests/Index/IndexManagerTest.php
index 0a8ea37..624f64e 100644
--- a/Tests/IndexManagerTest.php
+++ b/Tests/Index/IndexManagerTest.php
@@ -1,8 +1,8 @@
Date: Sun, 25 May 2014 18:51:14 +0200
Subject: [PATCH 248/447] fixing missing flush event handler
In [commit](https://github.com/FriendsOfSymfony/FOSElasticaBundle/commit/843c76b6cabd0fb71ef03cd95b9702e9dd41b2fc#diff-850942b3ba24ab03a40aaa81b6152852) the configuration-definition for the flush listener was accidentally removed.
As the flush listener is no longer set to be enabled in the extensions getDoctrineEvents method, the flush listener is not set.
This results in a situation were we are only able to have the modified objects on the list for index-update, but never actually sending the update to the ES host.
---
DependencyInjection/Configuration.php | 1 +
1 file changed, 1 insertion(+)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 275b23d..35d399f 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -654,6 +654,7 @@ class Configuration implements ConfigurationInterface
->scalarNode('insert')->defaultTrue()->end()
->scalarNode('update')->defaultTrue()->end()
->scalarNode('delete')->defaultTrue()->end()
+ ->scalarNode('flush')->defaultTrue()->end()
->booleanNode('immediate')->defaultFalse()->end()
->scalarNode('logger')
->defaultFalse()
From 2e0aa064a2b1d71a6315e21d5d7fedabeb58a0ab Mon Sep 17 00:00:00 2001
From: Tornaldo
Date: Sun, 1 Jun 2014 01:27:20 +0200
Subject: [PATCH 249/447] Update usage.md
---
Resources/doc/usage.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Resources/doc/usage.md b/Resources/doc/usage.md
index c1d5982..91f13ae 100644
--- a/Resources/doc/usage.md
+++ b/Resources/doc/usage.md
@@ -184,7 +184,7 @@ The following code will execute a search against the Elasticsearch server:
$finder = $this->container->get('fos_elastica.finder.site.article');
$boolQuery = new \Elastica\Query\Bool();
-$fieldQuery = new \Elastica\Query\Text();
+$fieldQuery = new \Elastica\Query\Match();
$fieldQuery->setFieldQuery('title', 'I am a title string');
$fieldQuery->setFieldParam('title', 'analyzer', 'my_analyzer');
$boolQuery->addShould($fieldQuery);
From 6a822504bc0cad280c4c7a713d089d5bcb919c76 Mon Sep 17 00:00:00 2001
From: Oskar Stark
Date: Sun, 1 Jun 2014 15:57:29 +0200
Subject: [PATCH 250/447] use $this->container instead of $container
---
Resources/doc/usage.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Resources/doc/usage.md b/Resources/doc/usage.md
index 91f13ae..55d90ab 100644
--- a/Resources/doc/usage.md
+++ b/Resources/doc/usage.md
@@ -65,7 +65,7 @@ You can now use the index wide finder service `fos_elastica.finder.website`:
```php
/** var FOS\ElasticaBundle\Finder\MappedFinder */
-$finder = $container->get('fos_elastica.finder.website');
+$finder = $this->container->get('fos_elastica.finder.website');
// Returns a mixed array of any objects mapped
$results = $finder->find('bob');
@@ -91,7 +91,7 @@ An example for using a repository:
```php
/** var FOS\ElasticaBundle\Manager\RepositoryManager */
-$repositoryManager = $container->get('fos_elastica.manager');
+$repositoryManager = $this->container->get('fos_elastica.manager');
/** var FOS\ElasticaBundle\Repository */
$repository = $repositoryManager->getRepository('UserBundle:User');
From 1dc6856ef9c28f253a2e47f3dfb3396a4b24b5c5 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Mon, 2 Jun 2014 00:40:03 +1000
Subject: [PATCH 251/447] Configuration rework
---
DependencyInjection/Configuration.php | 2 +-
DependencyInjection/FOSElasticaExtension.php | 406 ++++++++++---------
Resources/config/config.xml | 84 +---
Resources/config/index.xml | 39 ++
Resources/config/mongodb.xml | 4 +-
Resources/config/orm.xml | 12 +-
Resources/config/persister.xml | 27 ++
Resources/config/propel.xml | 3 -
Resources/config/provider.xml | 18 +
Resources/config/transformer.xml | 32 ++
Tests/Integration/MappingTest.php | 17 +
11 files changed, 372 insertions(+), 272 deletions(-)
create mode 100644 Resources/config/index.xml
create mode 100644 Resources/config/persister.xml
create mode 100644 Resources/config/provider.xml
create mode 100644 Resources/config/transformer.xml
create mode 100644 Tests/Integration/MappingTest.php
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 60b0684..2acc9e5 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -288,7 +288,7 @@ class Configuration implements ConfigurationInterface
->end()
->scalarNode('compress')->end()
->scalarNode('compress_threshold')->end()
- ->scalarNode('enabled')->end()
+ ->scalarNode('enabled')->defaultTrue()->end()
->end()
;
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index e896af2..c844f3a 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -13,9 +13,28 @@ use InvalidArgumentException;
class FOSElasticaExtension extends Extension
{
- protected $indexConfigs = array();
- protected $typeFields = array();
- protected $loadedDrivers = array();
+ /**
+ * Definition of elastica clients as configured by this extension.
+ *
+ * @var array
+ */
+ private $clients = array();
+
+ /**
+ * An array of indexes as configured by the extension.
+ *
+ * @var array
+ */
+ private $indexConfigs = array();
+
+ /**
+ * If we've encountered a type mapped to a specific persistence driver, it will be loaded
+ * here.
+ *
+ * @var array
+ */
+ private $loadedDrivers = array();
+
protected $serializerConfig = array();
public function load(array $configs, ContainerBuilder $container)
@@ -30,7 +49,9 @@ class FOSElasticaExtension extends Extension
return;
}
- $loader->load('config.xml');
+ foreach (array('config', 'index', 'persister', 'provider', 'transformer') as $basename) {
+ $loader->load(sprintf('%s.xml', $basename));
+ }
if (empty($config['default_client'])) {
$keys = array_keys($config['clients']);
@@ -42,22 +63,24 @@ class FOSElasticaExtension extends Extension
$config['default_index'] = reset($keys);
}
- $clientIdsByName = $this->loadClients($config['clients'], $container);
$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);
-
- $this->loadIndexManager($indexRefsByName, $container);
- $this->loadResetter($this->indexConfigs, $container);
+ $this->loadClients($config['clients'], $container);
$container->setAlias('fos_elastica.client', sprintf('fos_elastica.client.%s', $config['default_client']));
+
+ $this->loadIndexes($config['indexes'], $container);
$container->setAlias('fos_elastica.index', sprintf('fos_elastica.index.%s', $config['default_index']));
+ $this->loadIndexManager($container);
+
$this->createDefaultManagerAlias($config['default_manager'], $container);
}
+ /**
+ * @param array $config
+ * @param ContainerBuilder $container
+ * @return Configuration|null|\Symfony\Component\Config\Definition\ConfigurationInterface
+ */
public function getConfiguration(array $config, ContainerBuilder $container)
{
return new Configuration($container->getParameter('kernel.debug'));
@@ -70,24 +93,26 @@ class FOSElasticaExtension extends Extension
* @param ContainerBuilder $container A ContainerBuilder instance
* @return array
*/
- protected function loadClients(array $clients, ContainerBuilder $container)
+ private function loadClients(array $clients, ContainerBuilder $container)
{
- $clientIds = array();
foreach ($clients as $name => $clientConfig) {
$clientId = sprintf('fos_elastica.client.%s', $name);
- $clientDef = new Definition('%fos_elastica.client.class%', array($clientConfig));
+
+ $clientDef = new DefinitionDecorator('fos_elastica.client_prototype');
+ $clientDef->replaceArgument(0, $clientConfig);
+
$logger = $clientConfig['servers'][0]['logger'];
if (false !== $logger) {
$clientDef->addMethodCall('setLogger', array(new Reference($logger)));
}
- $clientDef->addTag('fos_elastica.client');
$container->setDefinition($clientId, $clientDef);
- $clientIds[$name] = $clientId;
+ $this->clients[$name] = array(
+ 'id' => $clientId,
+ 'reference' => new Reference($clientId)
+ );
}
-
- return $clientIds;
}
/**
@@ -95,56 +120,44 @@ class FOSElasticaExtension extends Extension
*
* @param array $indexes An array of indexes configurations
* @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)
+ private function loadIndexes(array $indexes, ContainerBuilder $container)
{
- $indexIds = array();
foreach ($indexes as $name => $index) {
- if (isset($index['client'])) {
- $clientName = $index['client'];
- if (!isset($clientIdsByName[$clientName])) {
- throw new InvalidArgumentException(sprintf('The elastica client with name "%s" is not defined', $clientName));
- }
- } else {
- $clientName = $defaultClientName;
- }
-
- $clientId = $clientIdsByName[$clientName];
$indexId = sprintf('fos_elastica.index.%s', $name);
- $indexName = isset($index['index_name']) ? $index['index_name'] : $name;
- $indexDefArgs = array($indexName);
- $indexDef = new Definition('%fos_elastica.index.class%', $indexDefArgs);
- $indexDef->setFactoryService($clientId);
- $indexDef->setFactoryMethod('getIndex');
+ $indexName = $index['index_name'] ?: $name;
+
+ $indexDef = new DefinitionDecorator('fos_elastica.index_prototype');
+ $indexDef->replaceArgument(0, $indexName);
+
+ if ($index['client']) {
+ $client = $this->getClient($index['client']);
+ $indexDef->setFactoryService($client);
+ }
+
$container->setDefinition($indexId, $indexDef);
- $typePrototypeConfig = isset($index['type_prototype']) ? $index['type_prototype'] : array();
- $indexIds[$name] = $indexId;
+ $reference = new Reference($indexId);
+
$this->indexConfigs[$name] = array(
- 'index' => new Reference($indexId),
- 'name_or_alias' => $indexName,
'config' => array(
- 'properties' => array()
- )
+ 'properties' => array(),
+ 'settings' => $index['settings']
+ ),
+ 'elasticsearch_name' => $indexName,
+ 'index' => $reference,
+ 'name' => $name,
+ 'type_prototype' => isset($index['type_prototype']) ? $index['type_prototype'] : array(),
+ 'use_alias' => $index['use_alias'],
);
+
if ($index['finder']) {
- $this->loadIndexFinder($container, $name, $indexId);
- }
- if (!empty($index['settings'])) {
- $this->indexConfigs[$name]['config']['settings'] = $index['settings'];
- }
- if ($index['use_alias']) {
- $this->indexConfigs[$name]['use_alias'] = true;
+ $this->loadIndexFinder($container, $name, $reference);
}
- $this->loadTypes(isset($index['types']) ? $index['types'] : array(), $container, $name, $indexId, $typePrototypeConfig);
+ $this->loadTypes((array) $index['types'], $container, $this->indexConfigs[$name]);
}
-
- return $indexIds;
}
/**
@@ -152,10 +165,10 @@ class FOSElasticaExtension extends Extension
*
* @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
* @param string $name The index name
- * @param string $indexId The index service identifier
+ * @param Reference $index Reference to the related index
* @return string
*/
- protected function loadIndexFinder(ContainerBuilder $container, $name, $indexId)
+ private function loadIndexFinder(ContainerBuilder $container, $name, Reference $index)
{
/* Note: transformer services may conflict with "collection.index", if
* an index and type names were "collection" and an index, respectively.
@@ -166,34 +179,60 @@ class FOSElasticaExtension extends Extension
$finderId = sprintf('fos_elastica.finder.%s', $name);
$finderDef = new DefinitionDecorator('fos_elastica.finder');
- $finderDef->replaceArgument(0, new Reference($indexId));
+ $finderDef->replaceArgument(0, $index);
$finderDef->replaceArgument(1, new Reference($transformerId));
$container->setDefinition($finderId, $finderDef);
-
- return $finderId;
}
/**
* Loads the configured types.
*
- * @param array $types An array of types configurations
- * @param ContainerBuilder $container A ContainerBuilder instance
- * @param $indexName
- * @param $indexId
- * @param array $typePrototypeConfig
- * @param $serializerConfig
+ * @param array $types
+ * @param ContainerBuilder $container
+ * @param array $indexConfig
*/
- protected function loadTypes(array $types, ContainerBuilder $container, $indexName, $indexId, array $typePrototypeConfig)
+ private function loadTypes(array $types, ContainerBuilder $container, array $indexConfig)
{
foreach ($types as $name => $type) {
- $type = self::deepArrayUnion($typePrototypeConfig, $type);
- $typeId = sprintf('%s.%s', $indexId, $name);
- $typeDefArgs = array($name);
- $typeDef = new Definition('%fos_elastica.type.class%', $typeDefArgs);
- $typeDef->setFactoryService($indexId);
- $typeDef->setFactoryMethod('getType');
- if ($this->serializerConfig) {
+ $indexName = $indexConfig['name'];
+ $type = self::deepArrayUnion($indexConfig['type_prototype'], $type);
+
+ $typeId = sprintf('%s.%s', $indexName, $name);
+ $typeDef = new DefinitionDecorator('fos_elastica.type_prototype');
+ $typeDef->replaceArgument(0, $name);
+ $typeDef->setFactoryService($indexConfig['reference']);
+
+ if (isset($type['persistence'])) {
+ $this->loadTypePersistenceIntegration($type['persistence'], $container, $typeDef, $indexName, $name);
+ }
+
+ foreach (array(
+ 'index_analyzer',
+ 'properties',
+ 'search_analyzer',
+ '_all',
+ '_boost',
+ '_id',
+ '_parent',
+ '_routing',
+ '_source',
+ '_timestamp',
+ '_ttl',
+ ) as $field) {
+ $this->indexConfigs[$indexName]['config']['properties'][$name][$field] = $type[$field];
+ }
+
+ if (!empty($type['dynamic_templates'])) {
+ $this->indexConfigs[$indexName]['config']['properties'][$name]['dynamic_templates'] = array();
+ foreach ($type['dynamic_templates'] as $templateName => $templateData) {
+ $this->indexConfigs[$indexName]['config']['properties'][$name]['dynamic_templates'][] = array($templateName => $templateData);
+ }
+ }
+
+ $container->setDefinition($typeId, $typeDef);
+
+ /*if ($this->serializerConfig) {
$callbackDef = new Definition($this->serializerConfig['callback_class']);
$callbackId = sprintf('%s.%s.serializer.callback', $indexId, $name);
@@ -213,63 +252,7 @@ class FOSElasticaExtension extends Extension
$container->setDefinition($callbackId, $callbackDef);
$typeDef->addMethodCall('setSerializer', array(array(new Reference($callbackId), 'serialize')));
- }
- $container->setDefinition($typeId, $typeDef);
-
- $this->indexConfigs[$indexName]['config']['properties'][$name] = array(
- "_source" => array("enabled" => true), // Add a default setting for empty mapping settings
- );
-
- if (isset($type['_id'])) {
- $this->indexConfigs[$indexName]['config']['properties'][$name]['_id'] = $type['_id'];
- }
- if (isset($type['_source'])) {
- $this->indexConfigs[$indexName]['config']['properties'][$name]['_source'] = $type['_source'];
- }
- if (isset($type['_boost'])) {
- $this->indexConfigs[$indexName]['config']['properties'][$name]['_boost'] = $type['_boost'];
- }
- if (isset($type['_routing'])) {
- $this->indexConfigs[$indexName]['config']['properties'][$name]['_routing'] = $type['_routing'];
- }
- if (isset($type['properties']) && !empty($type['properties'])) {
- $this->cleanUpProperties($type['properties']);
- $this->indexConfigs[$indexName]['config']['properties'][$name]['properties'] = $type['properties'];
- $typeName = sprintf('%s/%s', $indexName, $name);
- $this->typeFields[$typeName] = $type['properties'];
- }
- if (isset($type['_parent'])) {
- $this->indexConfigs[$indexName]['config']['properties'][$name]['_parent'] = array('type' => $type['_parent']['type']);
- $typeName = sprintf('%s/%s', $indexName, $name);
- $this->typeFields[$typeName]['_parent'] = $type['_parent'];
- }
- if (isset($type['persistence'])) {
- $this->loadTypePersistenceIntegration($type['persistence'], $container, $typeDef, $indexName, $name);
- }
- if (isset($type['index_analyzer'])) {
- $this->indexConfigs[$indexName]['config']['properties'][$name]['index_analyzer'] = $type['index_analyzer'];
- }
- if (isset($type['search_analyzer'])) {
- $this->indexConfigs[$indexName]['config']['properties'][$name]['search_analyzer'] = $type['search_analyzer'];
- }
- if (isset($type['index'])) {
- $this->indexConfigs[$indexName]['config']['properties'][$name]['index'] = $type['index'];
- }
- if (isset($type['_all'])) {
- $this->indexConfigs[$indexName]['config']['properties'][$name]['_all'] = $type['_all'];
- }
- if (isset($type['_timestamp'])) {
- $this->indexConfigs[$indexName]['config']['properties'][$name]['_timestamp'] = $type['_timestamp'];
- }
- if (isset($type['_ttl'])) {
- $this->indexConfigs[$indexName]['config']['properties'][$name]['_ttl'] = $type['_ttl'];
- }
- if (!empty($type['dynamic_templates'])) {
- $this->indexConfigs[$indexName]['config']['properties'][$name]['dynamic_templates'] = array();
- foreach ($type['dynamic_templates'] as $templateName => $templateData) {
- $this->indexConfigs[$indexName]['config']['properties'][$name]['dynamic_templates'][] = array($templateName => $templateData);
- }
- }
+ }*/
}
}
@@ -281,7 +264,7 @@ class FOSElasticaExtension extends Extension
*
* @return array The merged array
*/
- static protected function deepArrayUnion($array1, $array2)
+ private static function deepArrayUnion($array1, $array2)
{
foreach ($array2 as $key => $value) {
if (is_array($value) && isset($array1[$key]) && is_array($array1[$key])) {
@@ -303,30 +286,40 @@ class FOSElasticaExtension extends Extension
* @param $indexName
* @param $typeName
*/
- protected function loadTypePersistenceIntegration(array $typeConfig, ContainerBuilder $container, Definition $typeDef, $indexName, $typeName)
+ private function loadTypePersistenceIntegration(array $typeConfig, ContainerBuilder $container, Definition $typeDef, $indexName, $typeName)
{
$this->loadDriver($container, $typeConfig['driver']);
$elasticaToModelTransformerId = $this->loadElasticaToModelTransformer($typeConfig, $container, $indexName, $typeName);
$modelToElasticaTransformerId = $this->loadModelToElasticaTransformer($typeConfig, $container, $indexName, $typeName);
- $objectPersisterId = $this->loadObjectPersister($typeConfig, $typeDef, $container, $indexName, $typeName, $modelToElasticaTransformerId);
+ $objectPersisterId = $this->loadObjectPersister($typeConfig, $typeDef, $container, $indexName, $typeName, $modelToElasticaTransformerId);
if (isset($typeConfig['provider'])) {
- $this->loadTypeProvider($typeConfig, $container, $objectPersisterId, $typeDef, $indexName, $typeName);
+ $this->loadTypeProvider($typeConfig, $container, $objectPersisterId, $indexName, $typeName);
}
if (isset($typeConfig['finder'])) {
$this->loadTypeFinder($typeConfig, $container, $elasticaToModelTransformerId, $typeDef, $indexName, $typeName);
}
if (isset($typeConfig['listener'])) {
- $this->loadTypeListener($typeConfig, $container, $objectPersisterId, $typeDef, $indexName, $typeName);
+ $this->loadTypeListener($typeConfig, $container, $objectPersisterId, $indexName, $typeName);
}
}
- protected function loadElasticaToModelTransformer(array $typeConfig, ContainerBuilder $container, $indexName, $typeName)
+ /**
+ * Creates and loads an ElasticaToModelTransformer.
+ *
+ * @param array $typeConfig
+ * @param ContainerBuilder $container
+ * @param string $indexName
+ * @param string $typeName
+ * @return string
+ */
+ private function loadElasticaToModelTransformer(array $typeConfig, ContainerBuilder $container, $indexName, $typeName)
{
if (isset($typeConfig['elastica_to_model_transformer']['service'])) {
return $typeConfig['elastica_to_model_transformer']['service'];
}
+
/* Note: transformer services may conflict with "prototype.driver", if
* the index and type names were "prototype" and a driver, respectively.
*/
@@ -339,28 +332,32 @@ class FOSElasticaExtension extends Extension
$argPos = ('propel' === $typeConfig['driver']) ? 0 : 1;
$serviceDef->replaceArgument($argPos, $typeConfig['model']);
- $serviceDef->replaceArgument($argPos + 1, array(
- 'hydrate' => $typeConfig['elastica_to_model_transformer']['hydrate'],
- 'identifier' => $typeConfig['identifier'],
- 'ignore_missing' => $typeConfig['elastica_to_model_transformer']['ignore_missing'],
- 'query_builder_method' => $typeConfig['elastica_to_model_transformer']['query_builder_method']
- ));
+ $serviceDef->replaceArgument($argPos + 1, array_merge($typeConfig['elastica_to_model_transformer'], array(
+ 'identifier' => $typeConfig['identifier'],
+ )));
$container->setDefinition($serviceId, $serviceDef);
return $serviceId;
}
- protected function loadModelToElasticaTransformer(array $typeConfig, ContainerBuilder $container, $indexName, $typeName)
+ /**
+ * Creates and loads a ModelToElasticaTransformer for an index/type.
+ *
+ * @param array $typeConfig
+ * @param ContainerBuilder $container
+ * @param string $indexName
+ * @param string $typeName
+ * @return string
+ */
+ private function loadModelToElasticaTransformer(array $typeConfig, ContainerBuilder $container, $indexName, $typeName)
{
if (isset($typeConfig['model_to_elastica_transformer']['service'])) {
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');
- }
+ $abstractId = $this->serializerConfig ?
+ 'fos_elastica.model_to_elastica_identifier_transformer' :
+ 'fos_elastica.model_to_elastica_transformer';
$serviceId = sprintf('fos_elastica.model_to_elastica_transformer.%s.%s', $indexName, $typeName);
$serviceDef = new DefinitionDecorator($abstractId);
@@ -372,7 +369,18 @@ class FOSElasticaExtension extends Extension
return $serviceId;
}
- protected function loadObjectPersister(array $typeConfig, Definition $typeDef, ContainerBuilder $container, $indexName, $typeName, $transformerId)
+ /**
+ * Creates and loads an object persister for a type.
+ *
+ * @param array $typeConfig
+ * @param Definition $typeDef
+ * @param ContainerBuilder $container
+ * @param string $indexName
+ * @param string $typeName
+ * @param string $transformerId
+ * @return string
+ */
+ private function loadObjectPersister(array $typeConfig, Definition $typeDef, ContainerBuilder $container, $indexName, $typeName, $transformerId)
{
$arguments = array(
$typeDef,
@@ -386,8 +394,9 @@ class FOSElasticaExtension extends Extension
$arguments[] = array(new Reference($callbackId), 'serialize');
} else {
$abstractId = 'fos_elastica.object_persister';
- $arguments[] = $this->typeFields[sprintf('%s/%s', $indexName, $typeName)];
+ $arguments[] = $this->indexConfigs[$indexName]['config']['properties'][$typeName]['properties'];
}
+
$serviceId = sprintf('fos_elastica.object_persister.%s.%s', $indexName, $typeName);
$serviceDef = new DefinitionDecorator($abstractId);
foreach ($arguments as $i => $argument) {
@@ -399,11 +408,22 @@ class FOSElasticaExtension extends Extension
return $serviceId;
}
- protected function loadTypeProvider(array $typeConfig, ContainerBuilder $container, $objectPersisterId, $typeDef, $indexName, $typeName)
+ /**
+ * Loads a provider for a type.
+ *
+ * @param array $typeConfig
+ * @param ContainerBuilder $container
+ * @param string $objectPersisterId
+ * @param string $indexName
+ * @param string $typeName
+ * @return string
+ */
+ private function loadTypeProvider(array $typeConfig, ContainerBuilder $container, $objectPersisterId, $indexName, $typeName)
{
if (isset($typeConfig['provider']['service'])) {
return $typeConfig['provider']['service'];
}
+
/* Note: provider services may conflict with "prototype.driver", if the
* index and type names were "prototype" and a driver, respectively.
*/
@@ -414,16 +434,28 @@ class FOSElasticaExtension extends Extension
$providerDef->replaceArgument(1, $typeConfig['model']);
// Propel provider can simply ignore Doctrine-specific options
$providerDef->replaceArgument(2, array_diff_key($typeConfig['provider'], array('service' => 1)));
+
$container->setDefinition($providerId, $providerDef);
return $providerId;
}
- protected function loadTypeListener(array $typeConfig, ContainerBuilder $container, $objectPersisterId, $typeDef, $indexName, $typeName)
+ /**
+ * Loads doctrine listeners to handle indexing of new or updated objects.
+ *
+ * @param array $typeConfig
+ * @param ContainerBuilder $container
+ * @param string $objectPersisterId
+ * @param string $indexName
+ * @param string $typeName
+ * @return string
+ */
+ private function loadTypeListener(array $typeConfig, ContainerBuilder $container, $objectPersisterId, $indexName, $typeName)
{
if (isset($typeConfig['listener']['service'])) {
return $typeConfig['listener']['service'];
}
+
/* Note: listener services may conflict with "prototype.driver", if the
* index and type names were "prototype" and a driver, respectively.
*/
@@ -438,10 +470,6 @@ class FOSElasticaExtension extends Extension
$listenerDef->replaceArgument(4, new Reference($typeConfig['listener']['logger']));
}
- switch ($typeConfig['driver']) {
- case 'orm': $listenerDef->addTag('doctrine.event_subscriber'); break;
- case 'mongodb': $listenerDef->addTag('doctrine_mongodb.odm.event_subscriber'); break;
- }
if (isset($typeConfig['listener']['is_indexable_callback'])) {
$callback = $typeConfig['listener']['is_indexable_callback'];
@@ -493,7 +521,18 @@ class FOSElasticaExtension extends Extension
return $events;
}
- protected function loadTypeFinder(array $typeConfig, ContainerBuilder $container, $elasticaToModelId, $typeDef, $indexName, $typeName)
+ /**
+ * Loads a Type specific Finder.
+ *
+ * @param array $typeConfig
+ * @param ContainerBuilder $container
+ * @param string $elasticaToModelId
+ * @param Definition $typeDef
+ * @param string $indexName
+ * @param string $typeName
+ * @return string
+ */
+ private function loadTypeFinder(array $typeConfig, ContainerBuilder $container, $elasticaToModelId, Definition $typeDef, $indexName, $typeName)
{
if (isset($typeConfig['finder']['service'])) {
$finderId = $typeConfig['finder']['service'];
@@ -519,39 +558,39 @@ class FOSElasticaExtension extends Extension
/**
* Loads the index manager
*
- * @param array $indexRefsByName
* @param ContainerBuilder $container
**/
- protected function loadIndexManager(array $indexRefsByName, ContainerBuilder $container)
+ private function loadIndexManager(ContainerBuilder $container)
{
$managerDef = $container->getDefinition('fos_elastica.index_manager');
- $managerDef->replaceArgument(0, $indexRefsByName);
+ $managerDef->replaceArgument(0, array_keys($this->clients));
$managerDef->replaceArgument(1, new Reference('fos_elastica.index'));
}
/**
- * Loads the resetter
+ * Makes sure a specific driver has been loaded.
*
- * @param array $indexConfigs
- * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
+ * @param ContainerBuilder $container
+ * @param string $driver
*/
- protected function loadResetter(array $indexConfigs, ContainerBuilder $container)
- {
- $resetterDef = $container->getDefinition('fos_elastica.resetter');
- $resetterDef->replaceArgument(0, $indexConfigs);
- }
-
- protected function loadDriver(ContainerBuilder $container, $driver)
+ private function loadDriver(ContainerBuilder $container, $driver)
{
if (in_array($driver, $this->loadedDrivers)) {
return;
}
+
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load($driver.'.xml');
$this->loadedDrivers[] = $driver;
}
- protected function createDefaultManagerAlias($defaultManager, ContainerBuilder $container)
+ /**
+ * Creates a default manager alias for defined default manager or the first loaded driver.
+ *
+ * @param string $defaultManager
+ * @param ContainerBuilder $container
+ */
+ private function createDefaultManagerAlias($defaultManager, ContainerBuilder $container)
{
if (0 == count($this->loadedDrivers)) {
return;
@@ -568,18 +607,19 @@ class FOSElasticaExtension extends Extension
$container->setAlias('fos_elastica.manager', sprintf('fos_elastica.manager.%s', $defaultManagerService));
}
- protected function cleanUpProperties(&$properties)
+ /**
+ * Returns a reference to a client given its configured name.
+ *
+ * @param string $clientName
+ * @return Reference
+ * @throws \InvalidArgumentException
+ */
+ private function getClient($clientName)
{
- foreach ($properties as &$fieldProperties) {
- if (empty($fieldProperties['fields'])) {
- unset($fieldProperties['fields']);
- } else {
- $this->cleanUpProperties($fieldProperties['fields']);
- }
-
- if (!empty($fieldProperties['properties'])) {
- $this->cleanUpProperties($fieldProperties['properties']);
- }
+ if (!array_key_exists($clientName, $this->clients)) {
+ throw new InvalidArgumentException(sprintf('The elastica client with name "%s" is not defined', $clientName));
}
+
+ return $this->clients[$clientName]['reference'];
}
}
diff --git a/Resources/config/config.xml b/Resources/config/config.xml
index cff2b49..c1ac0f9 100644
--- a/Resources/config/config.xml
+++ b/Resources/config/config.xml
@@ -1,100 +1,34 @@
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
- FOS\ElasticaBundle\Elastica\Client
- FOS\ElasticaBundle\Elastica\Index
- Elastica\Type
- FOS\ElasticaBundle\IndexManager
- FOS\ElasticaBundle\Resetter
- FOS\ElasticaBundle\Finder\TransformedFinder
+ FOS\ElasticaBundle\Elastica\LoggingClient
FOS\ElasticaBundle\Logger\ElasticaLogger
FOS\ElasticaBundle\DataCollector\ElasticaDataCollector
- FOS\ElasticaBundle\Manager\RepositoryManager
- FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerCollection
- FOS\ElasticaBundle\Provider\ProviderRegistry
Symfony\Component\PropertyAccess\PropertyAccessor
- FOS\ElasticaBundle\Persister\ObjectPersister
- FOS\ElasticaBundle\Persister\ObjectSerializerPersister
- FOS\ElasticaBundle\Transformer\ModelToElasticaAutoTransformer
- FOS\ElasticaBundle\Transformer\ModelToElasticaIdentifierTransformer
+
+
+
+
+
%kernel.debug%
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Resources/config/index.xml b/Resources/config/index.xml
new file mode 100644
index 0000000..85f5744
--- /dev/null
+++ b/Resources/config/index.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+ FOS\ElasticaBundle\Elastica\Index
+ Elastica\Type
+ FOS\ElasticaBundle\Index\IndexManager
+ FOS\ElasticaBundle\Index\Resetter
+ FOS\ElasticaBundle\Finder\TransformedFinder
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Resources/config/mongodb.xml b/Resources/config/mongodb.xml
index 0af7aa1..0c6b2af 100644
--- a/Resources/config/mongodb.xml
+++ b/Resources/config/mongodb.xml
@@ -5,7 +5,6 @@
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
-
@@ -18,6 +17,7 @@
+
@@ -33,7 +33,5 @@
-
-
diff --git a/Resources/config/orm.xml b/Resources/config/orm.xml
index 5bd16e5..bf67688 100644
--- a/Resources/config/orm.xml
+++ b/Resources/config/orm.xml
@@ -1,11 +1,10 @@
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
-
@@ -19,6 +18,7 @@
+
@@ -31,10 +31,8 @@
-
-
+
+
-
-
diff --git a/Resources/config/persister.xml b/Resources/config/persister.xml
new file mode 100644
index 0000000..8bd4dca
--- /dev/null
+++ b/Resources/config/persister.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+ FOS\ElasticaBundle\Persister\ObjectPersister
+ FOS\ElasticaBundle\Persister\ObjectSerializerPersister
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Resources/config/propel.xml b/Resources/config/propel.xml
index 7a7d93e..4ccc867 100644
--- a/Resources/config/propel.xml
+++ b/Resources/config/propel.xml
@@ -4,7 +4,6 @@
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
-
@@ -22,7 +21,5 @@
-
-
diff --git a/Resources/config/provider.xml b/Resources/config/provider.xml
new file mode 100644
index 0000000..0732d54
--- /dev/null
+++ b/Resources/config/provider.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+ FOS\ElasticaBundle\Provider\ProviderRegistry
+
+
+
+
+
+
+
+
+
+
diff --git a/Resources/config/transformer.xml b/Resources/config/transformer.xml
new file mode 100644
index 0000000..e3abbbc
--- /dev/null
+++ b/Resources/config/transformer.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+ FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerCollection
+ FOS\ElasticaBundle\Transformer\ModelToElasticaAutoTransformer
+ FOS\ElasticaBundle\Transformer\ModelToElasticaIdentifierTransformer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Tests/Integration/MappingTest.php b/Tests/Integration/MappingTest.php
new file mode 100644
index 0000000..be134ed
--- /dev/null
+++ b/Tests/Integration/MappingTest.php
@@ -0,0 +1,17 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+
+namespace FOS\ElasticaBundle\Tests\Integration;
+
+
+class MappingTest {
+
+}
\ No newline at end of file
From 8540f13bbf606ae409ba3c02f8d9243577d249d5 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Mon, 2 Jun 2014 21:35:51 +1000
Subject: [PATCH 252/447] Fix nested property configuration
Fixes #592
---
DependencyInjection/Configuration.php | 10 ++--
.../DependencyInjection/ConfigurationTest.php | 48 ++++++++++++++++++-
2 files changed, 53 insertions(+), 5 deletions(-)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 7a12e95..db8ae6a 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -20,7 +20,6 @@ class Configuration implements ConfigurationInterface
public function __construct($configArray, $debug)
{
-
$this->configArray = $configArray;
$this->debug = $debug;
}
@@ -386,13 +385,16 @@ class Configuration implements ConfigurationInterface
}
foreach ($index['types'] as $type) {
- if (empty($type['mappings'])) {
- continue;
+ if (array_key_exists('mappings', $type) and !empty($type['mappings'])) {
+ $nestings = array_merge_recursive($nestings, $this->getNestingsForType($type['mappings'], $nestings));
}
- $nestings = array_merge_recursive($nestings, $this->getNestingsForType($type['mappings'], $nestings));
+ if (array_key_exists('properties', $type) and !empty($type['properties'])) {
+ $nestings = array_merge_recursive($nestings, $this->getNestingsForType($type['properties'], $nestings));
+ }
}
}
+
return $nestings;
}
diff --git a/Tests/DependencyInjection/ConfigurationTest.php b/Tests/DependencyInjection/ConfigurationTest.php
index efaaa52..8f0e1b9 100644
--- a/Tests/DependencyInjection/ConfigurationTest.php
+++ b/Tests/DependencyInjection/ConfigurationTest.php
@@ -22,7 +22,7 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
private function getConfigs(array $configArray)
{
- $configuration = new Configuration($configArray, true);
+ $configuration = new Configuration(array($configArray), true);
return $this->processor->processConfiguration($configuration, array($configArray));
}
@@ -257,4 +257,50 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
$this->assertCount(3, $configuration['indexes']['test']['types']['test']['properties']);
}
+
+ public function testNestedProperties()
+ {
+ $configuration = $this->getConfigs(array(
+ 'clients' => array(
+ 'default' => array('url' => 'http://localhost:9200'),
+ ),
+ 'indexes' => array(
+ 'test' => array(
+ 'types' => array(
+ 'user' => array(
+ 'properties' => array(
+ 'field1' => array(),
+ ),
+ 'persistence' => array(),
+ ),
+ 'user_profile' => array(
+ '_parent' => array(
+ 'type' => 'user',
+ 'property' => 'owner',
+ ),
+ 'properties' => array(
+ 'field1' => array(),
+ 'field2' => array(
+ 'type' => 'nested',
+ 'properties' => array(
+ 'nested_field1' => array(
+ 'type' => 'integer'
+ ),
+ 'nested_field2' => array(
+ 'type' => 'object',
+ 'properties' => array(
+ 'id' => array(
+ 'type' => 'integer'
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ ));
+ }
}
From 366fb3960653392becd4cb63be334a459fe3fd18 Mon Sep 17 00:00:00 2001
From: Patrick McAndrew
Date: Wed, 4 Jun 2014 17:26:25 +0100
Subject: [PATCH 253/447] fix method call
---
Resetter.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Resetter.php b/Resetter.php
index d614f1b..9fdcbca 100644
--- a/Resetter.php
+++ b/Resetter.php
@@ -191,7 +191,7 @@ class Resetter
$additionalError = sprintf(
'Tried to delete newly built index %s, but also failed: %s',
$newIndexName,
- $deleteNewIndexException->getError()
+ $deleteNewIndexException->getMessage()
);
}
From 5009673b6a7b3bff3266b4766fe4e892e7a8b1a4 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Sun, 8 Jun 2014 22:35:38 +1000
Subject: [PATCH 254/447] Functional Tests v1
---
.travis.yml | 3 +
Tests/Functional/MappingToElasticaTest.php | 52 +++++++++
Tests/Functional/WebTestCase.php | 40 +++++++
Tests/Functional/app/AppKernel.php | 118 +++++++++++++++++++++
Tests/Functional/app/Basic/bundles.php | 10 ++
Tests/Functional/app/Basic/config.yml | 53 +++++++++
Tests/Functional/app/config/config.yml | 8 ++
composer.json | 13 +--
8 files changed, 291 insertions(+), 6 deletions(-)
create mode 100644 Tests/Functional/MappingToElasticaTest.php
create mode 100644 Tests/Functional/WebTestCase.php
create mode 100644 Tests/Functional/app/AppKernel.php
create mode 100644 Tests/Functional/app/Basic/bundles.php
create mode 100644 Tests/Functional/app/Basic/config.yml
create mode 100644 Tests/Functional/app/config/config.yml
diff --git a/.travis.yml b/.travis.yml
index 72632de..4fdf2b9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,3 +8,6 @@ php:
before_script:
- echo "extension = mongo.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
- composer install --dev --prefer-source
+
+services:
+ - elasticsearch
\ No newline at end of file
diff --git a/Tests/Functional/MappingToElasticaTest.php b/Tests/Functional/MappingToElasticaTest.php
new file mode 100644
index 0000000..3c32e10
--- /dev/null
+++ b/Tests/Functional/MappingToElasticaTest.php
@@ -0,0 +1,52 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace FOS\ElasticaBundle\Tests\Functional;
+
+use Symfony\Bundle\FrameworkBundle\Client;
+
+/**
+ * @group functional
+ */
+class MappingToElasticaTest extends WebTestCase
+{
+ public function testReset()
+ {
+ $client = $this->createClient(array('test_case' => 'Basic'));
+ $resetter = $this->getResetter($client);
+
+ $resetter->resetIndex('index');
+ $resetter->resetIndexType('index', 'type');
+ }
+
+ /**
+ * @param Client $client
+ * @return \FOS\ElasticaBundle\Resetter $resetter
+ */
+ private function getResetter(Client $client)
+ {
+ return $client->getContainer()->get('fos_elastica.resetter');
+ }
+
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $this->deleteTmpDir('Basic');
+ }
+
+ protected function tearDown()
+ {
+ parent::tearDown();
+
+ $this->deleteTmpDir('Basic');
+ }
+}
diff --git a/Tests/Functional/WebTestCase.php b/Tests/Functional/WebTestCase.php
new file mode 100644
index 0000000..38f5489
--- /dev/null
+++ b/Tests/Functional/WebTestCase.php
@@ -0,0 +1,40 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace FOS\ElasticaBundle\Tests\Functional;
+
+use Symfony\Bundle\FrameworkBundle\Tests\Functional\WebTestCase as BaseWebTestCase;
+
+class WebTestCase extends BaseWebTestCase
+{
+ protected static function getKernelClass()
+ {
+ require_once __DIR__.'/app/AppKernel.php';
+
+ return 'FOS\ElasticaBundle\Tests\Functional\app\AppKernel';
+ }
+
+ protected static function createKernel(array $options = array())
+ {
+ $class = self::getKernelClass();
+
+ if (!isset($options['test_case'])) {
+ throw new \InvalidArgumentException('The option "test_case" must be set.');
+ }
+
+ return new $class(
+ $options['test_case'],
+ isset($options['root_config']) ? $options['root_config'] : 'config.yml',
+ isset($options['environment']) ? $options['environment'] : 'foselasticabundle'.strtolower($options['test_case']),
+ isset($options['debug']) ? $options['debug'] : true
+ );
+ }
+}
diff --git a/Tests/Functional/app/AppKernel.php b/Tests/Functional/app/AppKernel.php
new file mode 100644
index 0000000..f47a5b3
--- /dev/null
+++ b/Tests/Functional/app/AppKernel.php
@@ -0,0 +1,118 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace FOS\ElasticaBundle\Tests\Functional\app;
+
+// get the autoload file
+$dir = __DIR__;
+$lastDir = null;
+while ($dir !== $lastDir) {
+ $lastDir = $dir;
+
+ if (file_exists($dir.'/autoload.php')) {
+ require_once $dir.'/autoload.php';
+ break;
+ }
+
+ if (file_exists($dir.'/autoload.php.dist')) {
+ require_once $dir.'/autoload.php.dist';
+ break;
+ }
+
+ if (file_exists($dir.'/vendor/autoload.php')) {
+ require_once $dir.'/vendor/autoload.php';
+ break;
+ }
+
+ $dir = dirname($dir);
+}
+
+use Symfony\Component\Config\Loader\LoaderInterface;
+use Symfony\Component\Filesystem\Filesystem;
+use Symfony\Component\HttpKernel\Kernel;
+
+/**
+ * App Test Kernel for functional tests.
+ *
+ * @author Johannes M. Schmitt
+ */
+class AppKernel extends Kernel
+{
+ private $testCase;
+ private $rootConfig;
+
+ public function __construct($testCase, $rootConfig, $environment, $debug)
+ {
+ if (!is_dir(__DIR__.'/'.$testCase)) {
+ throw new \InvalidArgumentException(sprintf('The test case "%s" does not exist.', $testCase));
+ }
+ $this->testCase = $testCase;
+
+ $fs = new Filesystem();
+ if (!$fs->isAbsolutePath($rootConfig) && !file_exists($rootConfig = __DIR__.'/'.$testCase.'/'.$rootConfig)) {
+ throw new \InvalidArgumentException(sprintf('The root config "%s" does not exist.', $rootConfig));
+ }
+ $this->rootConfig = $rootConfig;
+
+ parent::__construct($environment, $debug);
+ }
+
+ public function registerBundles()
+ {
+ if (!file_exists($filename = $this->getRootDir().'/'.$this->testCase.'/bundles.php')) {
+ throw new \RuntimeException(sprintf('The bundles file "%s" does not exist.', $filename));
+ }
+
+ return include $filename;
+ }
+
+ public function init()
+ {
+ }
+
+ public function getRootDir()
+ {
+ return __DIR__;
+ }
+
+ public function getCacheDir()
+ {
+ return sys_get_temp_dir().'/'.Kernel::VERSION.'/'.$this->testCase.'/cache/'.$this->environment;
+ }
+
+ public function getLogDir()
+ {
+ return sys_get_temp_dir().'/'.Kernel::VERSION.'/'.$this->testCase.'/logs';
+ }
+
+ public function registerContainerConfiguration(LoaderInterface $loader)
+ {
+ $loader->load($this->rootConfig);
+ }
+
+ public function serialize()
+ {
+ return serialize(array($this->testCase, $this->rootConfig, $this->getEnvironment(), $this->isDebug()));
+ }
+
+ public function unserialize($str)
+ {
+ call_user_func_array(array($this, '__construct'), unserialize($str));
+ }
+
+ protected function getKernelParameters()
+ {
+ $parameters = parent::getKernelParameters();
+ $parameters['kernel.test_case'] = $this->testCase;
+
+ return $parameters;
+ }
+}
\ No newline at end of file
diff --git a/Tests/Functional/app/Basic/bundles.php b/Tests/Functional/app/Basic/bundles.php
new file mode 100644
index 0000000..9f23bdf
--- /dev/null
+++ b/Tests/Functional/app/Basic/bundles.php
@@ -0,0 +1,10 @@
+=2.2,<2.5-dev",
+ "doctrine/orm": "~2.2",
"doctrine/mongodb-odm": "1.0.*@dev",
"propel/propel1": "1.6.*",
"pagerfanta/pagerfanta": "1.0.*@dev",
- "knplabs/knp-components": "1.2.*",
- "symfony/expression-language" : "2.4.*@dev"
+ "knplabs/knp-components": "~1.2",
+ "symfony/browser-kit" : "~2.3",
+ "symfony/expression-language" : "~2.4"
},
"suggest": {
- "doctrine/orm": ">=2.2,<2.5-dev",
+ "doctrine/orm": "~2.2",
"doctrine/mongodb-odm": "1.0.*@dev",
"propel/propel1": "1.6.*",
"pagerfanta/pagerfanta": "1.0.*@dev",
- "knplabs/knp-components": "1.2.*",
- "symfony/expression-language" : "2.4.*@dev"
+ "knplabs/knp-components": "~1.2",
+ "symfony/expression-language" : "~2.4"
},
"autoload": {
"psr-0": { "FOS\\ElasticaBundle": "" }
From fe19df365a74373c19161449526d35beb708e49b Mon Sep 17 00:00:00 2001
From: Gilles Doge
Date: Tue, 10 Jun 2014 18:18:30 +0200
Subject: [PATCH 255/447] Make the class of fos_elastica.paginator.subscriber
service configurable
---
Resources/config/config.xml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Resources/config/config.xml b/Resources/config/config.xml
index 7687250..2b48e87 100644
--- a/Resources/config/config.xml
+++ b/Resources/config/config.xml
@@ -21,6 +21,7 @@
FOS\ElasticaBundle\Persister\ObjectSerializerPersister
FOS\ElasticaBundle\Transformer\ModelToElasticaAutoTransformer
FOS\ElasticaBundle\Transformer\ModelToElasticaIdentifierTransformer
+ FOS\ElasticaBundle\Subscriber\PaginateElasticaQuerySubscriber
@@ -87,7 +88,7 @@
-
+
From 66d241099984810e26ae809629b23e7dcade116f Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Mon, 16 Jun 2014 15:57:27 +1000
Subject: [PATCH 256/447] Move Indexable callback calculations to a new service
---
DependencyInjection/Configuration.php | 17 +-
DependencyInjection/FOSElasticaExtension.php | 24 ++-
Doctrine/Listener.php | 172 +++++-------------
Persister/ObjectPersister.php | 21 +++
Provider/Indexable.php | 174 +++++++++++++++++++
Provider/IndexableInterface.php | 25 +++
Resources/config/config.xml | 5 +
Resources/config/mongodb.xml | 3 +-
Resources/config/orm.xml | 6 +-
Tests/Doctrine/AbstractListenerTest.php | 142 +++++++--------
Tests/Functional/IndexableCallbackTest.php | 51 ++++++
Tests/Functional/TypeObj.php | 25 +++
Tests/Functional/app/Basic/config.yml | 2 +-
Tests/Functional/app/ORM/bundles.php | 11 ++
Tests/Functional/app/ORM/config.yml | 44 +++++
Tests/Provider/IndexableTest.php | 91 ++++++++++
composer.json | 1 +
17 files changed, 584 insertions(+), 230 deletions(-)
create mode 100644 Provider/Indexable.php
create mode 100644 Provider/IndexableInterface.php
create mode 100644 Tests/Functional/IndexableCallbackTest.php
create mode 100644 Tests/Functional/TypeObj.php
create mode 100644 Tests/Functional/app/ORM/bundles.php
create mode 100644 Tests/Functional/app/ORM/config.yml
create mode 100644 Tests/Provider/IndexableTest.php
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index ce1c982..f32f295 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -187,9 +187,23 @@ class Configuration implements ConfigurationInterface
return $v;
})
->end()
+ ->beforeNormalization()
+ ->ifTrue(function ($v) {
+ return isset($v['persistence']) &&
+ isset($v['persistence']['listener']) &&
+ isset($v['persistence']['listener']['is_indexable_callback']);
+ })
+ ->then(function ($v) {
+ $v['indexable_callback'] = $v['persistence']['listener']['is_indexable_callback'];
+ unset($v['persistence']['listener']['is_indexable_callback']);
+
+ return $v;
+ })
+ ->end()
->children()
->scalarNode('index_analyzer')->end()
->scalarNode('search_analyzer')->end()
+ ->scalarNode('indexable_callback')->end()
->append($this->getPersistenceNode())
->append($this->getSerializerNode())
->end()
@@ -230,7 +244,7 @@ class Configuration implements ConfigurationInterface
unset($v[$prop]);
}
}
-
+
return $v;
})
->end()
@@ -674,7 +688,6 @@ class Configuration implements ConfigurationInterface
->treatTrueLike('fos_elastica.logger')
->end()
->scalarNode('service')->end()
- ->variableNode('is_indexable_callback')->defaultNull()->end()
->end()
->end()
->arrayNode('finder')
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 1529544..9e50c0b 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -186,8 +186,11 @@ class FOSElasticaExtension extends Extension
*/
protected function loadTypes(array $types, ContainerBuilder $container, $indexName, $indexId, array $typePrototypeConfig)
{
+ $indexableCallbacks = array();
+
foreach ($types as $name => $type) {
$type = self::deepArrayUnion($typePrototypeConfig, $type);
+ $typeName = sprintf('%s/%s', $indexName, $name);
$typeId = sprintf('%s.%s', $indexId, $name);
$typeDefArgs = array($name);
$typeDef = new Definition('%fos_elastica.type.class%', $typeDefArgs);
@@ -240,7 +243,6 @@ class FOSElasticaExtension extends Extension
}
if (isset($type['_parent'])) {
$this->indexConfigs[$indexName]['config']['properties'][$name]['_parent'] = array('type' => $type['_parent']['type']);
- $typeName = sprintf('%s/%s', $indexName, $name);
$this->typeFields[$typeName]['_parent'] = $type['_parent'];
}
if (isset($type['persistence'])) {
@@ -252,6 +254,9 @@ class FOSElasticaExtension extends Extension
if (isset($type['search_analyzer'])) {
$this->indexConfigs[$indexName]['config']['properties'][$name]['search_analyzer'] = $type['search_analyzer'];
}
+ if (isset($type['indexable_callback'])) {
+ $indexableCallbacks[$typeName] = $type['indexable_callback'];
+ }
if (isset($type['index'])) {
$this->indexConfigs[$indexName]['config']['properties'][$name]['index'] = $type['index'];
}
@@ -271,6 +276,9 @@ class FOSElasticaExtension extends Extension
}
}
}
+
+ $indexable = $container->getDefinition('fos_elastica.indexable');
+ $indexable->replaceArgument(0, $indexableCallbacks);
}
/**
@@ -431,8 +439,7 @@ class FOSElasticaExtension extends Extension
$listenerId = sprintf('fos_elastica.listener.%s.%s', $indexName, $typeName);
$listenerDef = new DefinitionDecorator($abstractListenerId);
$listenerDef->replaceArgument(0, new Reference($objectPersisterId));
- $listenerDef->replaceArgument(1, $typeConfig['model']);
- $listenerDef->replaceArgument(2, $this->getDoctrineEvents($typeConfig));
+ $listenerDef->replaceArgument(1, $this->getDoctrineEvents($typeConfig));
$listenerDef->replaceArgument(3, $typeConfig['identifier']);
if ($typeConfig['listener']['logger']) {
$listenerDef->replaceArgument(4, new Reference($typeConfig['listener']['logger']));
@@ -442,18 +449,7 @@ class FOSElasticaExtension extends Extension
case 'orm': $listenerDef->addTag('doctrine.event_subscriber'); break;
case 'mongodb': $listenerDef->addTag('doctrine_mongodb.odm.event_subscriber'); break;
}
- if (isset($typeConfig['listener']['is_indexable_callback'])) {
- $callback = $typeConfig['listener']['is_indexable_callback'];
- if (is_array($callback)) {
- list($class) = $callback + array(null);
- if (is_string($class) && !class_exists($class)) {
- $callback[0] = new Reference($class);
- }
- }
-
- $listenerDef->addMethodCall('setIsIndexableCallback', array($callback));
- }
$container->setDefinition($listenerId, $listenerDef);
return $listenerId;
diff --git a/Doctrine/Listener.php b/Doctrine/Listener.php
index ff9fc60..4a01aa1 100644
--- a/Doctrine/Listener.php
+++ b/Doctrine/Listener.php
@@ -2,15 +2,13 @@
namespace FOS\ElasticaBundle\Doctrine;
-use Psr\Log\LoggerInterface;
use Doctrine\Common\EventArgs;
use Doctrine\Common\EventSubscriber;
use FOS\ElasticaBundle\Persister\ObjectPersisterInterface;
use FOS\ElasticaBundle\Persister\ObjectPersister;
-use Symfony\Component\ExpressionLanguage\Expression;
-use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
-use Symfony\Component\ExpressionLanguage\SyntaxError;
+use FOS\ElasticaBundle\Provider\IndexableInterface;
use Symfony\Component\PropertyAccess\PropertyAccess;
+use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
/**
* Automatically update ElasticSearch based on changes to the Doctrine source
@@ -25,13 +23,6 @@ class Listener implements EventSubscriber
*/
protected $objectPersister;
- /**
- * Class of the domain model
- *
- * @var string
- */
- protected $objectClass;
-
/**
* List of subscribed events
*
@@ -46,13 +37,6 @@ class Listener implements EventSubscriber
*/
protected $esIdentifierField;
- /**
- * Callback for determining if an object should be indexed
- *
- * @var mixed
- */
- protected $isIndexableCallback;
-
/**
* Objects scheduled for insertion and replacement
*/
@@ -64,13 +48,6 @@ class Listener implements EventSubscriber
*/
public $scheduledForDeletion = array();
- /**
- * An instance of ExpressionLanguage
- *
- * @var ExpressionLanguage
- */
- protected $expressionLanguage;
-
/**
* PropertyAccessor instance
*
@@ -78,26 +55,36 @@ class Listener implements EventSubscriber
*/
protected $propertyAccessor;
+ /**
+ * @var \FOS\ElasticaBundle\Provider\IndexableInterface
+ */
+ private $indexable;
+
/**
* Constructor.
*
* @param ObjectPersisterInterface $objectPersister
- * @param string $objectClass
- * @param array $events
- * @param string $esIdentifierField
+ * @param array $events
+ * @param IndexableInterface $indexable
+ * @param string $esIdentifierField
+ * @param null $logger
*/
- public function __construct(ObjectPersisterInterface $objectPersister, $objectClass, array $events, $esIdentifierField = 'id', $logger = null)
- {
- $this->objectPersister = $objectPersister;
- $this->objectClass = $objectClass;
- $this->events = $events;
- $this->esIdentifierField = $esIdentifierField;
+ public function __construct(
+ ObjectPersisterInterface $objectPersister,
+ array $events,
+ IndexableInterface $indexable,
+ $esIdentifierField = 'id',
+ $logger = null
+ ) {
+ $this->esIdentifierField = $esIdentifierField;
+ $this->events = $events;
+ $this->indexable = $indexable;
+ $this->objectPersister = $objectPersister;
+ $this->propertyAccessor = PropertyAccess::createPropertyAccessor();
if ($logger) {
$this->objectPersister->setLogger($logger);
}
-
- $this->propertyAccessor = PropertyAccess::createPropertyAccessor();
}
/**
@@ -108,82 +95,6 @@ class Listener implements EventSubscriber
return $this->events;
}
- /**
- * Set the callback for determining object index eligibility.
- *
- * If callback is a string, it must be public method on the object class
- * that expects no arguments and returns a boolean. Otherwise, the callback
- * should expect the object for consideration as its only argument and
- * return a boolean.
- *
- * @param callback $callback
- * @throws \RuntimeException if the callback is not callable
- */
- public function setIsIndexableCallback($callback)
- {
- if (is_string($callback)) {
- if (!is_callable(array($this->objectClass, $callback))) {
- if (false !== ($expression = $this->getExpressionLanguage())) {
- $callback = new Expression($callback);
- try {
- $expression->compile($callback, array($this->getExpressionVar()));
- } catch (SyntaxError $e) {
- throw new \RuntimeException(sprintf('Indexable callback %s::%s() is not callable or a valid expression.', $this->objectClass, $callback), 0, $e);
- }
- } else {
- throw new \RuntimeException(sprintf('Indexable callback %s::%s() is not callable.', $this->objectClass, $callback));
- }
- }
- } elseif (!is_callable($callback)) {
- if (is_array($callback)) {
- list($class, $method) = $callback + array(null, null);
- if (is_object($class)) {
- $class = get_class($class);
- }
-
- if ($class && $method) {
- throw new \RuntimeException(sprintf('Indexable callback %s::%s() is not callable.', $class, $method));
- }
- }
- throw new \RuntimeException('Indexable callback is not callable.');
- }
-
- $this->isIndexableCallback = $callback;
- }
-
- /**
- * Return whether the object is indexable with respect to the callback.
- *
- * @param object $object
- * @return boolean
- */
- protected function isObjectIndexable($object)
- {
- if (!$this->isIndexableCallback) {
- return true;
- }
-
- if ($this->isIndexableCallback instanceof Expression) {
- return $this->getExpressionLanguage()->evaluate($this->isIndexableCallback, array($this->getExpressionVar($object) => $object));
- }
-
- return is_string($this->isIndexableCallback)
- ? call_user_func(array($object, $this->isIndexableCallback))
- : call_user_func($this->isIndexableCallback, $object);
- }
-
- /**
- * @param mixed $object
- * @return string
- */
- private function getExpressionVar($object = null)
- {
- $class = $object ?: $this->objectClass;
- $ref = new \ReflectionClass($class);
-
- return strtolower($ref->getShortName());
- }
-
/**
* Provides unified method for retrieving a doctrine object from an EventArgs instance
*
@@ -204,27 +115,11 @@ class Listener implements EventSubscriber
throw new \RuntimeException('Unable to retrieve object from EventArgs.');
}
- /**
- * @return bool|ExpressionLanguage
- */
- private function getExpressionLanguage()
- {
- if (null === $this->expressionLanguage) {
- if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
- return false;
- }
-
- $this->expressionLanguage = new ExpressionLanguage();
- }
-
- return $this->expressionLanguage;
- }
-
public function postPersist(EventArgs $eventArgs)
{
$entity = $this->getDoctrineObject($eventArgs);
- if ($entity instanceof $this->objectClass && $this->isObjectIndexable($entity)) {
+ if ($this->objectPersister->handlesObject($entity) && $this->isObjectIndexable($entity)) {
$this->scheduledForInsertion[] = $entity;
}
}
@@ -233,7 +128,7 @@ class Listener implements EventSubscriber
{
$entity = $this->getDoctrineObject($eventArgs);
- if ($entity instanceof $this->objectClass) {
+ if ($this->objectPersister->handlesObject($entity)) {
if ($this->isObjectIndexable($entity)) {
$this->scheduledForUpdate[] = $entity;
} else {
@@ -251,7 +146,7 @@ class Listener implements EventSubscriber
{
$entity = $this->getDoctrineObject($eventArgs);
- if ($entity instanceof $this->objectClass) {
+ if ($this->objectPersister->handlesObject($entity)) {
$this->scheduleForDeletion($entity);
}
}
@@ -305,4 +200,19 @@ class Listener implements EventSubscriber
$this->scheduledForDeletion[] = $identifierValue;
}
}
+
+ /**
+ * Checks if the object is indexable or not.
+ *
+ * @param object $object
+ * @return bool
+ */
+ private function isObjectIndexable($object)
+ {
+ return $this->indexable->isObjectIndexable(
+ $this->objectPersister->getType()->getIndex()->getName(),
+ $this->objectPersister->getType()->getName(),
+ $object
+ );
+ }
}
diff --git a/Persister/ObjectPersister.php b/Persister/ObjectPersister.php
index c279ec7..2b6a8af 100644
--- a/Persister/ObjectPersister.php
+++ b/Persister/ObjectPersister.php
@@ -31,6 +31,27 @@ class ObjectPersister implements ObjectPersisterInterface
$this->fields = $fields;
}
+ /**
+ * @internal Temporary method that will be removed.
+ *
+ * @return Type
+ */
+ public function getType()
+ {
+ return $this->type;
+ }
+
+ /**
+ * If the ObjectPersister handles a given object.
+ *
+ * @param object $object
+ * @return bool
+ */
+ public function handlesObject($object)
+ {
+ return $object instanceof $this->objectClass;
+ }
+
public function setLogger(LoggerInterface $logger)
{
$this->logger = $logger;
diff --git a/Provider/Indexable.php b/Provider/Indexable.php
new file mode 100644
index 0000000..b388c58
--- /dev/null
+++ b/Provider/Indexable.php
@@ -0,0 +1,174 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace FOS\ElasticaBundle\Provider;
+
+use Symfony\Component\ExpressionLanguage\Expression;
+use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
+use Symfony\Component\ExpressionLanguage\SyntaxError;
+use Symfony\Component\PropertyAccess\PropertyAccess;
+use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
+
+class Indexable implements IndexableInterface
+{
+ /**
+ * An array of raw configured callbacks for all types.
+ *
+ * @var array
+ */
+ private $callbacks = array();
+
+ /**
+ * An instance of ExpressionLanguage
+ *
+ * @var ExpressionLanguage
+ */
+ private $expressionLanguage;
+
+ /**
+ * An array of initialised callbacks.
+ *
+ * @var array
+ */
+ private $initialisedCallbacks = array();
+
+ /**
+ * PropertyAccessor instance
+ *
+ * @var PropertyAccessorInterface
+ */
+ private $propertyAccessor;
+
+ /**
+ * @param array $callbacks
+ */
+ public function __construct(array $callbacks)
+ {
+ $this->callbacks = $callbacks;
+ $this->propertyAccessor = PropertyAccess::createPropertyAccessor();
+ }
+
+ /**
+ * Return whether the object is indexable with respect to the callback.
+ *
+ * @param string $indexName
+ * @param string $typeName
+ * @param mixed $object
+ * @return bool
+ */
+ public function isObjectIndexable($indexName, $typeName, $object)
+ {
+ $type = sprintf('%s/%s', $indexName, $typeName);
+ $callback = $this->getCallback($type, $object);
+ if (!$callback) {
+ return true;
+ }
+
+ if ($callback instanceof Expression) {
+ return $this->getExpressionLanguage()->evaluate($callback, array(
+ 'object' => $object,
+ $this->getExpressionVar($object) => $object
+ ));
+ }
+
+ return is_string($callback)
+ ? call_user_func(array($object, $callback))
+ : call_user_func($callback, $object);
+ }
+
+ /**
+ * Builds and initialises a callback.
+ *
+ * @param string $type
+ * @param object $object
+ * @return mixed
+ */
+ private function buildCallback($type, $object)
+ {
+ if (!array_key_exists($type, $this->callbacks)) {
+ throw new \InvalidArgumentException(sprintf('Callback for type "%s" is not configured', $type));
+ }
+
+ $callback = $this->callbacks[$type];
+
+ if (is_callable($callback) or is_callable(array($object, $callback))) {
+ return $callback;
+ }
+
+ if (is_array($callback)) {
+ list($class, $method) = $callback + array(null, null);
+ if (is_object($class)) {
+ $class = get_class($class);
+ }
+
+ if ($class && $method) {
+ throw new \InvalidArgumentException(sprintf('Callback for type "%s", "%s::%s()", is not callable.', $type, $class, $method));
+ }
+ }
+
+ if (is_string($callback) && $expression = $this->getExpressionLanguage()) {
+ $callback = new Expression($callback);
+
+ try {
+ $expression->compile($callback, array('object', $this->getExpressionVar($object)));
+
+ return $callback;
+ } catch (SyntaxError $e) {
+ throw new \InvalidArgumentException(sprintf('Callback for type "%s" is an invalid expression', $type), $e->getCode(), $e);
+ }
+ }
+
+ throw new \InvalidArgumentException(sprintf('Callback for type "%s" is not a valid callback.', $type));
+ }
+
+ /**
+ * Retreives a cached callback, or creates a new callback if one is not found.
+ *
+ * @param string $type
+ * @param object $object
+ * @return mixed
+ */
+ private function getCallback($type, $object)
+ {
+ if (!array_key_exists($type, $this->initialisedCallbacks)) {
+ $this->initialisedCallbacks[$type] = $this->buildCallback($type, $object);
+ }
+
+ return $this->initialisedCallbacks[$type];
+ }
+
+ /**
+ * @return bool|ExpressionLanguage
+ */
+ private function getExpressionLanguage()
+ {
+ if (null === $this->expressionLanguage) {
+ if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
+ return false;
+ }
+
+ $this->expressionLanguage = new ExpressionLanguage();
+ }
+
+ return $this->expressionLanguage;
+ }
+
+ /**
+ * @param mixed $object
+ * @return string
+ */
+ private function getExpressionVar($object = null)
+ {
+ $ref = new \ReflectionClass($object);
+
+ return strtolower($ref->getShortName());
+ }
+}
diff --git a/Provider/IndexableInterface.php b/Provider/IndexableInterface.php
new file mode 100644
index 0000000..4871b58
--- /dev/null
+++ b/Provider/IndexableInterface.php
@@ -0,0 +1,25 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace FOS\ElasticaBundle\Provider;
+
+interface IndexableInterface
+{
+ /**
+ * Checks if an object passed should be indexable or not.
+ *
+ * @param string $indexName
+ * @param string $typeName
+ * @param mixed $object
+ * @return bool
+ */
+ public function isObjectIndexable($indexName, $typeName, $object);
+}
diff --git a/Resources/config/config.xml b/Resources/config/config.xml
index 7687250..f4b2606 100644
--- a/Resources/config/config.xml
+++ b/Resources/config/config.xml
@@ -9,6 +9,7 @@
FOS\ElasticaBundle\DynamicIndex
Elastica\Type
FOS\ElasticaBundle\IndexManager
+ FOS\ElasticaBundle\Provider\Indexable
FOS\ElasticaBundle\Resetter
FOS\ElasticaBundle\Finder\TransformedFinder
FOS\ElasticaBundle\Logger\ElasticaLogger
@@ -44,6 +45,10 @@
+
+
+
+
diff --git a/Resources/config/mongodb.xml b/Resources/config/mongodb.xml
index 0af7aa1..e575e5d 100644
--- a/Resources/config/mongodb.xml
+++ b/Resources/config/mongodb.xml
@@ -15,9 +15,10 @@
-
+
+
diff --git a/Resources/config/orm.xml b/Resources/config/orm.xml
index 5bd16e5..43d1670 100644
--- a/Resources/config/orm.xml
+++ b/Resources/config/orm.xml
@@ -15,10 +15,10 @@
-
-
-
+
+
+
diff --git a/Tests/Doctrine/AbstractListenerTest.php b/Tests/Doctrine/AbstractListenerTest.php
index ee657f1..de5ba0c 100644
--- a/Tests/Doctrine/AbstractListenerTest.php
+++ b/Tests/Doctrine/AbstractListenerTest.php
@@ -11,12 +11,12 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
{
public function testObjectInsertedOnPersist()
{
- $persister = $this->getMockPersister();
-
$entity = new Listener\Entity(1);
+ $persister = $this->getMockPersister($entity, 'index', 'type');
$eventArgs = $this->createLifecycleEventArgs($entity, $this->getMockObjectManager());
+ $indexable = $this->getMockIndexable('index', 'type', $entity, true);
- $listener = $this->createListener($persister, get_class($entity), array());
+ $listener = $this->createListener($persister, array(), $indexable);
$listener->postPersist($eventArgs);
$this->assertEquals($entity, current($listener->scheduledForInsertion));
@@ -28,18 +28,14 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
$listener->postFlush($eventArgs);
}
- /**
- * @dataProvider provideIsIndexableCallbacks
- */
- public function testNonIndexableObjectNotInsertedOnPersist($isIndexableCallback)
+ public function testNonIndexableObjectNotInsertedOnPersist()
{
- $persister = $this->getMockPersister();
-
- $entity = new Listener\Entity(1, false);
+ $entity = new Listener\Entity(1);
+ $persister = $this->getMockPersister($entity, 'index', 'type');
$eventArgs = $this->createLifecycleEventArgs($entity, $this->getMockObjectManager());
+ $indexable = $this->getMockIndexable('index', 'type', $entity, false);
- $listener = $this->createListener($persister, get_class($entity), array());
- $listener->setIsIndexableCallback($isIndexableCallback);
+ $listener = $this->createListener($persister, array(), $indexable);
$listener->postPersist($eventArgs);
$this->assertEmpty($listener->scheduledForInsertion);
@@ -54,12 +50,12 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
public function testObjectReplacedOnUpdate()
{
- $persister = $this->getMockPersister();
-
$entity = new Listener\Entity(1);
+ $persister = $this->getMockPersister($entity, 'index', 'type');
$eventArgs = $this->createLifecycleEventArgs($entity, $this->getMockObjectManager());
+ $indexable = $this->getMockIndexable('index', 'type', $entity, true);
- $listener = $this->createListener($persister, get_class($entity), array());
+ $listener = $this->createListener($persister, array(), $indexable);
$listener->postUpdate($eventArgs);
$this->assertEquals($entity, current($listener->scheduledForUpdate));
@@ -73,17 +69,15 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
$listener->postFlush($eventArgs);
}
- /**
- * @dataProvider provideIsIndexableCallbacks
- */
- public function testNonIndexableObjectRemovedOnUpdate($isIndexableCallback)
+ public function testNonIndexableObjectRemovedOnUpdate()
{
$classMetadata = $this->getMockClassMetadata();
$objectManager = $this->getMockObjectManager();
- $persister = $this->getMockPersister();
- $entity = new Listener\Entity(1, false);
+ $entity = new Listener\Entity(1);
+ $persister = $this->getMockPersister($entity, 'index', 'type');
$eventArgs = $this->createLifecycleEventArgs($entity, $objectManager);
+ $indexable = $this->getMockIndexable('index', 'type', $entity, false);
$objectManager->expects($this->any())
->method('getClassMetadata')
@@ -95,8 +89,7 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
->with($entity, 'id')
->will($this->returnValue($entity->getId()));
- $listener = $this->createListener($persister, get_class($entity), array());
- $listener->setIsIndexableCallback($isIndexableCallback);
+ $listener = $this->createListener($persister, array(), $indexable);
$listener->postUpdate($eventArgs);
$this->assertEmpty($listener->scheduledForUpdate);
@@ -115,10 +108,11 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
{
$classMetadata = $this->getMockClassMetadata();
$objectManager = $this->getMockObjectManager();
- $persister = $this->getMockPersister();
$entity = new Listener\Entity(1);
+ $persister = $this->getMockPersister($entity, 'index', 'type');
$eventArgs = $this->createLifecycleEventArgs($entity, $objectManager);
+ $indexable = $this->getMockIndexable('index', 'type', $entity);
$objectManager->expects($this->any())
->method('getClassMetadata')
@@ -130,7 +124,7 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
->with($entity, 'id')
->will($this->returnValue($entity->getId()));
- $listener = $this->createListener($persister, get_class($entity), array());
+ $listener = $this->createListener($persister, array(), $indexable);
$listener->preRemove($eventArgs);
$this->assertEquals($entity->getId(), current($listener->scheduledForDeletion));
@@ -146,11 +140,12 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
{
$classMetadata = $this->getMockClassMetadata();
$objectManager = $this->getMockObjectManager();
- $persister = $this->getMockPersister();
$entity = new Listener\Entity(1);
$entity->identifier = 'foo';
+ $persister = $this->getMockPersister($entity, 'index', 'type');
$eventArgs = $this->createLifecycleEventArgs($entity, $objectManager);
+ $indexable = $this->getMockIndexable('index', 'type', $entity);
$objectManager->expects($this->any())
->method('getClassMetadata')
@@ -162,7 +157,7 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
->with($entity, 'identifier')
->will($this->returnValue($entity->getId()));
- $listener = $this->createListener($persister, get_class($entity), array(), 'identifier');
+ $listener = $this->createListener($persister, array(), $indexable, 'identifier');
$listener->preRemove($eventArgs);
$this->assertEquals($entity->identifier, current($listener->scheduledForDeletion));
@@ -174,36 +169,6 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
$listener->postFlush($eventArgs);
}
- /**
- * @dataProvider provideInvalidIsIndexableCallbacks
- * @expectedException \RuntimeException
- */
- public function testInvalidIsIndexableCallbacks($isIndexableCallback)
- {
- $listener = $this->createListener($this->getMockPersister(), 'FOS\ElasticaBundle\Tests\Doctrine\Listener\Entity', array());
- $listener->setIsIndexableCallback($isIndexableCallback);
- }
-
- public function provideInvalidIsIndexableCallbacks()
- {
- return array(
- array('nonexistentEntityMethod'),
- array(array(new Listener\IndexableDecider(), 'internalMethod')),
- array(42),
- array('entity.getIsIndexable() && nonexistentEntityFunction()'),
- );
- }
-
- public function provideIsIndexableCallbacks()
- {
- return array(
- array('getIsIndexable'),
- array(array(new Listener\IndexableDecider(), 'isIndexable')),
- array(function(Listener\Entity $entity) { return $entity->getIsIndexable(); }),
- array('entity.getIsIndexable()')
- );
- }
-
abstract protected function getLifecycleEventArgsClass();
abstract protected function getListenerClass();
@@ -240,9 +205,48 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
->getMock();
}
- private function getMockPersister()
+ private function getMockPersister($object, $indexName, $typeName)
{
- return $this->getMock('FOS\ElasticaBundle\Persister\ObjectPersisterInterface');
+ $mock = $this->getMockBuilder('FOS\ElasticaBundle\Persister\ObjectPersister')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $mock->expects($this->any())
+ ->method('handlesObject')
+ ->with($object)
+ ->will($this->returnValue(true));
+
+ $index = $this->getMockBuilder('Elastica\Index')->disableOriginalConstructor()->getMock();
+ $index->expects($this->any())
+ ->method('getName')
+ ->will($this->returnValue($indexName));
+ $type = $this->getMockBuilder('Elastica\Type')->disableOriginalConstructor()->getMock();
+ $type->expects($this->any())
+ ->method('getName')
+ ->will($this->returnValue($typeName));
+ $type->expects($this->any())
+ ->method('getIndex')
+ ->will($this->returnValue($index));
+
+ $mock->expects($this->any())
+ ->method('getType')
+ ->will($this->returnValue($type));
+
+ return $mock;
+ }
+
+ private function getMockIndexable($indexName, $typeName, $object, $return = null)
+ {
+ $mock = $this->getMock('FOS\ElasticaBundle\Provider\IndexableInterface');
+
+ if (null !== $return) {
+ $mock->expects($this->once())
+ ->method('isObjectIndexable')
+ ->with($indexName, $typeName, $object)
+ ->will($this->returnValue($return));
+ }
+
+ return $mock;
}
}
@@ -251,33 +255,15 @@ namespace FOS\ElasticaBundle\Tests\Doctrine\Listener;
class Entity
{
private $id;
- private $isIndexable;
- public function __construct($id, $isIndexable = true)
+ public function __construct($id)
{
$this->id = $id;
- $this->isIndexable = $isIndexable;
}
public function getId()
{
return $this->id;
}
-
- public function getIsIndexable()
- {
- return $this->isIndexable;
- }
}
-class IndexableDecider
-{
- public function isIndexable(Entity $entity)
- {
- return $entity->getIsIndexable();
- }
-
- protected function internalMethod()
- {
- }
-}
diff --git a/Tests/Functional/IndexableCallbackTest.php b/Tests/Functional/IndexableCallbackTest.php
new file mode 100644
index 0000000..89fca1d
--- /dev/null
+++ b/Tests/Functional/IndexableCallbackTest.php
@@ -0,0 +1,51 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace FOS\ElasticaBundle\Tests\Functional;
+
+/**
+ * @group functional
+ */
+class IndexableCallbackTest extends WebTestCase
+{
+ /**
+ * 2 reasons for this test:
+ *
+ * 1) To test that the configuration rename from is_indexable_callback under the listener
+ * key is respected, and
+ * 2) To test the Extension's set up of the Indexable service.
+ */
+ public function testIndexableCallback()
+ {
+ $client = $this->createClient(array('test_case' => 'ORM'));
+
+ /** @var \FOS\ElasticaBundle\Provider\Indexable $in */
+ $in = $client->getContainer()->get('fos_elastica.indexable');
+
+ $this->assertTrue($in->isObjectIndexable('index', 'type', new TypeObj()));
+ $this->assertFalse($in->isObjectIndexable('index', 'type2', new TypeObj()));
+ $this->assertFalse($in->isObjectIndexable('index', 'type3', new TypeObj()));
+ }
+
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $this->deleteTmpDir('ORM');
+ }
+
+ protected function tearDown()
+ {
+ parent::tearDown();
+
+ $this->deleteTmpDir('ORM');
+ }
+}
diff --git a/Tests/Functional/TypeObj.php b/Tests/Functional/TypeObj.php
new file mode 100644
index 0000000..c264e7b
--- /dev/null
+++ b/Tests/Functional/TypeObj.php
@@ -0,0 +1,25 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace FOS\ElasticaBundle\Tests\Functional;
+
+class TypeObj
+{
+ public function isIndexable()
+ {
+ return true;
+ }
+
+ public function isntIndexable()
+ {
+ return false;
+ }
+}
diff --git a/Tests/Functional/app/Basic/config.yml b/Tests/Functional/app/Basic/config.yml
index 7025532..09e5aec 100644
--- a/Tests/Functional/app/Basic/config.yml
+++ b/Tests/Functional/app/Basic/config.yml
@@ -50,4 +50,4 @@ fos_elastica:
_parent:
type: "parent"
property: "parent"
- identifier: "id"
\ No newline at end of file
+ identifier: "id"
diff --git a/Tests/Functional/app/ORM/bundles.php b/Tests/Functional/app/ORM/bundles.php
new file mode 100644
index 0000000..d0b6efb
--- /dev/null
+++ b/Tests/Functional/app/ORM/bundles.php
@@ -0,0 +1,11 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace FOS\ElasticaBundle\Tests\Provider;
+
+use FOS\ElasticaBundle\Provider\Indexable;
+
+class IndexableTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider provideIsIndexableCallbacks
+ */
+ public function testValidIndexableCallbacks($callback, $return)
+ {
+ $indexable = new Indexable(array(
+ 'index/type' => $callback
+ ));
+ $index = $indexable->isObjectIndexable('index', 'type', new Entity);
+
+ $this->assertEquals($return, $index);
+ }
+
+ /**
+ * @dataProvider provideInvalidIsIndexableCallbacks
+ * @expectedException \InvalidArgumentException
+ */
+ public function testInvalidIsIndexableCallbacks($callback)
+ {
+ $indexable = new Indexable(array(
+ 'index/type' => $callback
+ ));
+ $indexable->isObjectIndexable('index', 'type', new Entity);
+ }
+
+ public function provideInvalidIsIndexableCallbacks()
+ {
+ return array(
+ array('nonexistentEntityMethod'),
+ array(array(new IndexableDecider(), 'internalMethod')),
+ array(42),
+ array('entity.getIsIndexable() && nonexistentEntityFunction()'),
+ );
+ }
+
+ public function provideIsIndexableCallbacks()
+ {
+ return array(
+ array('isIndexable', false),
+ array(array(new IndexableDecider(), 'isIndexable'), true),
+ array(function(Entity $entity) { return $entity->maybeIndex(); }, true),
+ array('entity.maybeIndex()', true),
+ array('!object.isIndexable() && entity.property == "abc"', true),
+ array('entity.property != "abc"', false),
+ );
+ }
+}
+
+class Entity
+{
+ public $property = 'abc';
+
+ public function isIndexable()
+ {
+ return false;
+ }
+
+ public function maybeIndex()
+ {
+ return true;
+ }
+}
+
+class IndexableDecider
+{
+ public function isIndexable(Entity $entity)
+ {
+ return !$entity->isIndexable();
+ }
+
+ protected function internalMethod()
+ {
+ }
+}
diff --git a/composer.json b/composer.json
index 8783822..d67e329 100644
--- a/composer.json
+++ b/composer.json
@@ -21,6 +21,7 @@
},
"require-dev":{
"doctrine/orm": "~2.2",
+ "doctrine/doctrine-bundle": "~1.2@beta",
"doctrine/mongodb-odm": "1.0.*@dev",
"propel/propel1": "1.6.*",
"pagerfanta/pagerfanta": "1.0.*@dev",
From e54cc3c2434cebc341f06d96596f11f14052094c Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Mon, 16 Jun 2014 16:17:04 +1000
Subject: [PATCH 257/447] Implement callback checking in the provider
---
Doctrine/AbstractProvider.php | 24 +++++--
Persister/ObjectPersisterInterface.php | 7 ++
Provider/AbstractProvider.php | 35 ++++++++--
Tests/Doctrine/AbstractProviderTest.php | 88 ++++++++++++++++++++-----
4 files changed, 126 insertions(+), 28 deletions(-)
diff --git a/Doctrine/AbstractProvider.php b/Doctrine/AbstractProvider.php
index b9ffda5..0c43b2d 100644
--- a/Doctrine/AbstractProvider.php
+++ b/Doctrine/AbstractProvider.php
@@ -6,6 +6,7 @@ use Doctrine\Common\Persistence\ManagerRegistry;
use Elastica\Exception\Bulk\ResponseException as BulkResponseException;
use FOS\ElasticaBundle\Persister\ObjectPersisterInterface;
use FOS\ElasticaBundle\Provider\AbstractProvider as BaseAbstractProvider;
+use FOS\ElasticaBundle\Provider\IndexableInterface;
abstract class AbstractProvider extends BaseAbstractProvider
{
@@ -15,13 +16,19 @@ abstract class AbstractProvider extends BaseAbstractProvider
* Constructor.
*
* @param ObjectPersisterInterface $objectPersister
- * @param string $objectClass
- * @param array $options
- * @param ManagerRegistry $managerRegistry
+ * @param IndexableInterface $indexable
+ * @param string $objectClass
+ * @param array $options
+ * @param ManagerRegistry $managerRegistry
*/
- public function __construct(ObjectPersisterInterface $objectPersister, $objectClass, array $options, $managerRegistry)
- {
- parent::__construct($objectPersister, $objectClass, array_merge(array(
+ public function __construct(
+ ObjectPersisterInterface $objectPersister,
+ IndexableInterface $indexable,
+ $objectClass,
+ array $options,
+ ManagerRegistry $managerRegistry
+ ) {
+ parent::__construct($objectPersister, $indexable, $objectClass, array_merge(array(
'clear_object_manager' => true,
'debug_logging' => false,
'ignore_errors' => false,
@@ -53,6 +60,10 @@ abstract class AbstractProvider extends BaseAbstractProvider
$stepStartTime = microtime(true);
}
$objects = $this->fetchSlice($queryBuilder, $batchSize, $offset);
+ if ($loggerClosure) {
+ $stepNbObjects = count($objects);
+ }
+ $objects = array_filter($objects, array($this, 'isObjectIndexable'));
if (!$ignoreErrors) {
$this->objectPersister->insertMany($objects);
@@ -73,7 +84,6 @@ abstract class AbstractProvider extends BaseAbstractProvider
usleep($sleep);
if ($loggerClosure) {
- $stepNbObjects = count($objects);
$stepCount = $stepNbObjects + $offset;
$percentComplete = 100 * $stepCount / $nbObjects;
$timeDifference = microtime(true) - $stepStartTime;
diff --git a/Persister/ObjectPersisterInterface.php b/Persister/ObjectPersisterInterface.php
index 2b4c8ee..5953d5a 100644
--- a/Persister/ObjectPersisterInterface.php
+++ b/Persister/ObjectPersisterInterface.php
@@ -68,4 +68,11 @@ interface ObjectPersisterInterface
* @param array $identifiers array of domain model object identifiers
*/
public function deleteManyByIdentifiers(array $identifiers);
+
+ /**
+ * Returns the elastica type used by this persister
+ *
+ * @return \Elastica\Type
+ */
+ public function getType();
}
diff --git a/Provider/AbstractProvider.php b/Provider/AbstractProvider.php
index 2761a25..8642be8 100644
--- a/Provider/AbstractProvider.php
+++ b/Provider/AbstractProvider.php
@@ -24,23 +24,48 @@ abstract class AbstractProvider implements ProviderInterface
*/
protected $options;
+ /**
+ * @var Indexable
+ */
+ private $indexable;
+
/**
* Constructor.
*
* @param ObjectPersisterInterface $objectPersister
- * @param string $objectClass
- * @param array $options
+ * @param IndexableInterface $indexable
+ * @param string $objectClass
+ * @param array $options
*/
- public function __construct(ObjectPersisterInterface $objectPersister, $objectClass, array $options = array())
- {
- $this->objectPersister = $objectPersister;
+ public function __construct(
+ ObjectPersisterInterface $objectPersister,
+ IndexableInterface $indexable,
+ $objectClass,
+ array $options = array()
+ ) {
+ $this->indexable = $indexable;
$this->objectClass = $objectClass;
+ $this->objectPersister = $objectPersister;
$this->options = array_merge(array(
'batch_size' => 100,
), $options);
}
+ /**
+ * Checks if a given object should be indexed or not.
+ *
+ * @param object $object
+ * @return bool
+ */
+ protected function isObjectIndexable($object)
+ {
+ $typeName = $this->objectPersister->getType()->getName();
+ $indexName = $this->objectPersister->getType()->getIndex()->getName();
+
+ return $this->indexable->isObjectIndexable($indexName, $typeName, $object);
+ }
+
/**
* Get string with RAM usage information (current and peak)
*
diff --git a/Tests/Doctrine/AbstractProviderTest.php b/Tests/Doctrine/AbstractProviderTest.php
index dcceccf..3640d16 100644
--- a/Tests/Doctrine/AbstractProviderTest.php
+++ b/Tests/Doctrine/AbstractProviderTest.php
@@ -9,24 +9,42 @@ class AbstractProviderTest extends \PHPUnit_Framework_TestCase
private $objectPersister;
private $options;
private $managerRegistry;
+ private $indexable;
public function setUp()
{
- if (!interface_exists('Doctrine\Common\Persistence\ManagerRegistry')) {
- $this->markTestSkipped('Doctrine Common is not available.');
- }
+ if (!interface_exists('Doctrine\Common\Persistence\ManagerRegistry')) {
+ $this->markTestSkipped('Doctrine Common is not available.');
+ }
- $this->objectClass = 'objectClass';
- $this->options = array('debug_logging' => true);
+ $this->objectClass = 'objectClass';
+ $this->options = array('debug_logging' => true);
- $this->objectPersister = $this->getMockObjectPersister();
- $this->managerRegistry = $this->getMockManagerRegistry();
- $this->objectManager = $this->getMockObjectManager();
+ $this->objectPersister = $this->getMockObjectPersister();
+ $this->managerRegistry = $this->getMockManagerRegistry();
+ $this->objectManager = $this->getMockObjectManager();
+ $this->indexable = $this->getMockIndexable();
- $this->managerRegistry->expects($this->any())
- ->method('getManagerForClass')
- ->with($this->objectClass)
- ->will($this->returnValue($this->objectManager));
+ $index = $this->getMockBuilder('Elastica\Index')->disableOriginalConstructor()->getMock();
+ $index->expects($this->any())
+ ->method('getName')
+ ->will($this->returnValue('index'));
+ $type = $this->getMockBuilder('Elastica\Type')->disableOriginalConstructor()->getMock();
+ $type->expects($this->any())
+ ->method('getName')
+ ->will($this->returnValue('type'));
+ $type->expects($this->any())
+ ->method('getIndex')
+ ->will($this->returnValue($index));
+
+ $this->objectPersister->expects($this->any())
+ ->method('getType')
+ ->will($this->returnValue($type));
+
+ $this->managerRegistry->expects($this->any())
+ ->method('getManagerForClass')
+ ->with($this->objectClass)
+ ->will($this->returnValue($this->objectManager));
}
/**
@@ -59,14 +77,13 @@ class AbstractProviderTest extends \PHPUnit_Framework_TestCase
->with($queryBuilder, $batchSize, $offset)
->will($this->returnValue($objects));
- $this->objectPersister->expects($this->at($i))
- ->method('insertMany')
- ->with($objects);
-
$this->objectManager->expects($this->at($i))
->method('clear');
}
+ $this->objectPersister->expects($this->exactly(count($objectsByIteration)))
+ ->method('insertMany');
+
$provider->populate();
}
@@ -159,6 +176,36 @@ class AbstractProviderTest extends \PHPUnit_Framework_TestCase
$provider->populate(null, array('ignore-errors' => false));
}
+ public function testPopulateRunsIndexCallable()
+ {
+ $nbObjects = 2;
+ $objects = array(1, 2);
+
+ $provider = $this->getMockAbstractProvider();
+ $provider->expects($this->any())
+ ->method('countObjects')
+ ->will($this->returnValue($nbObjects));
+ $provider->expects($this->any())
+ ->method('fetchSlice')
+ ->will($this->returnValue($objects));
+
+ $this->indexable->expects($this->at(0))
+ ->method('isObjectIndexable')
+ ->with('index', 'type', 1)
+ ->will($this->returnValue(false));
+ $this->indexable->expects($this->at(1))
+ ->method('isObjectIndexable')
+ ->with('index', 'type', 2)
+ ->will($this->returnValue(true));
+
+
+ $this->objectPersister->expects($this->once())
+ ->method('insertMany')
+ ->with(array(1 => 2));
+
+ $provider->populate();
+ }
+
/**
* @return \FOS\ElasticaBundle\Doctrine\AbstractProvider|\PHPUnit_Framework_MockObject_MockObject
*/
@@ -166,6 +213,7 @@ class AbstractProviderTest extends \PHPUnit_Framework_TestCase
{
return $this->getMockForAbstractClass('FOS\ElasticaBundle\Doctrine\AbstractProvider', array(
$this->objectPersister,
+ $this->indexable,
$this->objectClass,
$this->options,
$this->managerRegistry,
@@ -205,6 +253,14 @@ class AbstractProviderTest extends \PHPUnit_Framework_TestCase
{
return $this->getMock('FOS\ElasticaBundle\Persister\ObjectPersisterInterface');
}
+
+ /**
+ * @return \FOS\ElasticaBundle\Provider\IndexableInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ private function getMockIndexable()
+ {
+ return $this->getMock('FOS\ElasticaBundle\Provider\IndexableInterface');
+ }
}
/**
From 391e18dcbf9e165a4881119b3e321806ed1b0b0f Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Mon, 16 Jun 2014 16:20:17 +1000
Subject: [PATCH 258/447] Update changelog
---
CHANGELOG-3.0.md | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG-3.0.md b/CHANGELOG-3.0.md
index 9d74640..f93832d 100644
--- a/CHANGELOG-3.0.md
+++ b/CHANGELOG-3.0.md
@@ -12,7 +12,17 @@ https://github.com/FriendsOfSymfony/FOSElasticaBundle/compare/v3.0.0...v3.0.1
To generate a changelog summary since the last version, run
`git log --no-merges --oneline v3.0.0...3.0.x`
-* 3.0.0-ALPHA3 (xxxx-xx-xx)
+* 3.0.0-ALPHA6 (xxxx-xx-xx)
+
+ * Moved `is_indexable_callback` from the listener properties to a type property called
+ `indexable_callback` which is run when both populating and listening for object
+ changes.
+ * BC BREAK `ObjectPersisterInterface` added method getType() (To be removed during
+ ObjectPersister refactoring before 3.0.0 stable when ObjectPersister will change)
+ * AbstractProvider constructor change: Second argument is now an `IndexableInterface`
+ instance.
+
+* 3.0.0-ALPHA3 (2014-04-01)
* a9c4c93: Logger is now only enabled in debug mode by default
* #463: allowing hot swappable reindexing
From 629ca0df2eb0784fc90b812bb17c32d586ab3ade Mon Sep 17 00:00:00 2001
From: Patrick McAndrew
Date: Mon, 16 Jun 2014 12:59:09 +0100
Subject: [PATCH 259/447] make sure headers is set prior to accessing
---
Client.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Client.php b/Client.php
index 3eb98fe..cfcfea6 100644
--- a/Client.php
+++ b/Client.php
@@ -28,7 +28,7 @@ class Client extends ElasticaClient
'host' => $connection->getHost(),
'port' => $connection->getPort(),
'transport' => $connection->getTransport(),
- 'headers' => $connection->getConfig('headers'),
+ 'headers' => $connection->hasConfig('headers')?$connection->getConfig('headers'):array(),
);
$this->_logger->logQuery($path, $method, $data, $time, $connection_array, $query);
From 64be10447de535ee85f1cc2511ea55e943642df9 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Mon, 16 Jun 2014 22:33:04 +1000
Subject: [PATCH 260/447] Move Search annotation
---
Annotation/Search.php | 16 ++++++++++++++++
CHANGELOG-3.0.md | 3 ++-
Configuration/Search.php | 19 ++++++++++++++-----
3 files changed, 32 insertions(+), 6 deletions(-)
create mode 100644 Annotation/Search.php
diff --git a/Annotation/Search.php b/Annotation/Search.php
new file mode 100644
index 0000000..26e1dbf
--- /dev/null
+++ b/Annotation/Search.php
@@ -0,0 +1,16 @@
+
+ * @Annotation
+ * @Target("CLASS")
+ */
+class Search
+{
+ /** @var string */
+ public $repositoryClass;
+}
diff --git a/CHANGELOG-3.0.md b/CHANGELOG-3.0.md
index 095c268..62e347a 100644
--- a/CHANGELOG-3.0.md
+++ b/CHANGELOG-3.0.md
@@ -14,6 +14,7 @@ To generate a changelog summary since the last version, run
* 3.0.0-ALPHA6
+ * Annotation @Search moved to FOS\ElasticaBundle\Annotation\Search with FOS\ElasticaBundle\Configuration\Search deprecated
* Deprecated FOS\ElasticaBundle\Client in favour of FOS\ElasticaBundle\Elastica\Client
* Deprecated FOS\ElasticaBundle\DynamicIndex in favour of FOS\ElasticaBundle\Elastica\Index
* Deprecated FOS\ElasticaBundle\IndexManager in favour of FOS\ElasticaBundle\Index\IndexManager
@@ -21,7 +22,7 @@ To generate a changelog summary since the last version, run
* 3.0.0-ALPHA5 (2014-05-23)
-* Doctrine Provider speed up by disabling persistence logging while populating documents
+ * Doctrine Provider speed up by disabling persistence logging while populating documents
* 3.0.0-ALPHA4 (2014-04-10)
diff --git a/Configuration/Search.php b/Configuration/Search.php
index cee10ab..1306f92 100644
--- a/Configuration/Search.php
+++ b/Configuration/Search.php
@@ -1,16 +1,25 @@
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
namespace FOS\ElasticaBundle\Configuration;
+use FOS\ElasticaBundle\Annotation\Search as BaseSearch;
+
/**
* Annotation class for setting search repository.
*
- * @author Richard Miller
* @Annotation
+ * @deprecated Use FOS\ElasticaBundle\Annotation\Search instead
* @Target("CLASS")
*/
-class Search
+class Search extends BaseSearch
{
- /** @var string */
- public $repositoryClass;
-}
+}
From 7682d5a80a56cf7de2538c5370e1494fb418bbce Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Mon, 16 Jun 2014 22:33:31 +1000
Subject: [PATCH 261/447] Update composer.json
---
composer.json | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/composer.json b/composer.json
index 8783822..806d0b0 100644
--- a/composer.json
+++ b/composer.json
@@ -6,7 +6,8 @@
"homepage": "https://github.com/FriendsOfSymfony/FOSElasticaBundle",
"license": "MIT",
"authors": [
- { "name": "Thibault Duplessis", "email": "thibault.duplessis@gmail.com" },
+ { "name": "FriendsOfSymfony Community", "homepage": "https://github.com/FriendsOfSymfony/FOSElasticaBundle/contributors" },
+ { "name": "Tim Nagel", "email": "tim@nagel.com.au" },
{ "name": "Richard Miller", "email": "richard.miller@limethinking.co.uk" },
{ "name": "Jeremy Mikola", "email": "jmikola@gmail.com" }
],
@@ -16,12 +17,13 @@
"symfony/console": "~2.1",
"symfony/form": "~2.1",
"symfony/property-access": "~2.2",
- "ruflin/elastica": ">=0.90.10.0, <1.2-dev",
+ "ruflin/elastica": ">=0.90.10.0, <1.3-dev",
"psr/log": "~1.0"
},
"require-dev":{
"doctrine/orm": "~2.2",
- "doctrine/mongodb-odm": "1.0.*@dev",
+ "doctrine/mongodb-odm": "1.0.*@beta",
+ "phpunit/phpunit": "~4.1",
"propel/propel1": "1.6.*",
"pagerfanta/pagerfanta": "1.0.*@dev",
"knplabs/knp-components": "~1.2",
@@ -37,9 +39,8 @@
"symfony/expression-language" : "~2.4"
},
"autoload": {
- "psr-0": { "FOS\\ElasticaBundle": "" }
+ "psr-4": { "FOS\\ElasticaBundle\\": "" }
},
- "target-dir": "FOS/ElasticaBundle",
"extra": {
"branch-alias": {
"dev-master": "3.0.x-dev"
From 813a4a5d264644b8bdd04570724dff3c39b75b1d Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Mon, 16 Jun 2014 22:43:16 +1000
Subject: [PATCH 262/447] Fix previous commits
---
Client.php | 4 ++--
DependencyInjection/Configuration.php | 8 +++----
DependencyInjection/FOSElasticaExtension.php | 22 +++++++++++++++----
Resources/config/config.xml | 13 +++++------
.../{LoggingClientTest.php => ClientTest.php} | 2 +-
5 files changed, 31 insertions(+), 18 deletions(-)
rename Tests/Elastica/{LoggingClientTest.php => ClientTest.php} (98%)
diff --git a/Client.php b/Client.php
index f85756d..d0cee46 100644
--- a/Client.php
+++ b/Client.php
@@ -2,11 +2,11 @@
namespace FOS\ElasticaBundle;
-use FOS\ElasticaBundle\Elastica\LoggingClient;
+use FOS\ElasticaBundle\Elastica\Client as BaseClient;
/**
* @deprecated Use \FOS\ElasticaBundle\Elastica\LoggingClient
*/
-class Client extends LoggingClient
+class Client extends BaseClient
{
}
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 754303b..7e8bca4 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -183,11 +183,11 @@ class Configuration implements ConfigurationInterface
->beforeNormalization()
->ifTrue(function($v) { return isset($v['mappings']); })
->then(function($v) {
- $v['properties'] = $v['mappings'];
- unset($v['mappings']);
+ $v['properties'] = $v['mappings'];
+ unset($v['mappings']);
- return $v;
- })
+ return $v;
+ })
->end()
->children()
->scalarNode('index_analyzer')->end()
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index c844f3a..0b994c5 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -72,6 +72,7 @@ class FOSElasticaExtension extends Extension
$container->setAlias('fos_elastica.index', sprintf('fos_elastica.index.%s', $config['default_index']));
$this->loadIndexManager($container);
+ $this->loadResetter($container);
$this->createDefaultManagerAlias($config['default_manager'], $container);
}
@@ -132,7 +133,7 @@ class FOSElasticaExtension extends Extension
$indexDef = new DefinitionDecorator('fos_elastica.index_prototype');
$indexDef->replaceArgument(0, $indexName);
- if ($index['client']) {
+ if (isset($index['client'])) {
$client = $this->getClient($index['client']);
$indexDef->setFactoryService($client);
}
@@ -146,7 +147,7 @@ class FOSElasticaExtension extends Extension
'settings' => $index['settings']
),
'elasticsearch_name' => $indexName,
- 'index' => $reference,
+ 'reference' => $reference,
'name' => $name,
'type_prototype' => isset($index['type_prototype']) ? $index['type_prototype'] : array(),
'use_alias' => $index['use_alias'],
@@ -220,7 +221,9 @@ class FOSElasticaExtension extends Extension
'_timestamp',
'_ttl',
) as $field) {
- $this->indexConfigs[$indexName]['config']['properties'][$name][$field] = $type[$field];
+ if (array_key_exists($field, $type)) {
+ $this->indexConfigs[$indexName]['config']['properties'][$name][$field] = $type[$field];
+ }
}
if (!empty($type['dynamic_templates'])) {
@@ -390,7 +393,7 @@ class FOSElasticaExtension extends Extension
if ($this->serializerConfig) {
$abstractId = 'fos_elastica.object_serializer_persister';
- $callbackId = sprintf('%s.%s.serializer.callback', $this->indexConfigs[$indexName]['index'], $typeName);
+ $callbackId = sprintf('%s.%s.serializer.callback', $this->indexConfigs[$indexName]['reference'], $typeName);
$arguments[] = array(new Reference($callbackId), 'serialize');
} else {
$abstractId = 'fos_elastica.object_persister';
@@ -622,4 +625,15 @@ class FOSElasticaExtension extends Extension
return $this->clients[$clientName]['reference'];
}
+
+ /**
+ * Loads the resetter
+ *
+ * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
+ */
+ private function loadResetter(ContainerBuilder $container)
+ {
+ $resetterDef = $container->getDefinition('fos_elastica.resetter');
+ $resetterDef->replaceArgument(0, $this->indexConfigs);
+ }
}
diff --git a/Resources/config/config.xml b/Resources/config/config.xml
index c1ac0f9..3cb6280 100644
--- a/Resources/config/config.xml
+++ b/Resources/config/config.xml
@@ -5,7 +5,7 @@
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
- FOS\ElasticaBundle\Elastica\LoggingClient
+ FOS\ElasticaBundle\Elastica\Client
FOS\ElasticaBundle\Logger\ElasticaLogger
FOS\ElasticaBundle\DataCollector\ElasticaDataCollector
Symfony\Component\PropertyAccess\PropertyAccessor
@@ -15,7 +15,11 @@
-
+
+
+
+
+
@@ -24,11 +28,6 @@
-
-
-
-
-
diff --git a/Tests/Elastica/LoggingClientTest.php b/Tests/Elastica/ClientTest.php
similarity index 98%
rename from Tests/Elastica/LoggingClientTest.php
rename to Tests/Elastica/ClientTest.php
index b08a2cf..43ac7a2 100644
--- a/Tests/Elastica/LoggingClientTest.php
+++ b/Tests/Elastica/ClientTest.php
@@ -28,7 +28,7 @@ class LoggingClientTest extends \PHPUnit_Framework_TestCase
$this->isType('array')
);
- $client = $this->getMockBuilder('FOS\ElasticaBundle\Elastica\LoggingClient')
+ $client = $this->getMockBuilder('FOS\ElasticaBundle\Elastica\Client')
->setMethods(array('getConnection'))
->getMock();
From ada3942576a920c56c020fb9bde6b18a0bffacbf Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Mon, 16 Jun 2014 23:23:49 +1000
Subject: [PATCH 263/447] Config Source providers
---
Configuration/IndexConfig.php | 122 ++++++++++++++++++
Configuration/Manager.php | 59 +++++++++
Configuration/ManagerInterface.php | 35 +++++
Configuration/Source/ContainerSource.php | 62 +++++++++
Configuration/Source/SourceInterface.php | 26 ++++
Configuration/TypeConfig.php | 31 +++++
.../Compiler/ConfigSourcePass.php | 36 ++++++
DependencyInjection/FOSElasticaExtension.php | 49 ++-----
FOSElasticaBundle.php | 2 +
Resources/config/config.xml | 4 +
Resources/config/source.xml | 13 ++
Tests/Functional/ConfigurationManagerTest.php | 54 ++++++++
12 files changed, 457 insertions(+), 36 deletions(-)
create mode 100644 Configuration/IndexConfig.php
create mode 100644 Configuration/Manager.php
create mode 100644 Configuration/ManagerInterface.php
create mode 100644 Configuration/Source/ContainerSource.php
create mode 100644 Configuration/Source/SourceInterface.php
create mode 100644 Configuration/TypeConfig.php
create mode 100644 DependencyInjection/Compiler/ConfigSourcePass.php
create mode 100644 Resources/config/source.xml
create mode 100644 Tests/Functional/ConfigurationManagerTest.php
diff --git a/Configuration/IndexConfig.php b/Configuration/IndexConfig.php
new file mode 100644
index 0000000..684713e
--- /dev/null
+++ b/Configuration/IndexConfig.php
@@ -0,0 +1,122 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace FOS\ElasticaBundle\Configuration;
+
+class IndexConfig
+{
+ /**
+ * The name of the index for ElasticSearch.
+ *
+ * @var string
+ */
+ private $elasticSearchName;
+
+ /**
+ * The internal name of the index. May not be the same as the name used in ElasticSearch,
+ * especially if aliases are enabled.
+ *
+ * @var string
+ */
+ private $name;
+
+ /**
+ * An array of settings sent to ElasticSearch when creating the index.
+ *
+ * @var array
+ */
+ private $settings;
+
+ /**
+ * All types that belong to this index.
+ *
+ * @var TypeConfig[]
+ */
+ private $types;
+
+ /**
+ * Indicates if the index should use an alias, allowing an index repopulation to occur
+ * without overwriting the current index.
+ *
+ * @var bool
+ */
+ private $useAlias = false;
+
+ /**
+ * Constructor expects an array as generated by the Container Configuration builder.
+ *
+ * @param string $name
+ * @param TypeConfig[] $types
+ * @param array $config
+ */
+ public function __construct($name, array $types, array $config)
+ {
+ $this->elasticSearchName = $config['elasticSearchName'];
+ $this->name = $name;
+ $this->settings = $config['settings'];
+ $this->types = $types;
+ $this->useAlias = $config['useAlias'];
+ }
+
+ /**
+ * @return string
+ */
+ public function getElasticSearchName()
+ {
+ return $this->elasticSearchName;
+ }
+
+ /**
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * @return array
+ */
+ public function getSettings()
+ {
+ return $this->settings;
+ }
+
+ /**
+ * @param string $typeName
+ * @return TypeConfig
+ * @throws \InvalidArgumentException
+ */
+ public function getType($typeName)
+ {
+ if (!array_key_exists($typeName, $this->types)) {
+ throw new \InvalidArgumentException(sprintf('Type "%s" does not exist on index "%s"', $typeName, $this->name));
+ }
+
+ return $this->types[$typeName];
+ }
+
+ /**
+ * @return \FOS\ElasticaBundle\Configuration\TypeConfig[]
+ */
+ public function getTypes()
+ {
+ return $this->types;
+ }
+
+ /**
+ * @return boolean
+ */
+ public function getUseAlias()
+ {
+ return $this->useAlias;
+ }
+}
diff --git a/Configuration/Manager.php b/Configuration/Manager.php
new file mode 100644
index 0000000..85afb99
--- /dev/null
+++ b/Configuration/Manager.php
@@ -0,0 +1,59 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace FOS\ElasticaBundle\Configuration;
+
+/**
+ * Central manager for index and type configuration.
+ */
+class Manager implements ManagerInterface
+{
+ /**
+ * @var IndexConfig[]
+ */
+ private $indexes = array();
+
+ /**
+ * @param Source\SourceInterface[] $sources
+ */
+ public function __construct(array $sources)
+ {
+ foreach ($sources as $source) {
+ $this->indexes = array_merge($source->getConfiguration(), $this->indexes);
+ }
+ }
+
+ public function getTypeConfiguration($indexName, $typeName)
+ {
+ $index = $this->getIndexConfiguration($indexName);
+ $type = $index->getType($typeName);
+
+ if (!$type) {
+ throw new \InvalidArgumentException(sprintf('Type with name "%s" on index "%s" is not configured', $typeName, $indexName));
+ }
+
+ return $type;
+ }
+
+ public function getIndexConfiguration($indexName)
+ {
+ if (!$this->hasIndexConfiguration($indexName)) {
+ throw new \InvalidArgumentException(sprintf('Index with name "%s" is not configured.', $indexName));
+ }
+
+ return $this->indexes[$indexName];
+ }
+
+ public function hasIndexConfiguration($indexName)
+ {
+ return isset($this->indexes[$indexName]);
+ }
+}
diff --git a/Configuration/ManagerInterface.php b/Configuration/ManagerInterface.php
new file mode 100644
index 0000000..7852828
--- /dev/null
+++ b/Configuration/ManagerInterface.php
@@ -0,0 +1,35 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace FOS\ElasticaBundle\Configuration;
+
+/**
+ * Central manager for index and type configuration.
+ */
+interface ManagerInterface
+{
+ /**
+ * Returns configuration for an index.
+ *
+ * @param $index
+ * @return IndexConfig
+ */
+ public function getIndexConfiguration($index);
+
+ /**
+ * Returns a type configuration.
+ *
+ * @param string $index
+ * @param string $type
+ * @return TypeConfig
+ */
+ public function getTypeConfiguration($index, $type);
+}
\ No newline at end of file
diff --git a/Configuration/Source/ContainerSource.php b/Configuration/Source/ContainerSource.php
new file mode 100644
index 0000000..5fba57a
--- /dev/null
+++ b/Configuration/Source/ContainerSource.php
@@ -0,0 +1,62 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace FOS\ElasticaBundle\Configuration\Source;
+
+use FOS\ElasticaBundle\Configuration\IndexConfig;
+use FOS\ElasticaBundle\Configuration\TypeConfig;
+
+/**
+ * Returns index and type configuration from the container.
+ */
+class ContainerSource implements SourceInterface
+{
+ /**
+ * The internal container representation of information.
+ *
+ * @var array
+ */
+ private $configArray;
+
+ public function __construct(array $configArray)
+ {
+ $this->configArray = $configArray;
+ }
+
+ /**
+ * Should return all configuration available from the data source.
+ *
+ * @return IndexConfig[]
+ */
+ public function getConfiguration()
+ {
+ $indexes = array();
+ foreach ($this->configArray as $config) {
+ $types = array();
+ foreach ($config['types'] as $typeConfig) {
+ $types[$typeConfig['name']] = new TypeConfig($typeConfig['name'], array(
+ 'dynamicTemplates' => $typeConfig['dynamic_templates'],
+ 'properties' => $typeConfig['properties'],
+ ), $config['type_prototype']);
+ }
+
+ $index = new IndexConfig($config['name'], $types, array(
+ 'elasticSearchName' => $config['elasticsearch_name'],
+ 'settings' => $config['settings'],
+ 'useAlias' => $config['use_alias'],
+ ));
+
+ $indexes[$config['name']] = $index;
+ }
+
+ return $indexes;
+ }
+}
diff --git a/Configuration/Source/SourceInterface.php b/Configuration/Source/SourceInterface.php
new file mode 100644
index 0000000..34e9901
--- /dev/null
+++ b/Configuration/Source/SourceInterface.php
@@ -0,0 +1,26 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace FOS\ElasticaBundle\Configuration\Source;
+
+/**
+ * Represents a source of index and type information (ie, the Container configuration or
+ * annotations).
+ */
+interface SourceInterface
+{
+ /**
+ * Should return all configuration available from the data source.
+ *
+ * @return \FOS\ElasticaBundle\Configuration\IndexConfig[]
+ */
+ public function getConfiguration();
+}
diff --git a/Configuration/TypeConfig.php b/Configuration/TypeConfig.php
new file mode 100644
index 0000000..c78a32a
--- /dev/null
+++ b/Configuration/TypeConfig.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace FOS\ElasticaBundle\Configuration;
+
+class TypeConfig
+{
+ /**
+ * @var array
+ */
+ private $config;
+
+ /**
+ * @var string
+ */
+ private $name;
+
+ public function __construct($name, array $config, array $prototype)
+ {
+ $this->config = $config;
+ $this->name = $name;
+ }
+}
diff --git a/DependencyInjection/Compiler/ConfigSourcePass.php b/DependencyInjection/Compiler/ConfigSourcePass.php
new file mode 100644
index 0000000..b35a665
--- /dev/null
+++ b/DependencyInjection/Compiler/ConfigSourcePass.php
@@ -0,0 +1,36 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace FOS\ElasticaBundle\DependencyInjection\Compiler;
+
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Reference;
+
+class ConfigSourcePass implements CompilerPassInterface
+{
+ /**
+ * {@inheritDoc}
+ */
+ public function process(ContainerBuilder $container)
+ {
+ if (!$container->hasDefinition('fos_elastica.config_manager')) {
+ return;
+ }
+
+ $sources = array();
+ foreach (array_keys($container->findTaggedServiceIds('fos_elastica.config_source')) as $id) {
+ $sources[] = new Reference($id);
+ }
+
+ $container->getDefinition('fos_elastica.config_manager')->replaceArgument(0, $sources);
+ }
+}
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 0b994c5..7699fd7 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -49,7 +49,7 @@ class FOSElasticaExtension extends Extension
return;
}
- foreach (array('config', 'index', 'persister', 'provider', 'transformer') as $basename) {
+ foreach (array('config', 'index', 'persister', 'provider', 'source', 'transformer') as $basename) {
$loader->load(sprintf('%s.xml', $basename));
}
@@ -71,6 +71,8 @@ class FOSElasticaExtension extends Extension
$this->loadIndexes($config['indexes'], $container);
$container->setAlias('fos_elastica.index', sprintf('fos_elastica.index.%s', $config['default_index']));
+ $container->getDefinition('fos_elastica.config_source.container')->replaceArgument(0, $this->indexConfigs);
+
$this->loadIndexManager($container);
$this->loadResetter($container);
@@ -142,13 +144,10 @@ class FOSElasticaExtension extends Extension
$reference = new Reference($indexId);
$this->indexConfigs[$name] = array(
- 'config' => array(
- 'properties' => array(),
- 'settings' => $index['settings']
- ),
'elasticsearch_name' => $indexName,
'reference' => $reference,
'name' => $name,
+ 'settings' => $index['settings'],
'type_prototype' => isset($index['type_prototype']) ? $index['type_prototype'] : array(),
'use_alias' => $index['use_alias'],
);
@@ -197,7 +196,6 @@ class FOSElasticaExtension extends Extension
{
foreach ($types as $name => $type) {
$indexName = $indexConfig['name'];
- $type = self::deepArrayUnion($indexConfig['type_prototype'], $type);
$typeId = sprintf('%s.%s', $indexName, $name);
$typeDef = new DefinitionDecorator('fos_elastica.type_prototype');
@@ -208,7 +206,14 @@ class FOSElasticaExtension extends Extension
$this->loadTypePersistenceIntegration($type['persistence'], $container, $typeDef, $indexName, $name);
}
+ $this->indexConfigs[$indexName]['types'][$name] = array(
+ 'dynamic_templates' => array(),
+ 'name' => $name,
+ 'properties' => array()
+ );
+
foreach (array(
+ 'dynamic_templates',
'index_analyzer',
'properties',
'search_analyzer',
@@ -222,14 +227,7 @@ class FOSElasticaExtension extends Extension
'_ttl',
) as $field) {
if (array_key_exists($field, $type)) {
- $this->indexConfigs[$indexName]['config']['properties'][$name][$field] = $type[$field];
- }
- }
-
- if (!empty($type['dynamic_templates'])) {
- $this->indexConfigs[$indexName]['config']['properties'][$name]['dynamic_templates'] = array();
- foreach ($type['dynamic_templates'] as $templateName => $templateData) {
- $this->indexConfigs[$indexName]['config']['properties'][$name]['dynamic_templates'][] = array($templateName => $templateData);
+ $this->indexConfigs[$indexName]['types'][$name]['properties'][$field] = $type[$field];
}
}
@@ -259,27 +257,6 @@ class FOSElasticaExtension extends Extension
}
}
- /**
- * Merges two arrays without reindexing numeric keys.
- *
- * @param array $array1 An array to merge
- * @param array $array2 An array to merge
- *
- * @return array The merged array
- */
- private static function deepArrayUnion($array1, $array2)
- {
- foreach ($array2 as $key => $value) {
- if (is_array($value) && isset($array1[$key]) && is_array($array1[$key])) {
- $array1[$key] = self::deepArrayUnion($array1[$key], $value);
- } else {
- $array1[$key] = $value;
- }
- }
-
- return $array1;
- }
-
/**
* Loads the optional provider and finder for a type
*
@@ -397,7 +374,7 @@ class FOSElasticaExtension extends Extension
$arguments[] = array(new Reference($callbackId), 'serialize');
} else {
$abstractId = 'fos_elastica.object_persister';
- $arguments[] = $this->indexConfigs[$indexName]['config']['properties'][$typeName]['properties'];
+ $arguments[] = $this->indexConfigs[$indexName]['types'][$typeName]['properties'];
}
$serviceId = sprintf('fos_elastica.object_persister.%s.%s', $indexName, $typeName);
diff --git a/FOSElasticaBundle.php b/FOSElasticaBundle.php
index 44424d3..ac4cc3d 100644
--- a/FOSElasticaBundle.php
+++ b/FOSElasticaBundle.php
@@ -2,6 +2,7 @@
namespace FOS\ElasticaBundle;
+use FOS\ElasticaBundle\DependencyInjection\Compiler\ConfigSourcePass;
use FOS\ElasticaBundle\DependencyInjection\Compiler\RegisterProvidersPass;
use FOS\ElasticaBundle\DependencyInjection\Compiler\TransformerPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -23,5 +24,6 @@ class FOSElasticaBundle extends Bundle
$container->addCompilerPass(new RegisterProvidersPass(), PassConfig::TYPE_BEFORE_REMOVING);
$container->addCompilerPass(new TransformerPass());
+ $container->addCompilerPass(new ConfigSourcePass());
}
}
diff --git a/Resources/config/config.xml b/Resources/config/config.xml
index 3cb6280..4ee733f 100644
--- a/Resources/config/config.xml
+++ b/Resources/config/config.xml
@@ -17,6 +17,10 @@
+
+
+
+
diff --git a/Resources/config/source.xml b/Resources/config/source.xml
new file mode 100644
index 0000000..c0f085c
--- /dev/null
+++ b/Resources/config/source.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Tests/Functional/ConfigurationManagerTest.php b/Tests/Functional/ConfigurationManagerTest.php
new file mode 100644
index 0000000..0574481
--- /dev/null
+++ b/Tests/Functional/ConfigurationManagerTest.php
@@ -0,0 +1,54 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace FOS\ElasticaBundle\Tests\Functional;
+
+use Symfony\Bundle\FrameworkBundle\Client;
+
+/**
+ * @group functional
+ */
+class ConfigurationManagerTest extends WebTestCase
+{
+ public function testContainerSource()
+ {
+ $client = $this->createClient(array('test_case' => 'Basic'));
+ $manager = $this->getManager($client);
+
+ $index = $manager->getIndexConfiguration('index');
+ var_dump($index); die;
+ }
+
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $this->deleteTmpDir('Basic');
+ }
+
+ protected function tearDown()
+ {
+ parent::tearDown();
+
+ $this->deleteTmpDir('Basic');
+ }
+
+ /**
+ * @param Client $client
+ * @return \FOS\ElasticaBundle\Configuration\Manager
+ */
+ private function getManager(Client $client)
+ {
+ $manager = $client->getContainer()->get('fos_elastica.config_manager');
+
+ return $manager;
+ }
+}
From 0383811834eb9ac85e001f4c83964a07573cc93f Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Mon, 16 Jun 2014 23:28:53 +1000
Subject: [PATCH 264/447] Fix test, add test for failing mappings
---
Tests/Doctrine/AbstractProviderTest.php | 9 ++++---
Tests/Functional/MappingToElasticaTest.php | 28 ++++++++++++++++++++--
2 files changed, 32 insertions(+), 5 deletions(-)
diff --git a/Tests/Doctrine/AbstractProviderTest.php b/Tests/Doctrine/AbstractProviderTest.php
index dcceccf..c53940c 100644
--- a/Tests/Doctrine/AbstractProviderTest.php
+++ b/Tests/Doctrine/AbstractProviderTest.php
@@ -2,6 +2,9 @@
namespace FOS\ElasticaBundle\Tests\Doctrine;
+use Elastica\Bulk\ResponseSet;
+use Elastica\Response;
+
class AbstractProviderTest extends \PHPUnit_Framework_TestCase
{
private $objectClass;
@@ -177,9 +180,9 @@ class AbstractProviderTest extends \PHPUnit_Framework_TestCase
*/
private function getMockBulkResponseException()
{
- return $this->getMockBuilder('Elastica\Exception\Bulk\ResponseException')
- ->disableOriginalConstructor()
- ->getMock();
+ return $this->getMock('Elastica\Exception\Bulk\ResponseException', null, array(
+ new ResponseSet(new Response(array()), array())
+ ));
}
/**
diff --git a/Tests/Functional/MappingToElasticaTest.php b/Tests/Functional/MappingToElasticaTest.php
index 3c32e10..bffcf76 100644
--- a/Tests/Functional/MappingToElasticaTest.php
+++ b/Tests/Functional/MappingToElasticaTest.php
@@ -18,13 +18,28 @@ use Symfony\Bundle\FrameworkBundle\Client;
*/
class MappingToElasticaTest extends WebTestCase
{
- public function testReset()
+ public function testResetIndexAddsMappings()
{
$client = $this->createClient(array('test_case' => 'Basic'));
$resetter = $this->getResetter($client);
-
$resetter->resetIndex('index');
+
+ $type = $this->getType($client);
+ $mapping = $type->getMapping();
+
+ $this->assertNotEmpty($mapping, 'Mapping was populated');
+ }
+
+ public function testResetType()
+ {
+ $client = $this->createClient(array('test_case' => 'Basic'));
+ $resetter = $this->getResetter($client);
$resetter->resetIndexType('index', 'type');
+
+ $type = $this->getType($client);
+ $mapping = $type->getMapping();
+
+ $this->assertNotEmpty($mapping, 'Mapping was populated');
}
/**
@@ -36,6 +51,15 @@ class MappingToElasticaTest extends WebTestCase
return $client->getContainer()->get('fos_elastica.resetter');
}
+ /**
+ * @param Client $client
+ * @return \Elastica\Type
+ */
+ private function getType(Client $client)
+ {
+ return $client->getContainer()->get('fos_elastica.index.index.type');
+ }
+
protected function setUp()
{
parent::setUp();
From 934c6af8b8254c9f8be328ec842922a330e8c681 Mon Sep 17 00:00:00 2001
From: Patrick McAndrew
Date: Mon, 16 Jun 2014 14:30:03 +0100
Subject: [PATCH 265/447] make PSR2 compliant
---
Client.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Client.php b/Client.php
index cfcfea6..265773a 100644
--- a/Client.php
+++ b/Client.php
@@ -28,7 +28,7 @@ class Client extends ElasticaClient
'host' => $connection->getHost(),
'port' => $connection->getPort(),
'transport' => $connection->getTransport(),
- 'headers' => $connection->hasConfig('headers')?$connection->getConfig('headers'):array(),
+ 'headers' => $connection->hasConfig('headers') ? $connection->getConfig('headers') : array(),
);
$this->_logger->logQuery($path, $method, $data, $time, $connection_array, $query);
From 2e23f4a1bf31eb4e2775880c2ecd319717fac984 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Tue, 17 Jun 2014 10:07:10 +1000
Subject: [PATCH 266/447] Added documentation changes for indexable_callback
---
Resources/doc/setup.md | 2 +-
Resources/doc/types.md | 81 ++++++++++++++++++++----------------------
2 files changed, 39 insertions(+), 44 deletions(-)
diff --git a/Resources/doc/setup.md b/Resources/doc/setup.md
index 9a39b95..485f290 100644
--- a/Resources/doc/setup.md
+++ b/Resources/doc/setup.md
@@ -7,7 +7,7 @@ A) Install FOSElasticaBundle
FOSElasticaBundle is installed using [Composer](https://getcomposer.org).
```bash
-$ php composer.phar require friendsofsymfony/elastica-bundle "3.0.*"
+$ php composer.phar require friendsofsymfony/elastica-bundle "3.0.*@alpha"
```
### Elasticsearch
diff --git a/Resources/doc/types.md b/Resources/doc/types.md
index aacb09e..be687d7 100644
--- a/Resources/doc/types.md
+++ b/Resources/doc/types.md
@@ -149,6 +149,44 @@ analyzer, you could write:
title: { boost: 8, analyzer: my_analyzer }
```
+Testing if an object should be indexed
+--------------------------------------
+
+FOSElasticaBundle can be configured to automatically index changes made for
+different kinds of objects if your persistence backend supports these methods,
+but in some cases you might want to run an external service or call a property
+on the object to see if it should be indexed.
+
+A property, `indexable_callback` is provided under the type configuration that
+lets you configure this behaviour which will apply for any automated watching
+for changes and for a repopulation of an index.
+
+In the example below, we're checking the enabled property on the user to only
+index enabled users.
+
+```yaml
+ types:
+ users:
+ indexable_callback: 'enabled'
+```
+
+The callback option supports multiple approaches:
+
+* A method on the object itself provided as a string. `enabled` will call
+ `Object->enabled()`
+* An array of a service id and a method which will be called with the object as the first
+ and only argument. `[ @my_custom_service, 'userIndexable' ]` will call the userIndexable
+ method on a service defined as my_custom_service.
+* If you have the ExpressionLanguage component installed, A valid ExpressionLanguage
+ expression provided as a string. The object being indexed will be supplied as `object`
+ in the expression. `object.isEnabled() or object.shouldBeIndexedAnyway()`. For more
+ information on the ExpressionLanguage component and its capabilities see its
+ [documentation](http://symfony.com/doc/current/components/expression_language/index.html)
+
+In all cases, the callback should return a true or false, with true indicating it will be
+indexed, and a false indicating the object should not be indexed, or should be removed
+from the index if we are running an update.
+
Provider Configuration
----------------------
@@ -234,49 +272,6 @@ You can also choose to only listen for some of the events:
> **Propel** doesn't support this feature yet.
-### Checking an entity method for listener
-
-If you use listeners to update your index, you may need to validate your
-entities before you index them (e.g. only index "public" entities). Typically,
-you'll want the listener to be consistent with the provider's query criteria.
-This may be achieved by using the `is_indexable_callback` config parameter:
-
-```yaml
- persistence:
- listener:
- is_indexable_callback: "isPublic"
-```
-
-If `is_indexable_callback` is a string and the entity has a method with the
-specified name, the listener will only index entities for which the method
-returns `true`. Additionally, you may provide a service and method name pair:
-
-```yaml
- persistence:
- listener:
- is_indexable_callback: [ "%custom_service_id%", "isIndexable" ]
-```
-
-In this case, the callback_class will be the `isIndexable()` method on the specified
-service and the object being considered for indexing will be passed as the only
-argument. This allows you to do more complex validation (e.g. ACL checks).
-
-If you have the [Symfony ExpressionLanguage](https://github.com/symfony/expression-language)
-component installed, you can use expressions to evaluate the callback:
-
-```yaml
- persistence:
- listener:
- is_indexable_callback: "user.isActive() && user.hasRole('ROLE_USER')"
-```
-
-As you might expect, new entities will only be indexed if the callback_class returns
-`true`. Additionally, modified entities will be updated or removed from the
-index depending on whether the callback_class returns `true` or `false`, respectively.
-The delete listener disregards the callback_class.
-
-> **Propel** doesn't support this feature yet.
-
Flushing Method
---------------
From b49437529c54f2ad9ffaef87019e5539a8b9372d Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Tue, 17 Jun 2014 10:41:11 +1000
Subject: [PATCH 267/447] Fix incorrect provider configuration
---
Propel/Provider.php | 10 +++++++---
Resources/config/mongodb.xml | 2 +-
Resources/config/orm.xml | 2 +-
Resources/config/propel.xml | 2 +-
4 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/Propel/Provider.php b/Propel/Provider.php
index 393beba..c242d47 100644
--- a/Propel/Provider.php
+++ b/Propel/Provider.php
@@ -30,14 +30,18 @@ class Provider extends AbstractProvider
$objects = $queryClass::create()
->limit($batchSize)
->offset($offset)
- ->find();
+ ->find()
+ ->getArrayCopy();
+ if ($loggerClosure) {
+ $stepNbObjects = count($objects);
+ }
+ $objects = array_filter($objects, array($this, 'isObjectIndexable'));
- $this->objectPersister->insertMany($objects->getArrayCopy());
+ $this->objectPersister->insertMany($objects);
usleep($sleep);
if ($loggerClosure) {
- $stepNbObjects = count($objects);
$stepCount = $stepNbObjects + $offset;
$percentComplete = 100 * $stepCount / $nbObjects;
$objectsPerSecond = $stepNbObjects / (microtime(true) - $stepStartTime);
diff --git a/Resources/config/mongodb.xml b/Resources/config/mongodb.xml
index e575e5d..ffa4f22 100644
--- a/Resources/config/mongodb.xml
+++ b/Resources/config/mongodb.xml
@@ -23,7 +23,7 @@
-
+
diff --git a/Resources/config/orm.xml b/Resources/config/orm.xml
index 43d1670..351992a 100644
--- a/Resources/config/orm.xml
+++ b/Resources/config/orm.xml
@@ -23,7 +23,7 @@
-
+
diff --git a/Resources/config/propel.xml b/Resources/config/propel.xml
index 7a7d93e..cbc8cd7 100644
--- a/Resources/config/propel.xml
+++ b/Resources/config/propel.xml
@@ -7,7 +7,7 @@
-
+
From e225d841edbd6633a0e864838af5b13f777b740b Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Tue, 17 Jun 2014 10:54:09 +1000
Subject: [PATCH 268/447] Wrong service. Whoops.
---
Resources/config/mongodb.xml | 4 ++--
Resources/config/orm.xml | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/Resources/config/mongodb.xml b/Resources/config/mongodb.xml
index ffa4f22..73b70c5 100644
--- a/Resources/config/mongodb.xml
+++ b/Resources/config/mongodb.xml
@@ -8,7 +8,7 @@
-
+
@@ -23,7 +23,7 @@
-
+
diff --git a/Resources/config/orm.xml b/Resources/config/orm.xml
index 351992a..807a5bf 100644
--- a/Resources/config/orm.xml
+++ b/Resources/config/orm.xml
@@ -8,7 +8,7 @@
-
+
@@ -23,7 +23,7 @@
-
+
From aafb8c8e89d23fd455263bddc817874092c787b6 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Tue, 17 Jun 2014 12:03:38 +1000
Subject: [PATCH 269/447] Fix indexable callbacks with alias based indexes
---
DependencyInjection/FOSElasticaExtension.php | 13 +++++++++---
Doctrine/Listener.php | 18 +++++++++--------
DynamicIndex.php | 21 ++++++++++++++++----
Persister/ObjectPersister.php | 10 ----------
Persister/ObjectPersisterInterface.php | 7 -------
Provider/AbstractProvider.php | 9 +++++----
Provider/Indexable.php | 2 +-
Resources/config/mongodb.xml | 1 +
Resources/config/orm.xml | 1 +
Resources/config/propel.xml | 1 +
Tests/Doctrine/AbstractListenerTest.php | 12 +++++------
Tests/Doctrine/AbstractProviderTest.php | 18 +----------------
Tests/Provider/IndexableTest.php | 8 ++++++++
13 files changed, 61 insertions(+), 60 deletions(-)
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 9e50c0b..66a2cef 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -419,9 +419,12 @@ class FOSElasticaExtension extends Extension
$providerDef = new DefinitionDecorator('fos_elastica.provider.prototype.' . $typeConfig['driver']);
$providerDef->addTag('fos_elastica.provider', array('index' => $indexName, 'type' => $typeName));
$providerDef->replaceArgument(0, new Reference($objectPersisterId));
- $providerDef->replaceArgument(1, $typeConfig['model']);
+ $providerDef->replaceArgument(2, $typeConfig['model']);
// Propel provider can simply ignore Doctrine-specific options
- $providerDef->replaceArgument(2, array_diff_key($typeConfig['provider'], array('service' => 1)));
+ $providerDef->replaceArgument(3, array_merge(array_diff_key($typeConfig['provider'], array('service' => 1)), array(
+ 'indexName' => $indexName,
+ 'typeName' => $typeName,
+ )));
$container->setDefinition($providerId, $providerDef);
return $providerId;
@@ -440,7 +443,11 @@ class FOSElasticaExtension extends Extension
$listenerDef = new DefinitionDecorator($abstractListenerId);
$listenerDef->replaceArgument(0, new Reference($objectPersisterId));
$listenerDef->replaceArgument(1, $this->getDoctrineEvents($typeConfig));
- $listenerDef->replaceArgument(3, $typeConfig['identifier']);
+ $listenerDef->replaceArgument(3, array(
+ 'identifier' => $typeConfig['identifier'],
+ 'indexName' => $indexName,
+ 'typeName' => $typeName,
+ ));
if ($typeConfig['listener']['logger']) {
$listenerDef->replaceArgument(4, new Reference($typeConfig['listener']['logger']));
}
diff --git a/Doctrine/Listener.php b/Doctrine/Listener.php
index 4a01aa1..73a271d 100644
--- a/Doctrine/Listener.php
+++ b/Doctrine/Listener.php
@@ -31,11 +31,11 @@ class Listener implements EventSubscriber
protected $events;
/**
- * Name of domain model field used as the ES identifier
+ * Configuration for the listener
*
* @var string
*/
- protected $esIdentifierField;
+ private $config;
/**
* Objects scheduled for insertion and replacement
@@ -66,17 +66,19 @@ class Listener implements EventSubscriber
* @param ObjectPersisterInterface $objectPersister
* @param array $events
* @param IndexableInterface $indexable
- * @param string $esIdentifierField
+ * @param array $config
* @param null $logger
*/
public function __construct(
ObjectPersisterInterface $objectPersister,
array $events,
IndexableInterface $indexable,
- $esIdentifierField = 'id',
+ array $config = array(),
$logger = null
) {
- $this->esIdentifierField = $esIdentifierField;
+ $this->config = array_merge(array(
+ 'identifier' => 'id',
+ ), $config);
$this->events = $events;
$this->indexable = $indexable;
$this->objectPersister = $objectPersister;
@@ -196,7 +198,7 @@ class Listener implements EventSubscriber
*/
protected function scheduleForDeletion($object)
{
- if ($identifierValue = $this->propertyAccessor->getValue($object, $this->esIdentifierField)) {
+ if ($identifierValue = $this->propertyAccessor->getValue($object, $this->config['identifier'])) {
$this->scheduledForDeletion[] = $identifierValue;
}
}
@@ -210,8 +212,8 @@ class Listener implements EventSubscriber
private function isObjectIndexable($object)
{
return $this->indexable->isObjectIndexable(
- $this->objectPersister->getType()->getIndex()->getName(),
- $this->objectPersister->getType()->getName(),
+ $this->config['indexName'],
+ $this->config['typeName'],
$object
);
}
diff --git a/DynamicIndex.php b/DynamicIndex.php
index cbec8e9..f890234 100644
--- a/DynamicIndex.php
+++ b/DynamicIndex.php
@@ -11,18 +11,31 @@ use Elastica\Index;
*/
class DynamicIndex extends Index
{
+ private $originalName;
+
/**
* Reassign index name
*
- * While it's technically a regular setter for name property, it's specifically named overrideName, but not setName
- * since it's used for a very specific case and normally should not be used
+ * While it's technically a regular setter for name property, it's specifically named
+ * overrideName, but not setName since it's used for a very specific case and normally
+ * should not be used.
*
* @param string $name Index name
- *
- * @return void
*/
public function overrideName($name)
{
+ $this->originalName = $this->_name;
$this->_name = $name;
}
+
+ /**
+ * Returns the original name of the index if the index has been renamed for reindexing
+ * or realiasing purposes.
+ *
+ * @return string
+ */
+ public function getOriginalName()
+ {
+ return $this->originalName ?: $this->_name;
+ }
}
diff --git a/Persister/ObjectPersister.php b/Persister/ObjectPersister.php
index 2b6a8af..54d5fd1 100644
--- a/Persister/ObjectPersister.php
+++ b/Persister/ObjectPersister.php
@@ -31,16 +31,6 @@ class ObjectPersister implements ObjectPersisterInterface
$this->fields = $fields;
}
- /**
- * @internal Temporary method that will be removed.
- *
- * @return Type
- */
- public function getType()
- {
- return $this->type;
- }
-
/**
* If the ObjectPersister handles a given object.
*
diff --git a/Persister/ObjectPersisterInterface.php b/Persister/ObjectPersisterInterface.php
index 5953d5a..2b4c8ee 100644
--- a/Persister/ObjectPersisterInterface.php
+++ b/Persister/ObjectPersisterInterface.php
@@ -68,11 +68,4 @@ interface ObjectPersisterInterface
* @param array $identifiers array of domain model object identifiers
*/
public function deleteManyByIdentifiers(array $identifiers);
-
- /**
- * Returns the elastica type used by this persister
- *
- * @return \Elastica\Type
- */
- public function getType();
}
diff --git a/Provider/AbstractProvider.php b/Provider/AbstractProvider.php
index 8642be8..82ea914 100644
--- a/Provider/AbstractProvider.php
+++ b/Provider/AbstractProvider.php
@@ -60,10 +60,11 @@ abstract class AbstractProvider implements ProviderInterface
*/
protected function isObjectIndexable($object)
{
- $typeName = $this->objectPersister->getType()->getName();
- $indexName = $this->objectPersister->getType()->getIndex()->getName();
-
- return $this->indexable->isObjectIndexable($indexName, $typeName, $object);
+ return $this->indexable->isObjectIndexable(
+ $this->options['indexName'],
+ $this->options['typeName'],
+ $object
+ );
}
/**
diff --git a/Provider/Indexable.php b/Provider/Indexable.php
index b388c58..09168a1 100644
--- a/Provider/Indexable.php
+++ b/Provider/Indexable.php
@@ -94,7 +94,7 @@ class Indexable implements IndexableInterface
private function buildCallback($type, $object)
{
if (!array_key_exists($type, $this->callbacks)) {
- throw new \InvalidArgumentException(sprintf('Callback for type "%s" is not configured', $type));
+ return null;
}
$callback = $this->callbacks[$type];
diff --git a/Resources/config/mongodb.xml b/Resources/config/mongodb.xml
index 73b70c5..df2d2cc 100644
--- a/Resources/config/mongodb.xml
+++ b/Resources/config/mongodb.xml
@@ -9,6 +9,7 @@
+
diff --git a/Resources/config/orm.xml b/Resources/config/orm.xml
index 807a5bf..0cd6c42 100644
--- a/Resources/config/orm.xml
+++ b/Resources/config/orm.xml
@@ -9,6 +9,7 @@
+
diff --git a/Resources/config/propel.xml b/Resources/config/propel.xml
index cbc8cd7..962cb09 100644
--- a/Resources/config/propel.xml
+++ b/Resources/config/propel.xml
@@ -8,6 +8,7 @@
+
diff --git a/Tests/Doctrine/AbstractListenerTest.php b/Tests/Doctrine/AbstractListenerTest.php
index de5ba0c..1f238d6 100644
--- a/Tests/Doctrine/AbstractListenerTest.php
+++ b/Tests/Doctrine/AbstractListenerTest.php
@@ -16,7 +16,7 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
$eventArgs = $this->createLifecycleEventArgs($entity, $this->getMockObjectManager());
$indexable = $this->getMockIndexable('index', 'type', $entity, true);
- $listener = $this->createListener($persister, array(), $indexable);
+ $listener = $this->createListener($persister, array(), $indexable, array('indexName' => 'index', 'typeName' => 'type'));
$listener->postPersist($eventArgs);
$this->assertEquals($entity, current($listener->scheduledForInsertion));
@@ -35,7 +35,7 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
$eventArgs = $this->createLifecycleEventArgs($entity, $this->getMockObjectManager());
$indexable = $this->getMockIndexable('index', 'type', $entity, false);
- $listener = $this->createListener($persister, array(), $indexable);
+ $listener = $this->createListener($persister, array(), $indexable, array('indexName' => 'index', 'typeName' => 'type'));
$listener->postPersist($eventArgs);
$this->assertEmpty($listener->scheduledForInsertion);
@@ -55,7 +55,7 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
$eventArgs = $this->createLifecycleEventArgs($entity, $this->getMockObjectManager());
$indexable = $this->getMockIndexable('index', 'type', $entity, true);
- $listener = $this->createListener($persister, array(), $indexable);
+ $listener = $this->createListener($persister, array(), $indexable, array('indexName' => 'index', 'typeName' => 'type'));
$listener->postUpdate($eventArgs);
$this->assertEquals($entity, current($listener->scheduledForUpdate));
@@ -89,7 +89,7 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
->with($entity, 'id')
->will($this->returnValue($entity->getId()));
- $listener = $this->createListener($persister, array(), $indexable);
+ $listener = $this->createListener($persister, array(), $indexable, array('indexName' => 'index', 'typeName' => 'type'));
$listener->postUpdate($eventArgs);
$this->assertEmpty($listener->scheduledForUpdate);
@@ -124,7 +124,7 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
->with($entity, 'id')
->will($this->returnValue($entity->getId()));
- $listener = $this->createListener($persister, array(), $indexable);
+ $listener = $this->createListener($persister, array(), $indexable, array('indexName' => 'index', 'typeName' => 'type'));
$listener->preRemove($eventArgs);
$this->assertEquals($entity->getId(), current($listener->scheduledForDeletion));
@@ -157,7 +157,7 @@ abstract class ListenerTest extends \PHPUnit_Framework_TestCase
->with($entity, 'identifier')
->will($this->returnValue($entity->getId()));
- $listener = $this->createListener($persister, array(), $indexable, 'identifier');
+ $listener = $this->createListener($persister, array(), $indexable, array('identifier' => 'identifier', 'indexName' => 'index', 'typeName' => 'type'));
$listener->preRemove($eventArgs);
$this->assertEquals($entity->identifier, current($listener->scheduledForDeletion));
diff --git a/Tests/Doctrine/AbstractProviderTest.php b/Tests/Doctrine/AbstractProviderTest.php
index e5f9735..cd0a58c 100644
--- a/Tests/Doctrine/AbstractProviderTest.php
+++ b/Tests/Doctrine/AbstractProviderTest.php
@@ -21,29 +21,13 @@ class AbstractProviderTest extends \PHPUnit_Framework_TestCase
}
$this->objectClass = 'objectClass';
- $this->options = array('debug_logging' => true);
+ $this->options = array('debug_logging' => true, 'indexName' => 'index', 'typeName' => 'type');
$this->objectPersister = $this->getMockObjectPersister();
$this->managerRegistry = $this->getMockManagerRegistry();
$this->objectManager = $this->getMockObjectManager();
$this->indexable = $this->getMockIndexable();
- $index = $this->getMockBuilder('Elastica\Index')->disableOriginalConstructor()->getMock();
- $index->expects($this->any())
- ->method('getName')
- ->will($this->returnValue('index'));
- $type = $this->getMockBuilder('Elastica\Type')->disableOriginalConstructor()->getMock();
- $type->expects($this->any())
- ->method('getName')
- ->will($this->returnValue('type'));
- $type->expects($this->any())
- ->method('getIndex')
- ->will($this->returnValue($index));
-
- $this->objectPersister->expects($this->any())
- ->method('getType')
- ->will($this->returnValue($type));
-
$this->managerRegistry->expects($this->any())
->method('getManagerForClass')
->with($this->objectClass)
diff --git a/Tests/Provider/IndexableTest.php b/Tests/Provider/IndexableTest.php
index 61d7f87..aae6484 100644
--- a/Tests/Provider/IndexableTest.php
+++ b/Tests/Provider/IndexableTest.php
@@ -15,6 +15,14 @@ use FOS\ElasticaBundle\Provider\Indexable;
class IndexableTest extends \PHPUnit_Framework_TestCase
{
+ public function testIndexableUnknown()
+ {
+ $indexable = new Indexable(array());
+ $index = $indexable->isObjectIndexable('index', 'type', new Entity);
+
+ $this->assertTrue($index);
+ }
+
/**
* @dataProvider provideIsIndexableCallbacks
*/
From 089e7f0d2ee45810fa989eabf92a4919ec661a7e Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Tue, 17 Jun 2014 12:12:54 +1000
Subject: [PATCH 270/447] Add unstable badge
[skip ci]
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 7909d2b..631951a 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ Symfony2. Features include:
> **Note** Propel support is limited and contributions fixing issues are welcome!
-[](http://travis-ci.org/FriendsOfSymfony/FOSElasticaBundle) [](https://packagist.org/packages/FriendsOfSymfony/elastica-bundle) [](https://packagist.org/packages/FriendsOfSymfony/elastica-bundle)
+[](http://travis-ci.org/FriendsOfSymfony/FOSElasticaBundle) [](https://packagist.org/packages/FriendsOfSymfony/elastica-bundle) [](https://packagist.org/packages/FriendsOfSymfony/elastica-bundle) [](https://packagist.org/packages/friendsofsymfony/elastica-bundle)
Documentation
-------------
From 1e07d3c7fe5993a22a7ef75c6f29564cfc34d6fc Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Mon, 16 Jun 2014 22:33:31 +1000
Subject: [PATCH 271/447] Update composer.json
---
.travis.yml | 4 +++-
composer.json | 11 ++++++-----
2 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 4fdf2b9..d6ba18a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,5 +9,7 @@ before_script:
- echo "extension = mongo.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
- composer install --dev --prefer-source
+script: vendor/bin/phpunit
+
services:
- - elasticsearch
\ No newline at end of file
+ - elasticsearch
diff --git a/composer.json b/composer.json
index d67e329..bde8b3e 100644
--- a/composer.json
+++ b/composer.json
@@ -6,7 +6,8 @@
"homepage": "https://github.com/FriendsOfSymfony/FOSElasticaBundle",
"license": "MIT",
"authors": [
- { "name": "Thibault Duplessis", "email": "thibault.duplessis@gmail.com" },
+ { "name": "FriendsOfSymfony Community", "homepage": "https://github.com/FriendsOfSymfony/FOSElasticaBundle/contributors" },
+ { "name": "Tim Nagel", "email": "tim@nagel.com.au" },
{ "name": "Richard Miller", "email": "richard.miller@limethinking.co.uk" },
{ "name": "Jeremy Mikola", "email": "jmikola@gmail.com" }
],
@@ -16,13 +17,14 @@
"symfony/console": "~2.1",
"symfony/form": "~2.1",
"symfony/property-access": "~2.2",
- "ruflin/elastica": ">=0.90.10.0, <1.2-dev",
+ "ruflin/elastica": ">=0.90.10.0, <1.3-dev",
"psr/log": "~1.0"
},
"require-dev":{
"doctrine/orm": "~2.2",
"doctrine/doctrine-bundle": "~1.2@beta",
- "doctrine/mongodb-odm": "1.0.*@dev",
+ "doctrine/mongodb-odm": "1.0.*@beta",
+ "phpunit/phpunit": "~4.1",
"propel/propel1": "1.6.*",
"pagerfanta/pagerfanta": "1.0.*@dev",
"knplabs/knp-components": "~1.2",
@@ -38,9 +40,8 @@
"symfony/expression-language" : "~2.4"
},
"autoload": {
- "psr-0": { "FOS\\ElasticaBundle": "" }
+ "psr-4": { "FOS\\ElasticaBundle\\": "" }
},
- "target-dir": "FOS/ElasticaBundle",
"extra": {
"branch-alias": {
"dev-master": "3.0.x-dev"
From ec5c05e8becd6342b20dc0499759e290a6a6f0df Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Tue, 17 Jun 2014 23:22:58 +1000
Subject: [PATCH 272/447] dev
---
Configuration/IndexConfig.php | 2 +-
Configuration/Manager.php | 23 ++++----
Configuration/ManagerInterface.php | 9 +++-
DependencyInjection/FOSElasticaExtension.php | 19 ++-----
Index/IndexManager.php | 6 +--
Index/Resetter.php | 54 +++++++------------
Resources/config/index.xml | 5 +-
Tests/Functional/ConfigurationManagerTest.php | 6 ++-
8 files changed, 59 insertions(+), 65 deletions(-)
diff --git a/Configuration/IndexConfig.php b/Configuration/IndexConfig.php
index 684713e..9add5e3 100644
--- a/Configuration/IndexConfig.php
+++ b/Configuration/IndexConfig.php
@@ -115,7 +115,7 @@ class IndexConfig
/**
* @return boolean
*/
- public function getUseAlias()
+ public function isUseAlias()
{
return $this->useAlias;
}
diff --git a/Configuration/Manager.php b/Configuration/Manager.php
index 85afb99..4436986 100644
--- a/Configuration/Manager.php
+++ b/Configuration/Manager.php
@@ -31,6 +31,20 @@ class Manager implements ManagerInterface
}
}
+ public function getIndexConfiguration($indexName)
+ {
+ if (!$this->hasIndexConfiguration($indexName)) {
+ throw new \InvalidArgumentException(sprintf('Index with name "%s" is not configured.', $indexName));
+ }
+
+ return $this->indexes[$indexName];
+ }
+
+ public function getIndexNames()
+ {
+ return array_keys($this->indexes);
+ }
+
public function getTypeConfiguration($indexName, $typeName)
{
$index = $this->getIndexConfiguration($indexName);
@@ -43,15 +57,6 @@ class Manager implements ManagerInterface
return $type;
}
- public function getIndexConfiguration($indexName)
- {
- if (!$this->hasIndexConfiguration($indexName)) {
- throw new \InvalidArgumentException(sprintf('Index with name "%s" is not configured.', $indexName));
- }
-
- return $this->indexes[$indexName];
- }
-
public function hasIndexConfiguration($indexName)
{
return isset($this->indexes[$indexName]);
diff --git a/Configuration/ManagerInterface.php b/Configuration/ManagerInterface.php
index 7852828..96d510f 100644
--- a/Configuration/ManagerInterface.php
+++ b/Configuration/ManagerInterface.php
@@ -24,6 +24,13 @@ interface ManagerInterface
*/
public function getIndexConfiguration($index);
+ /**
+ * Returns an array of known index names.
+ *
+ * @return array
+ */
+ public function getIndexNames();
+
/**
* Returns a type configuration.
*
@@ -32,4 +39,4 @@ interface ManagerInterface
* @return TypeConfig
*/
public function getTypeConfiguration($index, $type);
-}
\ No newline at end of file
+}
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index d122218..4d76baf 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -74,7 +74,6 @@ class FOSElasticaExtension extends Extension
$container->getDefinition('fos_elastica.config_source.container')->replaceArgument(0, $this->indexConfigs);
$this->loadIndexManager($container);
- $this->loadResetter($container);
$this->createDefaultManagerAlias($config['default_manager'], $container);
}
@@ -549,9 +548,12 @@ class FOSElasticaExtension extends Extension
**/
private function loadIndexManager(ContainerBuilder $container)
{
+ $indexRefs = array_map(function ($index) {
+ return $index['reference'];
+ }, $this->indexConfigs);
+
$managerDef = $container->getDefinition('fos_elastica.index_manager');
- $managerDef->replaceArgument(0, array_keys($this->clients));
- $managerDef->replaceArgument(1, new Reference('fos_elastica.index'));
+ $managerDef->replaceArgument(0, $indexRefs);
}
/**
@@ -609,15 +611,4 @@ class FOSElasticaExtension extends Extension
return $this->clients[$clientName]['reference'];
}
-
- /**
- * Loads the resetter
- *
- * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
- */
- private function loadResetter(ContainerBuilder $container)
- {
- $resetterDef = $container->getDefinition('fos_elastica.resetter');
- $resetterDef->replaceArgument(0, $this->indexConfigs);
- }
}
diff --git a/Index/IndexManager.php b/Index/IndexManager.php
index 543ccae..9dd7bfe 100644
--- a/Index/IndexManager.php
+++ b/Index/IndexManager.php
@@ -2,12 +2,12 @@
namespace FOS\ElasticaBundle\Index;
-use Elastica\Index;
+use FOS\ElasticaBundle\Elastica\Index;
class IndexManager
{
- protected $indexesByName;
- protected $defaultIndexName;
+ private $indexesByName;
+ private $defaultIndexName;
/**
* Constructor.
diff --git a/Index/Resetter.php b/Index/Resetter.php
index 3356c27..aabad87 100644
--- a/Index/Resetter.php
+++ b/Index/Resetter.php
@@ -6,22 +6,27 @@ use Elastica\Exception\ExceptionInterface;
use Elastica\Index;
use Elastica\Exception\ResponseException;
use Elastica\Type\Mapping;
+use FOS\ElasticaBundle\Configuration\Manager;
/**
* Deletes and recreates indexes
*/
class Resetter
{
- protected $indexConfigsByName;
+ /***
+ * @var \FOS\ElasticaBundle\Configuration\Manager
+ */
+ private $configManager;
/**
- * Constructor.
- *
- * @param array $indexConfigsByName
+ * @var IndexManager
*/
- public function __construct(array $indexConfigsByName)
+ private $indexManager;
+
+ public function __construct(Manager $configManager, IndexManager $indexManager)
{
- $this->indexConfigsByName = $indexConfigsByName;
+ $this->configManager = $configManager;
+ $this->indexManager = $indexManager;
}
/**
@@ -29,7 +34,7 @@ class Resetter
*/
public function resetAllIndexes()
{
- foreach (array_keys($this->indexConfigsByName) as $name) {
+ foreach ($this->configManager->getIndexNames() as $name) {
$this->resetIndex($name);
}
}
@@ -42,18 +47,17 @@ class Resetter
*/
public function resetIndex($indexName)
{
- $indexConfig = $this->getIndexConfig($indexName);
- $esIndex = $indexConfig['index'];
- if (isset($indexConfig['use_alias']) && $indexConfig['use_alias']) {
- $name = $indexConfig['name_or_alias'];
- $name .= uniqid();
- $esIndex->overrideName($name);
- $esIndex->create($indexConfig['config']);
+ $indexConfig = $this->configManager->getIndexConfiguration($indexName);
+ $index = $this->indexManager->getIndex($indexName);
- return;
+ if ($indexConfig->isUseAlias()) {
+ $name = sprintf('%s_%s', $indexConfig->getElasticSearchName(), uniqid());
+
+ $index->overrideName($name);
}
- $esIndex->create($indexConfig['config'], true);
+
+ $index->create($indexConfig['config'], true);
}
/**
@@ -108,24 +112,6 @@ class Resetter
return $mapping;
}
- /**
- * Gets an index config by its name
- *
- * @param string $indexName Index name
- *
- * @param $indexName
- * @return array
- * @throws \InvalidArgumentException if no index config exists for the given name
- */
- protected function getIndexConfig($indexName)
- {
- if (!isset($this->indexConfigsByName[$indexName])) {
- throw new \InvalidArgumentException(sprintf('The configuration for index "%s" does not exist.', $indexName));
- }
-
- return $this->indexConfigsByName[$indexName];
- }
-
public function postPopulate($indexName)
{
$indexConfig = $this->getIndexConfig($indexName);
diff --git a/Resources/config/index.xml b/Resources/config/index.xml
index de1a52e..331bfdd 100644
--- a/Resources/config/index.xml
+++ b/Resources/config/index.xml
@@ -28,11 +28,12 @@
-
+
-
+
+
diff --git a/Tests/Functional/ConfigurationManagerTest.php b/Tests/Functional/ConfigurationManagerTest.php
index 0574481..88bfa8b 100644
--- a/Tests/Functional/ConfigurationManagerTest.php
+++ b/Tests/Functional/ConfigurationManagerTest.php
@@ -24,7 +24,11 @@ class ConfigurationManagerTest extends WebTestCase
$manager = $this->getManager($client);
$index = $manager->getIndexConfiguration('index');
- var_dump($index); die;
+
+ $this->assertEquals('index', $index->getName());
+ $this->assertCount(2, $index->getTypes());
+ $this->assertInstanceOf('FOS\\ElasticaBundle\\Configuration\\TypeConfig', $index->getType('type'));
+ $this->assertInstanceOf('FOS\\ElasticaBundle\\Configuration\\TypeConfig', $index->getType('parent'));
}
protected function setUp()
From 8905b4248c07e34c5b5e0c055e7a385e2775978e Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Wed, 18 Jun 2014 16:47:01 +1000
Subject: [PATCH 273/447] Rename Manager to ConfigManager
---
Configuration/{Manager.php => ConfigManager.php} | 4 ++--
Resources/config/config.xml | 2 +-
Resources/config/index.xml | 4 ++--
Tests/Functional/ConfigurationManagerTest.php | 2 +-
4 files changed, 6 insertions(+), 6 deletions(-)
rename Configuration/{Manager.php => ConfigManager.php} (96%)
diff --git a/Configuration/Manager.php b/Configuration/ConfigManager.php
similarity index 96%
rename from Configuration/Manager.php
rename to Configuration/ConfigManager.php
index 4436986..bef061b 100644
--- a/Configuration/Manager.php
+++ b/Configuration/ConfigManager.php
@@ -14,7 +14,7 @@ namespace FOS\ElasticaBundle\Configuration;
/**
* Central manager for index and type configuration.
*/
-class Manager implements ManagerInterface
+class ConfigManager implements ManagerInterface
{
/**
* @var IndexConfig[]
@@ -61,4 +61,4 @@ class Manager implements ManagerInterface
{
return isset($this->indexes[$indexName]);
}
-}
+}
diff --git a/Resources/config/config.xml b/Resources/config/config.xml
index 4ee733f..75531a5 100644
--- a/Resources/config/config.xml
+++ b/Resources/config/config.xml
@@ -17,7 +17,7 @@
-
+
diff --git a/Resources/config/index.xml b/Resources/config/index.xml
index 331bfdd..ef9f4e7 100644
--- a/Resources/config/index.xml
+++ b/Resources/config/index.xml
@@ -5,12 +5,12 @@
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
+ FOS\ElasticaBundle\Finder\TransformedFinder
FOS\ElasticaBundle\Elastica\Index
- Elastica\Type
FOS\ElasticaBundle\Provider\Indexable
FOS\ElasticaBundle\Index\IndexManager
FOS\ElasticaBundle\Index\Resetter
- FOS\ElasticaBundle\Finder\TransformedFinder
+ Elastica\Type
diff --git a/Tests/Functional/ConfigurationManagerTest.php b/Tests/Functional/ConfigurationManagerTest.php
index 88bfa8b..6fdc1d7 100644
--- a/Tests/Functional/ConfigurationManagerTest.php
+++ b/Tests/Functional/ConfigurationManagerTest.php
@@ -47,7 +47,7 @@ class ConfigurationManagerTest extends WebTestCase
/**
* @param Client $client
- * @return \FOS\ElasticaBundle\Configuration\Manager
+ * @return \FOS\ElasticaBundle\Configuration\ConfigManager
*/
private function getManager(Client $client)
{
From afbaf875b990f326d8b284c39ddef082ae6e0b3e Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Wed, 18 Jun 2014 16:48:00 +1000
Subject: [PATCH 274/447] Cache creation of indexes and types in Elastica to
avoid recreation
---
Elastica/Client.php | 13 ++++++++++++-
Elastica/Index.php | 17 +++++++++++++++++
2 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/Elastica/Client.php b/Elastica/Client.php
index 0db15b3..e921965 100644
--- a/Elastica/Client.php
+++ b/Elastica/Client.php
@@ -14,6 +14,13 @@ use FOS\ElasticaBundle\Logger\ElasticaLogger;
*/
class Client extends BaseClient
{
+ /**
+ * Stores created indexes to avoid recreation.
+ *
+ * @var array
+ */
+ private $indexCache = array();
+
/**
* {@inheritdoc}
*/
@@ -42,6 +49,10 @@ class Client extends BaseClient
public function getIndex($name)
{
- return new Index($this, $name);
+ if (isset($this->indexCache[$name])) {
+ return $this->indexCache[$name];
+ }
+
+ return $this->indexCache[$name] = new Index($this, $name);
}
}
diff --git a/Elastica/Index.php b/Elastica/Index.php
index ec32c62..bf37c51 100644
--- a/Elastica/Index.php
+++ b/Elastica/Index.php
@@ -3,6 +3,7 @@
namespace FOS\ElasticaBundle\Elastica;
use Elastica\Index as BaseIndex;
+use Elastica\Type;
/**
* Overridden Elastica Index class that provides dynamic index name changes.
@@ -13,6 +14,13 @@ class Index extends BaseIndex
{
private $originalName;
+ /**
+ * Stores created types to avoid recreation.
+ *
+ * @var array
+ */
+ private $typeCache = array();
+
/**
* Returns the original name of the index if the index has been renamed for reindexing
* or realiasing purposes.
@@ -24,6 +32,15 @@ class Index extends BaseIndex
return $this->originalName ?: $this->_name;
}
+ public function getType($type)
+ {
+ if (isset($this->typeCache[$type])) {
+ return $this->typeCache[$type];
+ }
+
+ return $this->typeCache[$type] = parent::getType($type);
+ }
+
/**
* Reassign index name
*
From b155f304e434b0cc0e0b6ee9310bd9b1e40e3c20 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Wed, 18 Jun 2014 16:49:38 +1000
Subject: [PATCH 275/447] Move IndexManager's resolution to tagged index
services
---
DependencyInjection/Compiler/IndexPass.php | 38 ++++++++++++++++++++
DependencyInjection/FOSElasticaExtension.php | 3 ++
FOSElasticaBundle.php | 4 ++-
Index/IndexManager.php | 26 +++++++-------
Resources/config/index.xml | 1 +
5 files changed, 58 insertions(+), 14 deletions(-)
create mode 100644 DependencyInjection/Compiler/IndexPass.php
diff --git a/DependencyInjection/Compiler/IndexPass.php b/DependencyInjection/Compiler/IndexPass.php
new file mode 100644
index 0000000..e131214
--- /dev/null
+++ b/DependencyInjection/Compiler/IndexPass.php
@@ -0,0 +1,38 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace FOS\ElasticaBundle\DependencyInjection\Compiler;
+
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Reference;
+
+class IndexPass implements CompilerPassInterface
+{
+ /**
+ * {@inheritDoc}
+ */
+ public function process(ContainerBuilder $container)
+ {
+ if (!$container->hasDefinition('fos_elastica.index_manager')) {
+ return;
+ }
+
+ $indexes = array();
+ foreach ($container->findTaggedServiceIds('fos_elastica.index') as $id => $tags) {
+ foreach ($tags as $tag) {
+ $indexes[$tag['name']] = new Reference($id);
+ }
+ }
+
+ $container->getDefinition('fos_elastica.index_manager')->replaceArgument(0, $indexes);
+ }
+}
diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php
index 4d76baf..4730c0b 100644
--- a/DependencyInjection/FOSElasticaExtension.php
+++ b/DependencyInjection/FOSElasticaExtension.php
@@ -133,6 +133,9 @@ class FOSElasticaExtension extends Extension
$indexDef = new DefinitionDecorator('fos_elastica.index_prototype');
$indexDef->replaceArgument(0, $indexName);
+ $indexDef->addTag('fos_elastica.index', array(
+ 'name' => $name,
+ ));
if (isset($index['client'])) {
$client = $this->getClient($index['client']);
diff --git a/FOSElasticaBundle.php b/FOSElasticaBundle.php
index ac4cc3d..3dec2a0 100644
--- a/FOSElasticaBundle.php
+++ b/FOSElasticaBundle.php
@@ -3,6 +3,7 @@
namespace FOS\ElasticaBundle;
use FOS\ElasticaBundle\DependencyInjection\Compiler\ConfigSourcePass;
+use FOS\ElasticaBundle\DependencyInjection\Compiler\IndexPass;
use FOS\ElasticaBundle\DependencyInjection\Compiler\RegisterProvidersPass;
use FOS\ElasticaBundle\DependencyInjection\Compiler\TransformerPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -22,8 +23,9 @@ class FOSElasticaBundle extends Bundle
{
parent::build($container);
+ $container->addCompilerPass(new ConfigSourcePass());
+ $container->addCompilerPass(new IndexPass());
$container->addCompilerPass(new RegisterProvidersPass(), PassConfig::TYPE_BEFORE_REMOVING);
$container->addCompilerPass(new TransformerPass());
- $container->addCompilerPass(new ConfigSourcePass());
}
}
diff --git a/Index/IndexManager.php b/Index/IndexManager.php
index 9dd7bfe..38249a7 100644
--- a/Index/IndexManager.php
+++ b/Index/IndexManager.php
@@ -6,19 +6,19 @@ use FOS\ElasticaBundle\Elastica\Index;
class IndexManager
{
- private $indexesByName;
- private $defaultIndexName;
+ /**
+ * @var array
+ */
+ private $indexes;
/**
- * Constructor.
- *
- * @param array $indexesByName
+ * @param array $indexes
* @param Index $defaultIndex
*/
- public function __construct(array $indexesByName, Index $defaultIndex)
+ public function __construct(array $indexes, Index $defaultIndex)
{
- $this->indexesByName = $indexesByName;
- $this->defaultIndexName = $defaultIndex->getName();
+ $this->defaultIndex = $defaultIndex;
+ $this->indexes = $indexes;
}
/**
@@ -28,7 +28,7 @@ class IndexManager
*/
public function getAllIndexes()
{
- return $this->indexesByName;
+ return $this->indexes;
}
/**
@@ -41,14 +41,14 @@ class IndexManager
public function getIndex($name = null)
{
if (null === $name) {
- $name = $this->defaultIndexName;
+ return $this->defaultIndex;
}
- if (!isset($this->indexesByName[$name])) {
+ if (!isset($this->indexes[$name])) {
throw new \InvalidArgumentException(sprintf('The index "%s" does not exist', $name));
}
- return $this->indexesByName[$name];
+ return $this->indexes[$name];
}
/**
@@ -58,6 +58,6 @@ class IndexManager
*/
public function getDefaultIndex()
{
- return $this->getIndex($this->defaultIndexName);
+ return $this->defaultIndex;
}
}
diff --git a/Resources/config/index.xml b/Resources/config/index.xml
index ef9f4e7..60b75a9 100644
--- a/Resources/config/index.xml
+++ b/Resources/config/index.xml
@@ -20,6 +20,7 @@
+
From 949ea6963f6c642d4fb20550b4f78eb5cf6874e3 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Wed, 18 Jun 2014 19:55:33 +1000
Subject: [PATCH 276/447] Revert "Make the class of
fos_elastica.paginator.subscriber service configurable"
This reverts commit fe19df365a74373c19161449526d35beb708e49b.
---
Resources/config/config.xml | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/Resources/config/config.xml b/Resources/config/config.xml
index 5058626..f4b2606 100644
--- a/Resources/config/config.xml
+++ b/Resources/config/config.xml
@@ -22,7 +22,6 @@
FOS\ElasticaBundle\Persister\ObjectSerializerPersister
FOS\ElasticaBundle\Transformer\ModelToElasticaAutoTransformer
FOS\ElasticaBundle\Transformer\ModelToElasticaIdentifierTransformer
- FOS\ElasticaBundle\Subscriber\PaginateElasticaQuerySubscriber
@@ -93,7 +92,7 @@
-
+
From 3ae382c9331462ca5543b3686444877e4a177fe5 Mon Sep 17 00:00:00 2001
From: Tim Nagel
Date: Wed, 18 Jun 2014 20:02:05 +1000
Subject: [PATCH 277/447] Add tests to make sure KnpPaginator plays nice
---
Tests/Functional/app/Basic/bundles.php | 7 +++++--
Tests/Functional/app/Basic/config.yml | 7 +++++++
Tests/Functional/app/config/config.yml | 2 +-
composer.json | 4 +++-
4 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/Tests/Functional/app/Basic/bundles.php b/Tests/Functional/app/Basic/bundles.php
index 9f23bdf..7bcaae8 100644
--- a/Tests/Functional/app/Basic/bundles.php
+++ b/Tests/Functional/app/Basic/bundles.php
@@ -1,10 +1,13 @@
Date: Wed, 18 Jun 2014 16:12:16 +0300
Subject: [PATCH 278/447] Added elapsed item to toolbar and menu
Kind similar to doctrine toolbar item
---
Resources/views/Collector/elastica.html.twig | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Resources/views/Collector/elastica.html.twig b/Resources/views/Collector/elastica.html.twig
index 637dae7..e6d7072 100644
--- a/Resources/views/Collector/elastica.html.twig
+++ b/Resources/views/Collector/elastica.html.twig
@@ -4,6 +4,9 @@
{% set icon %}
{{ collector.querycount }}
+ {% if collector.querycount > 0 %}
+ in {{ '%0.2f'|format(collector.time * 1000) }} ms
+ {% endif %}
{% endset %}
{% set text %}