Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/serializer-transformer' into ser…
Browse files Browse the repository at this point in the history
…ializer-integration

Conflicts:
	DependencyInjection/FOSElasticaExtension.php
	Resources/config/config.xml
  • Loading branch information
damienalexandre committed Nov 29, 2013
2 parents 40d3df9 + 37cfdb0 commit d546b4d
Show file tree
Hide file tree
Showing 7 changed files with 351 additions and 15 deletions.
47 changes: 33 additions & 14 deletions DependencyInjection/FOSElasticaExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -40,8 +41,8 @@ public function load(array $configs, ContainerBuilder $container)
}

$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);
Expand Down Expand Up @@ -94,7 +95,7 @@ protected function loadClients(array $clients, ContainerBuilder $container)
* @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) {
Expand Down Expand Up @@ -129,7 +130,7 @@ protected function loadIndexes(array $indexes, ContainerBuilder $container, arra
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;
Expand Down Expand Up @@ -171,7 +172,7 @@ protected function loadIndexFinder(ContainerBuilder $container, $name, $indexId)
* @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);
Expand All @@ -180,12 +181,12 @@ protected function loadTypes(array $types, ContainerBuilder $container, $indexNa
$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']));
}
Expand Down Expand Up @@ -324,8 +325,14 @@ protected function loadModelToElasticaTransformer(array $typeConfig, ContainerBu
return $typeConfig['model_to_elastica_transformer']['service'];
}

if ($this->serializerConfig) {
$abstractId = sprintf('fos_elastica.model_to_elastica_identifier_transformer');
} else {
$abstractId = sprintf('fos_elastica.model_to_elastica_transformer');
}

$serviceId = sprintf('fos_elastica.model_to_elastica_transformer.%s.%s', $indexName, $typeName);
$serviceDef = new DefinitionDecorator('fos_elastica.model_to_elastica_transformer');
$serviceDef = new DefinitionDecorator($abstractId);
$serviceDef->replaceArgument(0, array(
'identifier' => $typeConfig['identifier']
));
Expand All @@ -336,12 +343,24 @@ protected function loadModelToElasticaTransformer(array $typeConfig, ContainerBu

protected function loadObjectPersister(array $typeConfig, Definition $typeDef, ContainerBuilder $container, $indexName, $typeName, $transformerId)
{
$arguments = array(
$typeDef,
new Reference($transformerId),
$typeConfig['model'],
);

if ($this->serializerConfig) {
$abstractId = 'fos_elastica.object_serializer_persister';
} else {
$abstractId = 'fos_elastica.object_persister';
$arguments[] = $this->typeFields[sprintf('%s/%s', $indexName, $typeName)];
}
$serviceId = sprintf('fos_elastica.object_persister.%s.%s', $indexName, $typeName);
$serviceDef = new DefinitionDecorator('fos_elastica.object_persister');
$serviceDef->replaceArgument(0, $typeDef);
$serviceDef->replaceArgument(1, new Reference($transformerId));
$serviceDef->replaceArgument(2, $typeConfig['model']);
$serviceDef->replaceArgument(3, $this->typeFields[sprintf('%s/%s', $indexName, $typeName)]);
$serviceDef = new DefinitionDecorator($abstractId);
foreach ($arguments as $i => $argument) {
$serviceDef->replaceArgument($i, $argument);
}

$container->setDefinition($serviceId, $serviceDef);

return $serviceId;
Expand Down
97 changes: 97 additions & 0 deletions Persister/ObjectSerializerPersister.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php

namespace FOS\ElasticaBundle\Persister;

use Elastica\Type;
use FOS\ElasticaBundle\Transformer\ModelToElasticaTransformerInterface;

/**
* Inserts, replaces and deletes single objects in an elastica type, making use
* of elastica's serializer support to convert objects in to elastica documents.
* Accepts domain model objects and passes them directly to elastica
*
* @author Lea Haensenberber <lea.haensenberger@gmail.com>
*/
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());
}
}
13 changes: 13 additions & 0 deletions Resources/config/config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,26 @@
<argument /> <!-- transformer -->
</service>

<service id="fos_elastica.object_serializer_persister" class="FOS\ElasticaBundle\Persister\ObjectSerializerPersister" abstract="true">
<argument /> <!-- type -->
<argument /> <!-- model to elastica transformer -->
<argument /> <!-- model -->
</service>

<service id="fos_elastica.model_to_elastica_transformer" class="FOS\ElasticaBundle\Transformer\ModelToElasticaAutoTransformer" public="false" abstract="true">
<argument /> <!-- options -->
<call method="setPropertyAccessor">
<argument type="service" id="fos_elastica.property_accessor" />
</call>
</service>

<service id="fos_elastica.model_to_elastica_identifier_transformer" class="FOS\ElasticaBundle\Transformer\ModelToElasticaIdentifierTransformer" public="false" abstract="true">
<argument /> <!-- options -->
<call method="setPropertyAccessor">
<argument type="service" id="fos_elastica.property_accessor" />
</call>
</service>

<service id="fos_elastica.elastica_to_model_transformer.collection" class="%fos_elastica.elastica_to_model_transformer.collection.class%" public="true" abstract="true">
<argument type="collection" /> <!-- transformers -->
</service>
Expand Down
117 changes: 117 additions & 0 deletions Tests/Persister/ObjectSerializerPersisterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<?php

namespace FOS\ElasticaBundle\Tests\ObjectSerializerPersister;

use FOS\ElasticaBundle\Persister\ObjectPersister;
use FOS\ElasticaBundle\Persister\ObjectSerializerPersister;
use FOS\ElasticaBundle\Transformer\ModelToElasticaAutoTransformer;
use FOS\ElasticaBundle\Transformer\ModelToElasticaIdentifierTransformer;
use Symfony\Component\PropertyAccess\PropertyAccess;

class POPO
{
public $id = 123;
public $name = 'popoName';

public function getId()
{
return $this->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;
}
}
1 change: 0 additions & 1 deletion Tests/Transformer/ModelToElasticaAutoTransformerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ class ModelToElasticaAutoTransformerTest extends \PHPUnit_Framework_TestCase
public function setUp()
{
if (!class_exists('Elastica\Document')) {
;
$this->markTestSkipped('The Elastica library classes are not available');
}
}
Expand Down
Loading

0 comments on commit d546b4d

Please sign in to comment.