diff --git a/CHANGELOG-3.1.md b/CHANGELOG-3.1.md index 8880675..12fbb05 100644 --- a/CHANGELOG-3.1.md +++ b/CHANGELOG-3.1.md @@ -19,3 +19,5 @@ https://github.com/FriendsOfSymfony/FOSElasticaBundle/compare/v3.0.4...v3.1.0 this class on every request where doctrine is active. #729 * Added ability to configure `date_detection`, `numeric_detection` and `dynamic_date_formats` for types. #753 + * New event `POST_TRANSFORM` which allows developers to add custom properties to + Elastica Documents for indexing. diff --git a/Event/TransformEvent.php b/Event/TransformEvent.php new file mode 100644 index 0000000..4f6871f --- /dev/null +++ b/Event/TransformEvent.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\ElasticaBundle\Event; + +use Symfony\Component\EventDispatcher\Event; + +class TransformEvent extends Event +{ + const POST_TRANSFORM = 'fos_elastica.post_transform'; + + /** + * @var mixed + */ + private $document; + + /** + * @var array + */ + private $fields; + + /** + * @var mixed + */ + private $object; + + /** + * @param mixed $document + * @param array $fields + * @param mixed $object + */ + public function __construct($document, array $fields, $object) + { + $this->document = $document; + $this->fields = $fields; + $this->object = $object; + } + + /** + * @return mixed + */ + public function getDocument() + { + return $this->document; + } + + /** + * @return array + */ + public function getFields() + { + return $this->fields; + } + + /** + * @return mixed + */ + public function getObject() + { + return $this->object; + } + + /** + * @param mixed $document + */ + public function setDocument($document) + { + $this->document = $document; + } +} diff --git a/Resources/config/transformer.xml b/Resources/config/transformer.xml index 4ce5062..0957152 100644 --- a/Resources/config/transformer.xml +++ b/Resources/config/transformer.xml @@ -12,7 +12,8 @@ - + + diff --git a/Resources/doc/cookbook/custom-properties.md b/Resources/doc/cookbook/custom-properties.md new file mode 100644 index 0000000..cc7751e --- /dev/null +++ b/Resources/doc/cookbook/custom-properties.md @@ -0,0 +1,33 @@ +##### Custom Repositories + +Since FOSElasticaBundle 3.1.0, we now dispatch an event for each transformation of an +object into an Elastica document which allows you to set custom properties on the Elastica +document for indexing. + +Set up an event listener or subscriber for +`FOS\ElasticaBundle\Event\TransformEvent::POST_TRANSFORM` to be able to inject your own +parameters. + +```php +class CustomPropertyListener implements EventSubscriberInterface +{ + private $anotherService; + + // ... + + public function addCustomProperty(TransformEvent $event) + { + $document = $event->getDocument(); + $custom = $this->anotherService->calculateCustom($event->getObject()); + + $document->set('custom', $custom); + } + + public static function getSubscribedEvents() + { + return array( + TransformEvent::POST_TRANSFORM => 'addCustomProperty', + ); + } +} +``` diff --git a/Resources/doc/index.md b/Resources/doc/index.md index 349723b..c856798 100644 --- a/Resources/doc/index.md +++ b/Resources/doc/index.md @@ -13,6 +13,7 @@ Cookbook Entries ---------------- * [Aliased Indexes](cookbook/aliased-indexes.md) +* [Custom Indexed Properties](cookbook/custom-properties.md) * [Custom Repositories](cookbook/custom-repositories.md) * [HTTP Headers for Elastica](cookbook/elastica-client-http-headers.md) * Performance - [Logging](cookbook/logging.md) diff --git a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php index 1fa6a8e..bb52129 100644 --- a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php +++ b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php @@ -2,6 +2,7 @@ namespace FOS\ElasticaBundle\Tests\Transformer\ModelToElasticaAutoTransformer; +use FOS\ElasticaBundle\Event\TransformEvent; use FOS\ElasticaBundle\Transformer\ModelToElasticaAutoTransformer; use Symfony\Component\PropertyAccess\PropertyAccess; @@ -132,6 +133,21 @@ class ModelToElasticaAutoTransformerTest extends \PHPUnit_Framework_TestCase } } + public function testTransformerDispatches() + { + $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface') + ->getMock(); + $dispatcher->expects($this->once()) + ->method('dispatch') + ->with( + TransformEvent::POST_TRANSFORM, + $this->isInstanceOf('FOS\ElasticaBundle\Event\TransformEvent') + ); + + $transformer = $this->getTransformer($dispatcher); + $transformer->transform(new POPO(), array()); + } + public function testThatCanTransformObject() { $transformer = $this->getTransformer(); @@ -295,8 +311,8 @@ class ModelToElasticaAutoTransformerTest extends \PHPUnit_Framework_TestCase $this->assertTrue(array_key_exists('obj', $data)); $this->assertInternalType('array', $data['obj']); $this->assertEquals(array( - 'foo' => 'foo', - 'bar' => 'foo', + 'foo' => 'foo', + 'bar' => 'foo', 'id' => 1 ), $data['obj']); } @@ -387,11 +403,12 @@ class ModelToElasticaAutoTransformerTest extends \PHPUnit_Framework_TestCase } /** + * @param null|\Symfony\Component\EventDispatcher\EventDispatcherInterface $dispatcher * @return ModelToElasticaAutoTransformer */ - private function getTransformer() + private function getTransformer($dispatcher = null) { - $transformer = new ModelToElasticaAutoTransformer(); + $transformer = new ModelToElasticaAutoTransformer(array(), $dispatcher); $transformer->setPropertyAccessor(PropertyAccess::getPropertyAccessor()); return $transformer; diff --git a/Transformer/ModelToElasticaAutoTransformer.php b/Transformer/ModelToElasticaAutoTransformer.php index 106db15..eff29d2 100644 --- a/Transformer/ModelToElasticaAutoTransformer.php +++ b/Transformer/ModelToElasticaAutoTransformer.php @@ -2,6 +2,8 @@ namespace FOS\ElasticaBundle\Transformer; +use FOS\ElasticaBundle\Event\TransformEvent; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\PropertyAccess\PropertyAccessorInterface; use Elastica\Document; @@ -12,6 +14,11 @@ use Elastica\Document; */ class ModelToElasticaAutoTransformer implements ModelToElasticaTransformerInterface { + /** + * @var EventDispatcherInterface + */ + protected $dispatcher; + /** * Optional parameters * @@ -32,10 +39,12 @@ class ModelToElasticaAutoTransformer implements ModelToElasticaTransformerInterf * Instanciates a new Mapper * * @param array $options + * @param EventDispatcherInterface $dispatcher */ - public function __construct(array $options = array()) + public function __construct(array $options = array(), EventDispatcherInterface $dispatcher = null) { $this->options = array_merge($this->options, $options); + $this->dispatcher = $dispatcher; } /** @@ -92,6 +101,13 @@ class ModelToElasticaAutoTransformer implements ModelToElasticaTransformerInterf $document->set($key, $this->normalizeValue($value)); } + if ($this->dispatcher) { + $event = new TransformEvent($document, $fields, $object); + $this->dispatcher->dispatch(TransformEvent::POST_TRANSFORM, $event); + + $document = $event->getDocument(); + } + return $document; }