Skip to content
This repository has been archived by the owner on Dec 1, 2021. It is now read-only.

Property array does not work, preflush event is ignored for relationship entity #151

Open
esynaps opened this issue Aug 28, 2017 · 0 comments

Comments

@esynaps
Copy link

esynaps commented Aug 28, 2017

Hi,
I try to persist and flush an entity with a relationship using a relationshipEntity.
This relationshipEntity contains one property of type "array" and this causes a ContextErrorException.

Notice: Array to string conversion in vendor\graphaware\neo4j-php-ogm\src\UnitOfWork.php (line 859)

if (!array_key_exists($oid, $this->reOriginalData)) {              
}                
$originalValues = $this->reOriginalData[$oid];                 
if (count(array_diff($originalValues, $newValues)) > 0) {                     
    $this->relEntitesScheduledForUpdate[$oid] = $e;
}

I tried to use PRE_FLUSH and ON_FLUSH events to serialize array before the flush : it works for nodes but not for relationshipEntity because $originalValues are not updated by the event.

VarDumper::dump($originalValues); gives

array:8 [▼
  "testArray" => array:2 [▼
    0 => "a"
    1 => "b"
  ]
]

whereas the result of the event is :

      #testArray: "a:2:{i:0;s:1:"a";i:1;s:1:"b";}"

Here is my listener :

class ArrayConvertorListener
{
    /**
     * @var EntityManager
     */
    private $entityManager;
    private $eventManager;

    public function __construct(EntityManager $entityManager)
    {
        $this->entityManager = $entityManager;
        $this->eventManager = $entityManager->getEventManager();
        $this->eventManager->addEventListener(Events::PRE_FLUSH, $this);
        $this->eventManager->addEventListener(Events::ON_FLUSH, $this);
    }

    public function onKernelRequest(GetResponseEvent $event)
    {
        return $event;
    }

    public function preFlush(PreFlushEventArgs $eventArgs) {
        $uow = $eventArgs->getEntityManager()->getUnitOfWork();
        $relationships = array_merge($uow->getRelEntitiesScheduledForCreate(), $uow->getRelEntitesScheduledForUpdate());
        foreach ($relationships as $item) {
            $relationship = $item[0];
            foreach ($eventArgs->getEntityManager()->getClassMetadata(get_class($relationship))->getPropertiesMetadata() as $entityPropertyMetadata) {
                if ($entityPropertyMetadata->getPropertyAnnotationMetadata()->getType() == 'array' &&
                    is_array($entityPropertyMetadata->getValue($relationship))
                ) {
                    $entityPropertyMetadata->setValue($relationship, serialize($entityPropertyMetadata->getValue($relationship)));
                }
            }
        }
        VarDumper::dump($eventArgs->getEntityManager()->getUnitOfWork()->getRelEntitiesScheduledForCreate());die;
        return $eventArgs;
    }

    /**
     * Convertit les propriétés de type array en type string après les avoir sérialisées
     * Assure la compatibilité entre l'API V1 et la V2 car l'API V1 ne supporte pas le type array dans neo4j
     * @param OnFlushEventArgs $eventArgs
     */
    public function onFlush(OnFlushEventArgs $eventArgs)
    {
        $nodes = array_merge($eventArgs->getEntityManager()->getUnitOfWork()->getNodesScheduledForCreate(),
            $eventArgs->getEntityManager()->getUnitOfWork()->getNodesScheduledForUpdate());
        foreach ($nodes as $node) {
            foreach ($eventArgs->getEntityManager()->getClassMetadata(get_class($node))->getPropertiesMetadata() as $entityPropertyMetadata) {
                if ($entityPropertyMetadata->getPropertyAnnotationMetadata()->getType() == 'array' &&
                    is_array($entityPropertyMetadata->getValue($node))
                ) {
                    $entityPropertyMetadata->setValue($node, serialize($entityPropertyMetadata->getValue($node)));
                }
            }
        }
    }
}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant