From eb962843966bcedec0184ee6bc6d0b8870c828b2 Mon Sep 17 00:00:00 2001 From: Nicolas Bastien Date: Fri, 21 Dec 2018 17:49:30 +0100 Subject: [PATCH] #16 : DoctrineEntityLoader handle manytomany relations --- src/Loader/DoctrineInsertUpdateLoader.php | 21 +++++++++++- .../Loader/DoctrineInsertUpdateLoaderTest.php | 33 +++++++++++++++++-- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/src/Loader/DoctrineInsertUpdateLoader.php b/src/Loader/DoctrineInsertUpdateLoader.php index 9966ac5..c50fa39 100644 --- a/src/Loader/DoctrineInsertUpdateLoader.php +++ b/src/Loader/DoctrineInsertUpdateLoader.php @@ -117,6 +117,25 @@ protected function processObject($object) $property, $this->references[$relationIdentifier] ); + } elseif ($propertyValue instanceof \Traversable) { + foreach ($propertyValue as $k => $v) { + if ($this->isEntityRelation($v)) { + if (!isset($this->entitiesToProcess[get_class($v)])) { + throw new EntityTypeNotHandledException(get_class($v)); + } + $relationIdentifier = $this->entitiesToProcess[get_class($v)]['callback']($v); + if (!isset($this->references[$relationIdentifier])) { + //new relation should be processed before + $this->processObject($v); + } + $propertyValue[$k] = $this->references[$relationIdentifier]; + } + } + $this->accessor->setValue( + $object, + $property, + $propertyValue + ); } } @@ -153,6 +172,6 @@ protected function processObject($object) */ protected function isEntityRelation($propertyValue) { - return (is_object($propertyValue) && !($propertyValue instanceof \DateTime)); + return (is_object($propertyValue) && !($propertyValue instanceof \DateTime) && !($propertyValue instanceof \Traversable)); } } diff --git a/tests/Loader/DoctrineInsertUpdateLoaderTest.php b/tests/Loader/DoctrineInsertUpdateLoaderTest.php index 6cd90f8..59c5b91 100644 --- a/tests/Loader/DoctrineInsertUpdateLoaderTest.php +++ b/tests/Loader/DoctrineInsertUpdateLoaderTest.php @@ -75,7 +75,8 @@ function ($e) { [ 'project', 'code', - 'name' + 'name', + 'tags' ] ); $loader->addEntityToProcess( @@ -123,12 +124,21 @@ function ($e) { //======================= // Test relations //======================= + $tagTodo = new Tag('Todo', 'todo'); + $tagDoing = new Tag('Doing', 'doing'); + $tagDone = new Tag('Done', 'done'); + $tagEasy = new Tag('Easy', 'easy'); + $tagHard = new Tag('Hard', 'hard'); + $this->assertEquals(2, $em->getRepository(Task::class)->count([])); $taskSetUp = new Task($projectEtl, 'Bundle setup updated'); $taskSetUp->setCode('etl-bundle-setup'); + $taskSetUp->addTag($tagTodo); $newTask = new Task($projectEtl, 'New Task'); $newTask->setCode('etl-bundle-new-task'); + $newTask->addTag($tagDoing); + $newTask->addTag($tagEasy); $loader->load([$taskSetUp, $newTask]); @@ -137,6 +147,7 @@ function ($e) { 'code' => 'etl-bundle-new-task' ]); $this->assertEquals('New Task', $newTaskLoaded->getName()); + $this->assertEquals(2, $newTaskLoaded->getTags()->count()); $newTask->setName('New Task updated'); $loader->load([$taskSetUp, $newTask]); @@ -147,6 +158,24 @@ function ($e) { $taskSetUpLoaded = $em->getRepository(Task::class)->findOneBy([ 'code' => 'etl-bundle-setup' ]); - $this->assertEquals(2, count($taskSetUpLoaded->getTags())); + $this->assertEquals(1, count($taskSetUpLoaded->getTags())); + //Test manytomany remove and replace + $tagTodoLoaded = $em->getRepository(Tag::class)->findOneBy(['importId' => 'todo']); + $taskSetUp->removeTag($tagTodoLoaded); + $taskSetUp->addTag($tagDone); + + $loader->load([$taskSetUp]); + $taskSetUpLoaded = $em->getRepository(Task::class)->findOneBy([ + 'code' => 'etl-bundle-setup' + ]); + $this->assertEquals(1, count($taskSetUpLoaded->getTags())); + //Test manytomany remove + $tagDoneLoaded = $em->getRepository(Tag::class)->findOneBy(['importId' => 'done']); + $taskSetUp->removeTag($tagDoneLoaded); + $loader->load([$taskSetUp]); + $taskSetUpLoaded = $em->getRepository(Task::class)->findOneBy([ + 'code' => 'etl-bundle-setup' + ]); + $this->assertEquals(0, count($taskSetUpLoaded->getTags())); } }