Skip to content

PRE_TRANSFORM and POST_TRANSFORM events when using serializer to transform object to elastica document #1185

@rahit

Description

@rahit

It is already mentioned in issue #1142 that, POST_TRANSFORM event does not trigger when object serialization is enabled. This is also true for PRE_TRANSFORM event.

This events mainly triggered in transformObjectToDocument() method of ModelToElasticaAutoTransformer class.

// Transformer/ModelToElasticaAutoTransformer.php
protected function transformObjectToDocument($object, array $fields, $identifier = '')
    {
        $document = new Document($identifier);

        if ($this->dispatcher) {
            $event = new TransformEvent($document, $fields, $object);
            $this->dispatcher->dispatch(TransformEvent::PRE_TRANSFORM, $event);

            $document = $event->getDocument();
        }

        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;
            }

            $path = isset($mapping['property_path']) ?
                $mapping['property_path'] :
                $key;
            if (false === $path) {
                continue;
            }
            $value = $this->propertyAccessor->getValue($object, $path);

            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));
        }

        if ($this->dispatcher) {
            $event = new TransformEvent($document, $fields, $object);
            $this->dispatcher->dispatch(TransformEvent::POST_TRANSFORM, $event);

            $document = $event->getDocument();
        }

        return $document;
    }

trunsform() method utilize this transformObjectToDocument() method to do the conversion.

// Transformer/ModelToElasticaAutoTransformer.php
public function transform($object, array $fields)
    {
        $identifier = $this->propertyAccessor->getValue($object, $this->options['identifier']);
        $document = $this->transformObjectToDocument($object, $fields, $identifier);

        return $document;
    }

But this is not the case for serialize persister. ObjectSerializePersister uses ModelToElasticaIdentifierTransformer which overrides the transform() method.

// Transformer/ModelToElasticaIdentifierTransformer.php
class ModelToElasticaIdentifierTransformer extends ModelToElasticaAutoTransformer
{
    /**
     * Creates an elastica document with the id of the doctrine object as id.
     *
     * @param object $object the object to convert
     * @param array  $fields the keys we want to have in the returned array
     *
     * @return Document
     **/
    public function transform($object, array $fields)
    {
        $identifier = $this->propertyAccessor->getValue($object, $this->options['identifier']);

        return new Document($identifier);
    }
}

ObjectSerializerPersister utilizes transformToElasticaDocument($object) to call transform method above.

// Persister/ObjectSerializerPersister.php
public function transformToElasticaDocument($object)
    {
        $document = $this->transformer->transform($object, array());

        $data = call_user_func($this->serializer, $object);
        $document->setData($data);

        return $document;
    }

This is why PRE_TRANSFORM and POST_TRANSFORM are not triggered while using serializer. I can make a PR to solve the issue. Waiting for feedback.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions