Skip to content

Commit

Permalink
Working with deleted entities
Browse files Browse the repository at this point in the history
  • Loading branch information
Benjamin Vison committed May 8, 2018
1 parent 36c73b5 commit cf38cab
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 128 deletions.
13 changes: 13 additions & 0 deletions Annotations/SyncEntity.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace NTI\SyncBundle\Annotations;
use Doctrine\Common\Annotations\Annotation\Required;

/**
* Class SyncParent
* @package NTI\SyncBundle\Annotations
* @Annotation
*/
class SyncEntity {

}
2 changes: 1 addition & 1 deletion Entity/SyncFailedItemState.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class SyncFailedItemState {
/**
* @var string
*
* @ORM\Column(name="errors", columnDefinition="TEXT", length=65535, nullable=true)
* @ORM\Column(name="errors", type="text", nullable=true)
*/
private $errors;

Expand Down
2 changes: 1 addition & 1 deletion Entity/SyncMapping.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class SyncMapping
/**
* @var string
*
* @ORM\Column(name="sync_service", type="string", length=255, nullable=false)
* @ORM\Column(name="sync_service", type="string", length=255, nullable=true)
*/
private $syncService;

Expand Down
84 changes: 0 additions & 84 deletions EventListener/DoctrineEventSubscriber.php

This file was deleted.

125 changes: 125 additions & 0 deletions EventSubscriber/DoctrineEventSubscriber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<?php

namespace NTI\SyncBundle\EventSubscriber;

use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\EventSubscriber;
use Doctrine\Common\Util\ClassUtils;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\OnFlushEventArgs;
use Doctrine\ORM\PersistentCollection;
use NTI\SyncBundle\Annotations\SyncEntity;
use NTI\SyncBundle\Annotations\SyncParent;
use NTI\SyncBundle\Entity\SyncMapping;
use NTI\SyncBundle\Entity\SyncState;
use Symfony\Component\DependencyInjection\ContainerInterface;

class DoctrineEventSubscriber implements EventSubscriber
{
private $container;
private $syncService;

public function __construct(ContainerInterface $container)
{
$this->container = $container;
$this->syncService = $this->container->get('nti.sync');
}

public function getSubscribedEvents()
{
return array(
'onFlush',
);
}

public function onFlush(OnFlushEventArgs $args)
{

$em = $args->getEntityManager();
$uow = $em->getUnitOfWork();

foreach ($uow->getScheduledEntityUpdates() as $entity) {
$this->processEntity($em, $entity);
}

foreach ($uow->getScheduledEntityInsertions() as $entity) {
$this->processEntity($em, $entity);
}

foreach ($uow->getScheduledEntityDeletions() as $entity) {
$this->processEntity($em, $entity);
$this->container->get('nti.sync')->addToDeleteSyncState(ClassUtils::getClass($entity), $entity->getId());
}

/** @var PersistentCollection $collectionUpdate */
foreach ($uow->getScheduledCollectionUpdates() as $collectionUpdate) {
foreach($collectionUpdate as $entity) {
$this->processEntity($em, $entity);
}
}

/** @var PersistentCollection $collectionDeletion */
foreach($uow->getScheduledCollectionDeletions() as $collectionDeletion) {
foreach($collectionDeletion as $entity) {
$this->processEntity($em, $entity);
$this->container->get('nti.sync')->addToDeleteSyncState(ClassUtils::getClass($entity), $entity->getId());
}
}

}

private function processEntity(EntityManagerInterface $em, $entity)
{

$reflection = new \ReflectionClass(ClassUtils::getClass($entity));
$annotationReader = new AnnotationReader();
$syncEntityAnnotation = $annotationReader->getClassAnnotation($reflection, SyncEntity::class);
// Check if the entity should be synchronized
if (!$syncEntityAnnotation) {
return;
}

$uow = $em->getUnitOfWork();
$timestamp = time();

// Update the mapping's sync state if exists
$mapping = $em->getRepository(SyncMapping::class)->findOneBy(array("class" => get_class($entity)));
if($mapping) {
$syncState = $em->getRepository(SyncState::class)->findOneBy(array("mapping" => $mapping));
if(!$syncState) {
$syncState = new SyncState();
$syncState->setMapping($mapping);
$em->persist($syncState);
}
$syncState->setTimestamp($timestamp);
$uow->recomputeSingleEntityChangeSet($em->getClassMetadata(SyncState::class), $syncState);
}

// Check if this class itself has a lastTimestamp
if(method_exists($entity, 'setLastTimestamp')) {
$entity->setLastTimestamp($timestamp);
$uow->recomputeSingleEntityChangeSet($em->getClassMetadata(get_class($entity)), $entity);
}

// Notify relationships
/** @var \ReflectionProperty $property */
foreach ($reflection->getProperties() as $property) {

/** @var SyncParent $annotation */
if (null !== ($annotation = $annotationReader->getPropertyAnnotation($property, SyncParent::class))) {
$getter = $annotation->getter;
$parent = $entity->$getter();
dump($parent);
die;
// Using ClassUtils as $parent is actually a Proxy of the class
$reflrectionParent = new \ReflectionClass(ClassUtils::getClass($parent));
$syncParentAnnotation = $annotationReader->getClassAnnotation($reflrectionParent, SyncEntity::class);
if(!$syncParentAnnotation) {
continue;
}
$this->processEntity($em, $parent);
}
}
}
}
6 changes: 0 additions & 6 deletions Interfaces/SyncEntityInterface.php

This file was deleted.

2 changes: 1 addition & 1 deletion Resources/config/services.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
services:
nti.sync.doctrine.listener:
class: NTI\SyncBundle\EventListener\DoctrineEventSubscriber
class: NTI\SyncBundle\EventSubscriber\DoctrineEventSubscriber
arguments: ["@service_container"]
tags:
- { name: doctrine.event_subscriber, connection: default }
Expand Down
38 changes: 3 additions & 35 deletions Service/SyncService.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use NTI\SyncBundle\Entity\SyncDeleteState;
use NTI\SyncBundle\Entity\SyncFailedItemState;
use NTI\SyncBundle\Entity\SyncMapping;
use NTI\SyncBundle\Entity\SyncNewItemState;
use NTI\SyncBundle\Entity\SyncState;
Expand Down Expand Up @@ -62,10 +63,7 @@ public function getFromMappings($mappings) {

$deletes = $this->em->getRepository(SyncDeleteState::class)->findFromTimestamp($mappingName, $timestamp);
$newItems = $this->em->getRepository(SyncNewItemState::class)->findFromTimestampAndMapping($mappingName, $timestamp);
/**
* Failed Items Synchronization
*/
$failedItems = $this->em->getRepository('NTISyncBundle:SyncFailedItemState')->findFromTimestampAndMapping($mappingName, $timestamp);
$failedItems = $this->em->getRepository(SyncFailedItemState::class)->findFromTimestampAndMapping($mappingName, $timestamp);

/** @var SyncRepositoryInterface $repository */
$repository = $this->em->getRepository($syncMapping->getClass());
Expand All @@ -88,30 +86,6 @@ public function getFromMappings($mappings) {
return $changes;
}

public function updateSyncState(EntityManagerInterface $em, $class, $timestamp) {

$mapping = $em->getRepository(SyncMapping::class)->findOneBy(array("class" => $class));
if(!$mapping) {
return;
}

$syncState = $em->getRepository(SyncState::class)->findOneBy(array("mapping" => $mapping));

$uow = $em->getUnitOfWork();

if(!$syncState) {
$syncState = new SyncState();
$syncState->setMapping($mapping);
$syncState->setTimestamp($timestamp);
$em->persist($syncState);
$uow->computeChangeSet($em->getClassMetadata(SyncState::class), $syncState);
} else {
$syncState->setTimestamp($timestamp);
$uow->recomputeSingleEntityChangeSet($em->getClassMetadata(SyncState::class), $syncState);
}

}

/**
* Create a new SyncDeleteState for the given class/id
*
Expand All @@ -122,6 +96,7 @@ public function addToDeleteSyncState($class, $id) {

$this->em = $this->container->get('doctrine')->getManager();

/** @var SyncMapping $mapping */
$mapping = $this->em->getRepository(SyncMapping::class)->findOneBy(array("class" => $class));
if(!$mapping) {
return;
Expand All @@ -133,12 +108,5 @@ public function addToDeleteSyncState($class, $id) {
$deleteEntry->setTimestamp(time());

$this->em->persist($deleteEntry);

try {
$this->em->flush();
} catch (\Exception $ex) {
error_log("Unable to register deletion of object: " . $class . " with ID " . $id);
error_log($ex->getMessage());
}
}
}

0 comments on commit cf38cab

Please sign in to comment.