Skip to content

Commit 4e48409

Browse files
author
Joris van de Sande
committed
Don't use parent identifier for objects/nested documents
This fixes #357
1 parent 347aa2f commit 4e48409

File tree

2 files changed

+125
-50
lines changed

2 files changed

+125
-50
lines changed

Tests/Transformer/ModelToElasticaAutoTransformerTest.php

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,19 @@ public function getUpperAlias()
122122
{
123123
return $this->getUpper();
124124
}
125+
126+
public function getObjWithoutIdentifier()
127+
{
128+
return (object) array('foo' => 'foo', 'bar' => 'foo');
129+
}
130+
131+
public function getSubWithoutIdentifier()
132+
{
133+
return array(
134+
(object) array('foo' => 'foo', 'bar' => 'foo'),
135+
(object) array('foo' => 'bar', 'bar' => 'bar'),
136+
);
137+
}
125138
}
126139

127140
class ModelToElasticaAutoTransformerTest extends \PHPUnit_Framework_TestCase
@@ -409,6 +422,50 @@ public function testParentMappingWithCustomProperty()
409422
$this->assertEquals("parent", $document->getParent());
410423
}
411424

425+
public function testThatMappedObjectsDontNeedAnIdentifierField()
426+
{
427+
$transformer = $this->getTransformer();
428+
$document = $transformer->transform(new POPO(), array(
429+
'objWithoutIdentifier' => array(
430+
'type' => 'object',
431+
'properties' => array(
432+
'foo' => array(),
433+
'bar' => array()
434+
)
435+
),
436+
));
437+
$data = $document->getData();
438+
439+
$this->assertTrue(array_key_exists('objWithoutIdentifier', $data));
440+
$this->assertInternalType('array', $data['objWithoutIdentifier']);
441+
$this->assertEquals(array(
442+
'foo' => 'foo',
443+
'bar' => 'foo'
444+
), $data['objWithoutIdentifier']);
445+
}
446+
447+
public function testThatNestedObjectsDontNeedAnIdentifierField()
448+
{
449+
$transformer = $this->getTransformer();
450+
$document = $transformer->transform(new POPO(), array(
451+
'subWithoutIdentifier' => array(
452+
'type' => 'nested',
453+
'properties' => array(
454+
'foo' => array(),
455+
'bar' => array()
456+
),
457+
),
458+
));
459+
$data = $document->getData();
460+
461+
$this->assertTrue(array_key_exists('subWithoutIdentifier', $data));
462+
$this->assertInternalType('array', $data['subWithoutIdentifier']);
463+
$this->assertEquals(array(
464+
array('foo' => 'foo', 'bar' => 'foo'),
465+
array('foo' => 'bar', 'bar' => 'bar'),
466+
), $data['subWithoutIdentifier']);
467+
}
468+
412469
/**
413470
* @param null|\Symfony\Component\EventDispatcher\EventDispatcherInterface $dispatcher
414471
*

Transformer/ModelToElasticaAutoTransformer.php

Lines changed: 68 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -68,54 +68,7 @@ public function setPropertyAccessor(PropertyAccessorInterface $propertyAccessor)
6868
public function transform($object, array $fields)
6969
{
7070
$identifier = $this->propertyAccessor->getValue($object, $this->options['identifier']);
71-
$document = new Document($identifier);
72-
73-
foreach ($fields as $key => $mapping) {
74-
if ($key == '_parent') {
75-
$property = (null !== $mapping['property']) ? $mapping['property'] : $mapping['type'];
76-
$value = $this->propertyAccessor->getValue($object, $property);
77-
$document->setParent($this->propertyAccessor->getValue($value, $mapping['identifier']));
78-
79-
continue;
80-
}
81-
82-
$path = isset($mapping['property_path']) ?
83-
$mapping['property_path'] :
84-
$key;
85-
if (false === $path) {
86-
continue;
87-
}
88-
$value = $this->propertyAccessor->getValue($object, $path);
89-
90-
if (isset($mapping['type']) && in_array($mapping['type'], array('nested', 'object')) && isset($mapping['properties']) && !empty($mapping['properties'])) {
91-
/* $value is a nested document or object. Transform $value into
92-
* an array of documents, respective the mapped properties.
93-
*/
94-
$document->set($key, $this->transformNested($value, $mapping['properties']));
95-
96-
continue;
97-
}
98-
99-
if (isset($mapping['type']) && $mapping['type'] == 'attachment') {
100-
// $value is an attachment. Add it to the document.
101-
if ($value instanceof \SplFileInfo) {
102-
$document->addFile($key, $value->getPathName());
103-
} else {
104-
$document->addFileContent($key, $value);
105-
}
106-
107-
continue;
108-
}
109-
110-
$document->set($key, $this->normalizeValue($value));
111-
}
112-
113-
if ($this->dispatcher) {
114-
$event = new TransformEvent($document, $fields, $object);
115-
$this->dispatcher->dispatch(TransformEvent::POST_TRANSFORM, $event);
116-
117-
$document = $event->getDocument();
118-
}
71+
$document = $this->transformObjectToDocument($object, $fields, $identifier);
11972

12073
return $document;
12174
}
@@ -133,13 +86,13 @@ protected function transformNested($objects, array $fields)
13386
if (is_array($objects) || $objects instanceof \Traversable || $objects instanceof \ArrayAccess) {
13487
$documents = array();
13588
foreach ($objects as $object) {
136-
$document = $this->transform($object, $fields);
89+
$document = $this->transformObjectToDocument($object, $fields);
13790
$documents[] = $document->getData();
13891
}
13992

14093
return $documents;
14194
} elseif (null !== $objects) {
142-
$document = $this->transform($objects, $fields);
95+
$document = $this->transformObjectToDocument($objects, $fields);
14396

14497
return $document->getData();
14598
}
@@ -173,4 +126,69 @@ protected function normalizeValue($value)
173126

174127
return $value;
175128
}
129+
130+
/**
131+
* Transforms the given object to an elastica document
132+
*
133+
* @param object $object the object to convert
134+
* @param array $fields the keys we want to have in the returned array
135+
* @param string $identifier the identifier for the new document
136+
* @return Document
137+
*/
138+
protected function transformObjectToDocument($object, array $fields, $identifier = '')
139+
{
140+
$document = new Document($identifier);
141+
142+
foreach ($fields as $key => $mapping) {
143+
if ($key == '_parent') {
144+
$property = (null !== $mapping['property']) ? $mapping['property'] : $mapping['type'];
145+
$value = $this->propertyAccessor->getValue($object, $property);
146+
$document->setParent($this->propertyAccessor->getValue($value, $mapping['identifier']));
147+
148+
continue;
149+
}
150+
151+
$path = isset($mapping['property_path']) ?
152+
$mapping['property_path'] :
153+
$key;
154+
if (false === $path) {
155+
continue;
156+
}
157+
$value = $this->propertyAccessor->getValue($object, $path);
158+
159+
if (isset($mapping['type']) && in_array(
160+
$mapping['type'], array('nested', 'object')
161+
) && isset($mapping['properties']) && !empty($mapping['properties'])
162+
) {
163+
/* $value is a nested document or object. Transform $value into
164+
* an array of documents, respective the mapped properties.
165+
*/
166+
$document->set($key, $this->transformNested($value, $mapping['properties']));
167+
168+
continue;
169+
}
170+
171+
if (isset($mapping['type']) && $mapping['type'] == 'attachment') {
172+
// $value is an attachment. Add it to the document.
173+
if ($value instanceof \SplFileInfo) {
174+
$document->addFile($key, $value->getPathName());
175+
} else {
176+
$document->addFileContent($key, $value);
177+
}
178+
179+
continue;
180+
}
181+
182+
$document->set($key, $this->normalizeValue($value));
183+
}
184+
185+
if ($this->dispatcher) {
186+
$event = new TransformEvent($document, $fields, $object);
187+
$this->dispatcher->dispatch(TransformEvent::POST_TRANSFORM, $event);
188+
189+
$document = $event->getDocument();
190+
}
191+
192+
return $document;
193+
}
176194
}

0 commit comments

Comments
 (0)