Doctrine deserialize entity and merge recursively

When you serialize doctrine entity and later unserialize you all lazy loaded associations are gone. Initializers won't fetch the data from database as well.
One approach could be eagerly fetch all the associations you will need after deserialization.
But there is another and more easy and memory effective way.
You can do merge() on your entity to "restore" it.
But you need to merge each entity you plan to use that could be quite annoying and sometimes impossible.
So save your efforts and use recursive merging function above:

<?php

use Doctrine\ORM\EntityManager;

class RecursiveMerge
{
    /**
     * @var EntityManager
     */
    protected $em;
    public function __construct(EntityManager $entityManager)
    {
        $this->em = $entityManager;
    }

    /**
     * Merge entity recursively
     *
     * @param object $entity
     * @param int $depth recursion depth to avoid cyclic references issue
     *
     * @return object
     */
    public function merge($entity, $depth = 3)
    {
        $merge = function ($entity, $currentDepth = 1) use ($depth, &$merge) {
            if ($currentDepth > $depth) {
                return $entity;
            }
            $class = $this->em->getClassMetadata(get_class($entity));
            foreach ($class->associationMappings as $property => $field) {
                if (
                    method_exists($entity, "get$property") &&
                    method_exists($entity, "set$property") &&
                    $propertyObject = $entity->{"get$property"}()
                ) {
                    if ($propertyObject instanceof \ArrayAccess) {
                        foreach ($propertyObject as $fieldEntity) {
                            $entity->{"set$property"}($merge($fieldEntity, $currentDepth + 1));
                        }
                    } else {
                        $entity->{"set$property"}($merge($propertyObject, $currentDepth + 1));
                    }
                }
            }
            return $this->em->merge($entity);
        };
        return $merge($entity);
    }

}

Comments

Popular posts from this blog

Memory efficient array permutation in PHP 5.5 using generators

How to dump http request headers with PHP under CGI/FastCGI SAPI

Jqgrid show totals in the footer plugin