From 5a7809e419764b44b56ae4a0ae51f3e21eecfb2d Mon Sep 17 00:00:00 2001 From: Nicolas Bastien Date: Thu, 20 Dec 2018 17:54:34 +0100 Subject: [PATCH] #16 : DoctrineEntityExtractor handle many to many relations --- src/Extractor/DoctrineEntityExtractor.php | 12 +++++++- tests/Entity/Task.php | 12 ++++++++ tests/Extractor/CsvEntityExtractorTest.php | 4 +-- .../Extractor/DoctrineEntityExtractorTest.php | 28 +++++++++++++++++-- 4 files changed, 51 insertions(+), 5 deletions(-) diff --git a/src/Extractor/DoctrineEntityExtractor.php b/src/Extractor/DoctrineEntityExtractor.php index 16ddedd..8fb02c2 100644 --- a/src/Extractor/DoctrineEntityExtractor.php +++ b/src/Extractor/DoctrineEntityExtractor.php @@ -107,6 +107,16 @@ public function extract() throw new EntityTypeNotHandledException(get_class($value)); } $entityData[$property] = '@' . $value->getImportId(); + } elseif ($value instanceof \Traversable) { + $entityData[$property] = []; + foreach ($value as $k => $v) { + if ($this->isEntityRelation($v)) { + if (!$v instanceof ImportableInterface) { + throw new EntityTypeNotHandledException(get_class($v)); + } + $entityData[$property][$k] = '@' . $v->getImportId(); + } + } } else { $entityData[$property] = $value; } @@ -125,6 +135,6 @@ public function extract() */ 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/Entity/Task.php b/tests/Entity/Task.php index 05d4d98..b4f85bb 100644 --- a/tests/Entity/Task.php +++ b/tests/Entity/Task.php @@ -65,4 +65,16 @@ public function setCode($code) { $this->code = $code; } + + /** + * @return string + */ + public function getImportId() + { + if (is_null($this->importId)) { + return $this->getCode(); + } + + return $this->importId; + } } diff --git a/tests/Extractor/CsvEntityExtractorTest.php b/tests/Extractor/CsvEntityExtractorTest.php index 50f2f7e..f583b14 100644 --- a/tests/Extractor/CsvEntityExtractorTest.php +++ b/tests/Extractor/CsvEntityExtractorTest.php @@ -22,10 +22,10 @@ public function testExtractEntities() $extractor = new CsvEntityExtractor(); $extractor->setFolderToExtract(__DIR__ . '/../fixtures/entity-csv'); $extractor - ->addEntityToProcess('project', 'Smart\EtlBundle\Tests\Model\Project', function ($e) { + ->addEntityToProcess('project', Project::class, function ($e) { return $e->getCode(); }) - ->addEntityToProcess('task', 'Smart\EtlBundle\Tests\Model\Task', function ($e) { + ->addEntityToProcess('task', Task::class, function ($e) { return 'task' . $e->getProject()->getCode() . '-' . substr(md5($e->getName()), 0, 5); }) ; diff --git a/tests/Extractor/DoctrineEntityExtractorTest.php b/tests/Extractor/DoctrineEntityExtractorTest.php index 7d66987..4efb10f 100644 --- a/tests/Extractor/DoctrineEntityExtractorTest.php +++ b/tests/Extractor/DoctrineEntityExtractorTest.php @@ -6,6 +6,8 @@ use Doctrine\ORM\Tools\SchemaTool; use Liip\FunctionalTestBundle\Test\WebTestCase; use Smart\EtlBundle\Extractor\DoctrineEntityExtractor; +use Smart\EtlBundle\Tests\Entity\Project; +use Smart\EtlBundle\Tests\Entity\Task; /** * vendor/bin/phpunit tests/Extractor/DoctrineEntityExtractorTest.php @@ -19,7 +21,7 @@ public function testExtractEntities() //Initialise database /** @var EntityManager $em */ $em = $this->getContainer()->get('doctrine')->getManager('default'); - $metadatas = $em->getMetadataFactory()->getMetadataFor('Smart\EtlBundle\Tests\Entity\Project'); + $metadatas = $em->getMetadataFactory()->getMetadataFor(Project::class); $schemaTool = new SchemaTool($em); $schemaTool->dropDatabase(); @@ -28,11 +30,12 @@ public function testExtractEntities() $this->loadFixtureFiles([ __DIR__ . '/../fixtures/doctrine-loader/organisation.yml', __DIR__ . '/../fixtures/doctrine-loader/project.yml', + __DIR__ . '/../fixtures/doctrine-loader/tag.yml', __DIR__ . '/../fixtures/doctrine-loader/task.yml', ]); $extractor = new DoctrineEntityExtractor($em); - $extractor->setEntityToExtract('Smart\EtlBundle\Tests\Entity\Project', ['organisation', 'name']); + $extractor->setEntityToExtract(Project::class, ['organisation', 'name']); $qbExtractor = $extractor->getQueryBuilder(); //We agree that you should not make where like query if you want reasonable performance $qbExtractor->andWhere( @@ -46,5 +49,26 @@ public function testExtractEntities() $this->assertEquals([ 'etl-bundle' => ['organisation' => '@smartbooster', 'name' => 'ETL Bundle'] ], $entities); + + + $extractor->setEntityToExtract(Task::class, ['code', 'project', 'name', 'tags']); + $entities = $extractor->extract(); + + $this->assertEquals(2, count($entities)); + + $this->assertEquals([ + 'etl-bundle-setup' => [ + 'code' => 'etl-bundle-setup', + 'project' => '@etl-bundle', + 'name' => 'Bundle setup', + 'tags' => ['@doing', '@easy'] + ], + 'etl-bundle-loadyml' => [ + 'code' => 'etl-bundle-loadyml', + 'project' => '@etl-bundle', + 'name' => 'Load yml entity file into database', + 'tags' => ['@todo', '@hard'] + ] + ], $entities); } }