From 5128373cf464be781deade4a1a53d891ffd904ec Mon Sep 17 00:00:00 2001 From: Joris van de Sande Date: Thu, 6 Aug 2015 09:43:26 +0200 Subject: [PATCH] Don't use parent identifier for objects/nested documents This fixes #357 --- .../ModelToElasticaAutoTransformerTest.php | 57 +++++++++++++ .../ModelToElasticaAutoTransformer.php | 83 +++++++++++-------- 2 files changed, 106 insertions(+), 34 deletions(-) diff --git a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php index 11bf52181..b80b29194 100644 --- a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php +++ b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php @@ -121,6 +121,19 @@ public function getUpperAlias() { return $this->getUpper(); } + + public function getObjWithoutIdentifier() + { + return (object) array('foo' => 'foo', 'bar' => 'foo'); + } + + public function getSubWithoutIdentifier() + { + return array( + (object) array('foo' => 'foo', 'bar' => 'foo'), + (object) array('foo' => 'bar', 'bar' => 'bar'), + ); + } } class ModelToElasticaAutoTransformerTest extends \PHPUnit_Framework_TestCase @@ -379,6 +392,50 @@ public function testParentMappingWithCustomProperty() $this->assertEquals("parent", $document->getParent()); } + public function testThatMappedObjectsDontNeedAnIdentifierField() + { + $transformer = $this->getTransformer(); + $document = $transformer->transform(new POPO(), array( + 'objWithoutIdentifier' => array( + 'type' => 'object', + 'properties' => array( + 'foo' => array(), + 'bar' => array() + ) + ), + )); + $data = $document->getData(); + + $this->assertTrue(array_key_exists('objWithoutIdentifier', $data)); + $this->assertInternalType('array', $data['objWithoutIdentifier']); + $this->assertEquals(array( + 'foo' => 'foo', + 'bar' => 'foo' + ), $data['objWithoutIdentifier']); + } + + public function testThatNestedObjectsDontNeedAnIdentifierField() + { + $transformer = $this->getTransformer(); + $document = $transformer->transform(new POPO(), array( + 'subWithoutIdentifier' => array( + 'type' => 'nested', + 'properties' => array( + 'foo' => array(), + 'bar' => array() + ), + ), + )); + $data = $document->getData(); + + $this->assertTrue(array_key_exists('subWithoutIdentifier', $data)); + $this->assertInternalType('array', $data['subWithoutIdentifier']); + $this->assertEquals(array( + array('foo' => 'foo', 'bar' => 'foo'), + array('foo' => 'bar', 'bar' => 'bar'), + ), $data['subWithoutIdentifier']); + } + /** * @return ModelToElasticaAutoTransformer */ diff --git a/Transformer/ModelToElasticaAutoTransformer.php b/Transformer/ModelToElasticaAutoTransformer.php index 3ca2281c7..bd7e0ce22 100644 --- a/Transformer/ModelToElasticaAutoTransformer.php +++ b/Transformer/ModelToElasticaAutoTransformer.php @@ -59,38 +59,7 @@ public function setPropertyAccessor(PropertyAccessorInterface $propertyAccessor) public function transform($object, array $fields) { $identifier = $this->propertyAccessor->getValue($object, $this->options['identifier']); - $document = new Document($identifier); - - foreach ($fields as $key => $mapping) { - if ($key == '_parent') { - $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')) && isset($mapping['properties']) && !empty($mapping['properties'])) { - /* $value is a nested document or object. Transform $value into - * an array of documents, respective the mapped properties. - */ - $document->set($key, $this->transformNested($value, $mapping['properties'])); - continue; - } - - if (isset($mapping['type']) && $mapping['type'] == 'attachment') { - // $value is an attachment. Add it to the document. - if ($value instanceof \SplFileInfo) { - $document->addFile($key, $value->getPathName()); - } else { - $document->addFileContent($key, $value); - } - continue; - } - - $document->set($key, $this->normalizeValue($value)); - } + $document = $this->transformObjectToDocument($object, $fields, $identifier); return $document; } @@ -108,13 +77,13 @@ protected function transformNested($objects, array $fields) if (is_array($objects) || $objects instanceof \Traversable || $objects instanceof \ArrayAccess) { $documents = array(); foreach ($objects as $object) { - $document = $this->transform($object, $fields); + $document = $this->transformObjectToDocument($object, $fields); $documents[] = $document->getData(); } return $documents; } elseif (null !== $objects) { - $document = $this->transform($objects, $fields); + $document = $this->transformObjectToDocument($objects, $fields); return $document->getData(); } @@ -148,4 +117,50 @@ protected function normalizeValue($value) return $value; } + + /** + * Transforms the given object to an elastica document + * + * @param object $object the object to convert + * @param array $fields the keys we want to have in the returned array + * @param string $identifier the identifier for the new document + * @return Document + */ + protected function transformObjectToDocument($object, array $fields, $identifier = '') + { + $document = new Document($identifier); + + foreach ($fields as $key => $mapping) { + if ($key == '_parent') { + $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')) && isset($mapping['properties']) && !empty($mapping['properties'])) { + /* $value is a nested document or object. Transform $value into + * an array of documents, respective the mapped properties. + */ + $document->set($key, $this->transformNested($value, $mapping['properties'])); + continue; + } + + if (isset($mapping['type']) && $mapping['type'] == 'attachment') { + // $value is an attachment. Add it to the document. + if ($value instanceof \SplFileInfo) { + $document->addFile($key, $value->getPathName()); + } else { + $document->addFileContent($key, $value); + } + continue; + } + + $document->set($key, $this->normalizeValue($value)); + } + + return $document; + } }