diff --git a/src/Entities/Classification.php b/src/Entities/Classification.php index 17ff332..00b9c20 100644 --- a/src/Entities/Classification.php +++ b/src/Entities/Classification.php @@ -19,7 +19,7 @@ class Classification /** * @var \Doctrine\Common\Collections\Collection|Taxonomy[] * - * @ManyToMany(targetEntity="Taxonomy", inversedBy="classification") + * @ManyToMany(targetEntity="Taxonomy", inversedBy="classification",cascade={"persist"}) * @JoinTable( * name="classifications_taxonomy", * joinColumns={ diff --git a/src/Entities/ContentType.php b/src/Entities/ContentType.php index 7638b30..80f6042 100644 --- a/src/Entities/ContentType.php +++ b/src/Entities/ContentType.php @@ -57,16 +57,24 @@ class ContentType /** * @var Collection|Taxonomy[] * - * @OneToMany(targetEntity="Taxonomy", mappedBy="contentType") + * @OneToMany(targetEntity="Taxonomy", mappedBy="contentType", cascade={"persist"}) */ private $taxonomy; + /** + * @var \Doctrine\Common\Collections\Collection|File[] + * + * @@OneToMany(targetEntity="File", mappedBy="contentType") + */ + private $files; + /** * ContentType constructor. */ public function __construct() { $this->taxonomy = new ArrayCollection(); + $this->files = new ArrayCollection(); } /** @@ -101,6 +109,11 @@ public function getName() return $this->name; } + public function setName($name) + { + $this->name = $name; + } + /** * @return string */ @@ -109,6 +122,11 @@ public function getPath() return $this->path; } + public function setPath($path) + { + $this->path = $path; + } + /** * @return string */ @@ -117,6 +135,11 @@ public function getTemplate() return $this->template; } + public function setTemplate($template) + { + $this->template = $template; + } + /** * @return string */ @@ -125,6 +148,11 @@ public function getPermalink() return $this->permalink; } + public function setPermalink($permalink) + { + $this->permalink = $permalink; + } + /** * @return boolean */ @@ -133,6 +161,11 @@ public function getEnabled() return $this->enabled; } + public function setEnabled($enabled) + { + $this->enabled = $enabled; + } + /** * @return Environment */ @@ -181,4 +214,35 @@ public function removeTaxonomy(Taxonomy $taxonomy) $this->taxonomy->removeElement($taxonomy); } + + public function getFiles() + { + return $this->files; + } + + /** + * @param File $file + */ + public function addFile(File $file) + { + if ($this->files->contains($file)) { + return; + } + + $this->files->add($file); + //$file->setContentType($this); + } + + /** + * @param File $file + */ + public function removeFile(File $file) + { + if (!$this->files->contains($file)) { + return; + } + + $this->files->removeElement($file); + } + } \ No newline at end of file diff --git a/src/Entities/File.php b/src/Entities/File.php index 051beb5..9364843 100644 --- a/src/Entities/File.php +++ b/src/Entities/File.php @@ -65,10 +65,16 @@ class File */ private $environment; + /** + * @var ContentType + * @ManyToOne(targetEntity="ContentType") + */ + private $contentType; + /** * @var Collection|Classification[] * - * @ManyToMany(targetEntity="Classification", inversedBy="files") + * @ManyToMany(targetEntity="Classification", inversedBy="files", cascade={"persist"}) * @JoinTable( * name="classifications_files", * joinColumns={ @@ -116,6 +122,19 @@ public function setEnvironment(Environment $environment) $this->environment = $environment; } + public function getContentType() + { + return $this->contentType; + } + + /** + * @param ContentType $contentType + */ + public function setContentType(ContentType $contentType) + { + $this->contentType = $contentType; + } + public function addFrontMatter(FrontMatter $frontMatter) { if ($this->frontMatter->contains($frontMatter)) { diff --git a/src/Entities/Taxonomy.php b/src/Entities/Taxonomy.php index 3936fb9..459ab2a 100644 --- a/src/Entities/Taxonomy.php +++ b/src/Entities/Taxonomy.php @@ -30,14 +30,14 @@ class Taxonomy /** * @var ContentType * - * @ManyToOne(targetEntity="ContentType", inversedBy="taxonomy") + * @ManyToOne(targetEntity="ContentType", inversedBy="taxonomy", cascade={"persist"}) */ private $contentType; /** * @var Collection|Classification[] * - * @ManyToMany(targetEntity="Classification", mappedBy="taxonomy") + * @ManyToMany(targetEntity="Classification", mappedBy="taxonomy", cascade={"persist"}) */ private $classifications; diff --git a/src/Exporter.php b/src/Exporter.php index fffb766..d2600ce 100644 --- a/src/Exporter.php +++ b/src/Exporter.php @@ -10,9 +10,12 @@ use Tapestry\Modules\ContentTypes\ContentTypeFactory; use Tapestry\Tapestry; use TapestryCloud\Database\Entities\Environment; -use TapestryCloud\Database\Synchronizes\ContentTypes; -use TapestryCloud\Database\Synchronizes\Files; +use TapestryCloud\Database\Synchronizes\ContentTypeSync; +use TapestryCloud\Database\Synchronizes\FileSync; use TapestryCloud\Database\Hydrators\File as FileHydrator; +use TapestryCloud\Database\Hydrators\ContentType as ContentTypeHydrator; +use TapestryCloud\Database\Hydrators\Taxonomy as TaxonomyHydrator; +use TapestryCloud\Database\Synchronizes\TaxonomySync; class Exporter { @@ -58,10 +61,30 @@ public function export(Project $project) $this->entityManager->flush(); } - $fileSync = new Files($this->entityManager, new FileHydrator($this->entityManager)); + // 1. Sync Content Types Base + $contentTypeSync = new ContentTypeSync( + $this->entityManager, + new ContentTypeHydrator($this->entityManager), + new TaxonomyHydrator($this->entityManager) + ); + $contentTypeSync->sync($contentTypes, $environment); + + // 2. Sync Files + $fileSync = new FileSync( + $this->entityManager, + new FileHydrator($this->entityManager) + ); $fileSync->sync($files, $environment); - $contentTypeSync = new ContentTypes($this->entityManager); - $contentTypeSync->sync($contentTypes, $environment); + // 3. Sync Taxonomy foreach Content Type + // 4. Sync Classifications foreach Taxonomy - attaching Files + + $taxonomySync = new TaxonomySync( + $this->entityManager, + new ContentTypeHydrator($this->entityManager), + new TaxonomyHydrator($this->entityManager) + ); + $taxonomySync->sync($contentTypes, $environment); + } } \ No newline at end of file diff --git a/src/Hydrators/ContentType.php b/src/Hydrators/ContentType.php new file mode 100644 index 0000000..82fa00c --- /dev/null +++ b/src/Hydrators/ContentType.php @@ -0,0 +1,29 @@ +setName($contentType->getName()); + $model->setPath($contentType->getPath()); + $model->setTemplate($contentType->getTemplate()); + $model->setPermalink($contentType->getPermalink()); + $model->setEnabled($contentType->isEnabled()); + + if (!is_null($environment)) { + $model->setEnvironment($environment); + } + } +} \ No newline at end of file diff --git a/src/Hydrators/File.php b/src/Hydrators/File.php index 387e2f5..24d2151 100644 --- a/src/Hydrators/File.php +++ b/src/Hydrators/File.php @@ -10,15 +10,15 @@ class File extends Hydrator { - /** * File Hydration. * * @param Model $model * @param \Tapestry\Entities\File $file - * @param Environment|null $environment + * @param \TapestryCloud\Database\Entities\ContentType $contentType + * @param null|Environment $environment */ - public function hydrate(Model $model, \Tapestry\Entities\File $file, Environment $environment = null) + public function hydrate(Model $model, \Tapestry\Entities\File $file, \TapestryCloud\Database\Entities\ContentType $contentType = null, Environment $environment = null) { $model->setUid($file->getUid()); $model->setLastModified($file->getLastModified()); @@ -40,6 +40,10 @@ public function hydrate(Model $model, \Tapestry\Entities\File $file, Environment } } + if (!is_null($contentType)) { + $model->setContentType($contentType); + } + if (!is_null($environment)) { $model->setEnvironment($environment); } diff --git a/src/Hydrators/Taxonomy.php b/src/Hydrators/Taxonomy.php new file mode 100644 index 0000000..5b93246 --- /dev/null +++ b/src/Hydrators/Taxonomy.php @@ -0,0 +1,19 @@ +setName($taxonomy->getName()); + } +} \ No newline at end of file diff --git a/src/Synchronizes/ContentTypeSync.php b/src/Synchronizes/ContentTypeSync.php new file mode 100644 index 0000000..e44b473 --- /dev/null +++ b/src/Synchronizes/ContentTypeSync.php @@ -0,0 +1,60 @@ +em = $em; + $this->contentTypeHydrator = $contentTypeHydrator; + $this->taxonomyHydrator = $taxonomyHydrator; + } + + public function sync(ContentTypeFactory $contentTypeFactory, Environment $environment) + { + foreach ($contentTypeFactory->all() as $contentType) { + if (!$record = $this->em->getRepository(ContentType::class)->findOneBy(['name' => $contentType->getName(), 'environment' => $environment->getId()])) { + $record = new ContentType(); + } + + $this->contentTypeHydrator->hydrate($record, $contentType, $environment); + $this->em->persist($record); + } + $this->em->flush(); + } +} \ No newline at end of file diff --git a/src/Synchronizes/Files.php b/src/Synchronizes/FileSync.php similarity index 70% rename from src/Synchronizes/Files.php rename to src/Synchronizes/FileSync.php index 7665aa3..1f20abe 100644 --- a/src/Synchronizes/Files.php +++ b/src/Synchronizes/FileSync.php @@ -5,11 +5,12 @@ use Doctrine\ORM\EntityManagerInterface; use Tapestry\Entities\Collections\FlatCollection; use Tapestry\Entities\File as TapestryFile; +use TapestryCloud\Database\Entities\ContentType; use TapestryCloud\Database\Entities\Environment; use TapestryCloud\Database\Entities\File; use TapestryCloud\Database\Hydrators\File as FileHydrator; -class Files +class FileSync { /** * @var EntityManagerInterface @@ -34,15 +35,18 @@ public function __construct(EntityManagerInterface $em, FileHydrator $fileHydrat public function sync(FlatCollection $files, Environment $environment) { - /** @var TapestryFile $file */ foreach ($files as $file) { + $contentTypeName = $file->getData('contentType', 'default'); + if (!$contentType = $this->em->getRepository(ContentType::class)->findOneBy(['name' => $contentTypeName, 'environment' => $environment->getId()])) { + throw new \Exception('The content type ['. $contentTypeName .'] has not been seeded.'); + } if (!$record = $this->em->getRepository(File::class)->findOneBy(['uid' => $file->getuid(), 'environment' => $environment->getId()])) { $record = new File(); } - $this->fileHydrator->hydrate($record, $file, $environment); + $this->fileHydrator->hydrate($record, $file, $contentType, $environment); $this->em->persist($record); } diff --git a/src/Synchronizes/ContentTypes.php b/src/Synchronizes/TaxonomySync.php similarity index 62% rename from src/Synchronizes/ContentTypes.php rename to src/Synchronizes/TaxonomySync.php index 8b35fec..e2f4371 100644 --- a/src/Synchronizes/ContentTypes.php +++ b/src/Synchronizes/TaxonomySync.php @@ -10,39 +10,53 @@ use TapestryCloud\Database\Entities\Environment; use TapestryCloud\Database\Entities\File; use TapestryCloud\Database\Entities\Taxonomy; +use TapestryCloud\Database\Hydrators\ContentType as ContentTypeHydrator; +use TapestryCloud\Database\Hydrators\Taxonomy as TaxonomyHydrator; -class ContentTypes +class TaxonomySync { /** * @var EntityManagerInterface */ private $em; + /** + * @var ContentTypeHydrator + */ + private $contentTypeHydrator; + + /** + * @var TaxonomyHydrator + */ + private $taxonomyHydrator; + /** * ContentTypes constructor. * @param EntityManagerInterface $em + * @param ContentTypeHydrator $contentTypeHydrator + * @param TaxonomyHydrator $taxonomyHydrator */ - public function __construct(EntityManagerInterface $em) - { + public function __construct( + EntityManagerInterface $em, + ContentTypeHydrator $contentTypeHydrator, + TaxonomyHydrator $taxonomyHydrator + ){ $this->em = $em; + $this->contentTypeHydrator = $contentTypeHydrator; + $this->taxonomyHydrator = $taxonomyHydrator; } public function sync(ContentTypeFactory $contentTypeFactory, Environment $environment) { foreach ($contentTypeFactory->all() as $contentType) { + /** @var ContentType $record */ if (!$record = $this->em->getRepository(ContentType::class)->findOneBy(['name' => $contentType->getName(), 'environment' => $environment->getId()])) { - // INSERT - $record = new ContentType(); - $record->hydrate($contentType, $environment); - $this->em->persist($record); - $this->em->flush(); - - $this->syncTaxonomyToContentType($record, $contentType->getTaxonomies(), $environment); - continue; + throw new \Exception('The content type ['. $contentType->getName() .'] has not been seeded.'); } - // UPDATE + $this->syncTaxonomyToContentType($record, $contentType->getTaxonomies(), $environment); } + $this->em->flush(); } /** @@ -54,37 +68,33 @@ private function syncTaxonomyToContentType(ContentType $contentType, array $taxo { /** @var TapestryTaxonomy $taxonomy */ foreach ($taxonomies as $taxonomy) { - if (!$record = $this->em->getRepository(Taxonomy::class)->findOneBy(['name' => $taxonomy->getName()])) { + if (!$record = $this->em->getRepository(Taxonomy::class)->findOneBy(['name' => $taxonomy->getName(), 'contentType' => $contentType])) { $record = new Taxonomy(); - $record->hydrate($taxonomy); - $this->em->persist($record); - $this->em->flush(); - - $contentType->addTaxonomy($record); - $this->em->persist($contentType); - $this->em->flush(); } + $this->taxonomyHydrator->hydrate($record, $taxonomy); + $contentType->addTaxonomy($record); + + //$this->em->persist($contentType); + foreach ($taxonomy->getFileList() as $classification => $files) { if (!$classificationRecord = $this->em->getRepository(Classification::class)->findOneBy(['name' => $classification])) { $classificationRecord = new Classification(); $classificationRecord->setName($classification); - $this->em->persist($classificationRecord); + //$this->em->persist($classificationRecord); } $classificationRecord->addTaxonomy($record); - $this->em->flush(); foreach (array_keys($files) as $filename) { /** @var File $file */ - if ($file = $this->em->getRepository(File::class)->findOneBy(['uid' => $filename, 'environment' => $environment->getId()])) { + if ($file = $this->em->getRepository(File::class)->findOneBy(['uid' => $filename, 'environment' => $environment])) { $file->addClassification($classificationRecord); - $this->em->persist($file); + //$this->em->persist($file); } } - - $this->em->flush(); } } + $this->em->flush(); } } \ No newline at end of file diff --git a/tests/PluginTest.php b/tests/PluginTest.php index 7f00f90..734bc23 100644 --- a/tests/PluginTest.php +++ b/tests/PluginTest.php @@ -15,6 +15,7 @@ use Tapestry\Tapestry; use TapestryCloud\Database\Entities\Classification; use TapestryCloud\Database\Entities\ContentType; +use TapestryCloud\Database\Entities\Environment; use TapestryCloud\Database\Entities\File; use TapestryCloud\Database\Entities\Taxonomy; @@ -62,15 +63,14 @@ public static function tearDownAfterClass() $tool->dropDatabase(); } - public static function runTapestry($siteDir = __DIR__ . DIRECTORY_SEPARATOR . 'mock_project') + public static function runTapestry($env = 'testing', $siteDir = __DIR__ . DIRECTORY_SEPARATOR . 'mock_project') { $definitions = new DefaultInputDefinition(); $tapestry = new Tapestry(new ArrayInput([ '--site-dir' => $siteDir, - '--env' => 'testing' + '--env' => $env ], $definitions)); - $bufferedOutput = new BufferedOutput(); $tapestry->setOutput($bufferedOutput); @@ -93,7 +93,7 @@ public function testNoChangeRunThrough() { $loops = 0; while ($loops < 2) { - $output = self::runTapestry(); + $output = self::runTapestry('testing'); $this->assertContains('[$] Syncing with database.', $output->fetch()); $contentTypes = self::$em->getRepository(ContentType::class)->findAll(); @@ -125,15 +125,25 @@ public function testNoChangeRunThrough() $this->assertCount(4, $classifications); $loops++; } - - $n = 1; } /** * This tests */ - public function testModifiedRunThrough() + public function testDifferentEnvironmentRunThrough() { - // @todo + $output = self::runTapestry('testing-1'); + $this->assertContains('[$] Syncing with database.', $output->fetch()); + + $environments = self::$em->getRepository(Environment::class)->findAll(); + $this->assertCount(2, $environments); + + $contentTypes = self::$em->getRepository(ContentType::class)->findAll(); + $this->assertCount(4, $contentTypes); + + /** @var Environment $environment */ + $environment = self::$em->getRepository(Environment::class)->findOneBy(['name' => 'testing-1']); + $this->assertNotNull($environment); + $this->assertSame('testing-1', $environment->getName()); } } \ No newline at end of file