From 9379b4945aa17a7dd3655aadbbaecda64d9473e7 Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Mon, 6 Oct 2014 21:12:43 +0200 Subject: [PATCH] Moved tag synchronization to TagService --- src/Dao/PostDao.php | 13 ++---- src/Dao/TagDao.php | 25 ----------- src/Services/PostService.php | 4 ++ src/Services/TagService.php | 60 +++++++++++++++++++++++++ tests/Dao/PostDaoTest.php | 8 +++- tests/Dao/TagDaoTest.php | 18 ++++---- tests/Services/PostServiceTest.php | 6 ++- tests/Services/TagServiceTest.php | 71 ++++++++++++++++++++++++++++++ 8 files changed, 158 insertions(+), 47 deletions(-) create mode 100644 src/Services/TagService.php create mode 100644 tests/Services/TagServiceTest.php diff --git a/src/Dao/PostDao.php b/src/Dao/PostDao.php index 61383be4..efce8518 100644 --- a/src/Dao/PostDao.php +++ b/src/Dao/PostDao.php @@ -203,21 +203,14 @@ class PostDao extends AbstractDao implements ICrudDao private function syncTags(\Szurubooru\Entities\Post $post) { - $tagNames = array_filter(array_unique(array_map( - function ($tag) - { - return $tag->getName(); - }, - $post->getTags()))); - - $this->tagDao->createMissingTags($tagNames); - $tagIds = array_map( function ($tag) { + if (!$tag->getId()) + throw new \RuntimeException('Unsaved entities found'); return $tag->getId(); }, - $this->tagDao->findByNames($tagNames)); + $post->getTags()); $existingTagRelationIds = array_map( function ($arrayEntity) diff --git a/src/Dao/TagDao.php b/src/Dao/TagDao.php index d45ba112..71409f02 100644 --- a/src/Dao/TagDao.php +++ b/src/Dao/TagDao.php @@ -48,31 +48,6 @@ class TagDao extends AbstractDao implements ICrudDao $this->fileService->save('tags.json', $json); } - public function createMissingTags(array $tagNames) - { - $tagNames = array_filter(array_unique($tagNames)); - if (empty($tagNames)) - return; - - $tagNamesNotToCreate = array_map( - function ($tag) - { - return $tag->getName(); - }, - $this->findByNames($tagNames)); - - $tagNamesToCreate = array_udiff($tagNames, $tagNamesNotToCreate, 'strcasecmp'); - - $tags = []; - foreach ($tagNamesToCreate as $tagName) - { - $tag = new \Szurubooru\Entities\Tag; - $tag->setName($tagName); - $tags[] = $tag; - } - $this->batchSave($tags); - } - protected function afterBatchSave(array $entities) { if (count($entities) > 0) diff --git a/src/Services/PostService.php b/src/Services/PostService.php index cb119054..cce16898 100644 --- a/src/Services/PostService.php +++ b/src/Services/PostService.php @@ -11,6 +11,7 @@ class PostService private $timeService; private $authService; private $fileService; + private $tagService; private $historyService; private $imageManipulator; @@ -23,6 +24,7 @@ class PostService \Szurubooru\Services\AuthService $authService, \Szurubooru\Services\TimeService $timeService, \Szurubooru\Services\FileService $fileService, + \Szurubooru\Services\TagService $tagService, \Szurubooru\Services\HistoryService $historyService, \Szurubooru\Services\ImageManipulation\ImageManipulator $imageManipulator) { @@ -34,6 +36,7 @@ class PostService $this->timeService = $timeService; $this->authService = $authService; $this->fileService = $fileService; + $this->tagService = $tagService; $this->historyService = $historyService; $this->imageManipulator = $imageManipulator; } @@ -267,6 +270,7 @@ class PostService $tag->setName($tagName); $tags[] = $tag; } + $tags = $this->tagService->createTags($tags); $post->setTags($tags); } diff --git a/src/Services/TagService.php b/src/Services/TagService.php new file mode 100644 index 00000000..08503e11 --- /dev/null +++ b/src/Services/TagService.php @@ -0,0 +1,60 @@ +transactionManager = $transactionManager; + $this->tagDao = $tagDao; + $this->timeService = $timeService; + } + + public function createTags(array $tags) + { + $transactionFunc = function() use ($tags) + { + $tagNameGetter = function($tag) + { + return $tag->getName(); + }; + + $tagNames = array_map($tagNameGetter, $tags); + $tagNames = array_filter(array_unique($tagNames)); + + $tagsNotToCreate = $this->tagDao->findByNames($tagNames); + $tagNamesNotToCreate = array_map($tagNameGetter, $tagsNotToCreate); + $tagNamesToCreate = array_udiff($tagNames, $tagNamesNotToCreate, 'strcasecmp'); + + $tagsToCreate = []; + foreach ($tagNamesToCreate as $tagName) + { + $tag = new \Szurubooru\Entities\Tag; + $tag->setName($tagName); + $tagsToCreate[] = $tag; + } + $createdTags = $this->tagDao->batchSave($tagsToCreate); + + $tagsNotToCreate = array_combine($tagNamesNotToCreate, $tagsNotToCreate); + $createdTags = array_combine($tagNamesToCreate, $createdTags); + $result = []; + foreach ($tags as $key => $tag) + { + if (isset($tagsNotToCreate[$tag->getName()])) + $tag = $tagsNotToCreate[$tag->getName()]; + else + $tag = $createdTags[$tag->getName()]; + $result[$key] = $tag; + } + return $result; + }; + return $this->transactionManager->commit($transactionFunc); + } +} diff --git a/tests/Dao/PostDaoTest.php b/tests/Dao/PostDaoTest.php index 13063b59..03d25477 100644 --- a/tests/Dao/PostDaoTest.php +++ b/tests/Dao/PostDaoTest.php @@ -13,7 +13,11 @@ final class PostDaoTest extends \Szurubooru\Tests\AbstractDatabaseTestCase parent::setUp(); $this->fileServiceMock = $this->mock(\Szurubooru\Services\FileService::class); $this->thumbnailServiceMock = $this->mock(\Szurubooru\Services\ThumbnailService::class); - $this->tagDao = new \Szurubooru\Dao\TagDao($this->databaseConnection, $this->fileServiceMock); + + $this->tagDao = new \Szurubooru\Dao\TagDao( + $this->databaseConnection, + $this->fileServiceMock); + $this->userDao = new \Szurubooru\Dao\UserDao( $this->databaseConnection, $this->fileServiceMock, @@ -141,6 +145,8 @@ final class PostDaoTest extends \Szurubooru\Tests\AbstractDatabaseTestCase $tag1->setName('tag1'); $tag2 = new \Szurubooru\Entities\Tag(); $tag2->setName('tag2'); + $this->tagDao->save($tag1); + $this->tagDao->save($tag2); $testTags = ['tag1' => $tag1, 'tag2' => $tag2]; $postDao = $this->getPostDao(); diff --git a/tests/Dao/TagDaoTest.php b/tests/Dao/TagDaoTest.php index a0e8dc5b..3355738f 100644 --- a/tests/Dao/TagDaoTest.php +++ b/tests/Dao/TagDaoTest.php @@ -14,16 +14,14 @@ final class TagDaoTest extends \Szurubooru\Tests\AbstractDatabaseTestCase public function testFindByPostIds() { $pdo = $this->databaseConnection->getPDO(); - $transactionManager = new \Szurubooru\Dao\TransactionManager($this->databaseConnection); - $transactionManager->commit(function() use ($pdo) - { - $pdo->exec('INSERT INTO tags(id, name) VALUES (1, \'test1\')'); - $pdo->exec('INSERT INTO tags(id, name) VALUES (2, \'test2\')'); - $pdo->exec('INSERT INTO postTags(postId, tagId) VALUES (5, 1)'); - $pdo->exec('INSERT INTO postTags(postId, tagId) VALUES (6, 1)'); - $pdo->exec('INSERT INTO postTags(postId, tagId) VALUES (5, 2)'); - $pdo->exec('INSERT INTO postTags(postId, tagId) VALUES (6, 2)'); - }); + + $pdo->exec('INSERT INTO tags(id, name) VALUES (1, \'test1\')'); + $pdo->exec('INSERT INTO tags(id, name) VALUES (2, \'test2\')'); + $pdo->exec('INSERT INTO postTags(postId, tagId) VALUES (5, 1)'); + $pdo->exec('INSERT INTO postTags(postId, tagId) VALUES (6, 1)'); + $pdo->exec('INSERT INTO postTags(postId, tagId) VALUES (5, 2)'); + $pdo->exec('INSERT INTO postTags(postId, tagId) VALUES (6, 2)'); + $tag1 = new \Szurubooru\Entities\Tag(1); $tag1->setName('test1'); $tag2 = new \Szurubooru\Entities\Tag(2); diff --git a/tests/Services/PostServiceTest.php b/tests/Services/PostServiceTest.php index f1047061..8c0881e8 100644 --- a/tests/Services/PostServiceTest.php +++ b/tests/Services/PostServiceTest.php @@ -1,7 +1,7 @@ configMock = $this->mockConfig(); $this->validatorMock = $this->mock(\Szurubooru\Validator::class); $this->transactionManagerMock = $this->mockTransactionManager(); @@ -24,6 +26,7 @@ class PostServiceTest extends \Szurubooru\Tests\AbstractTestCase $this->authServiceMock = $this->mock(\Szurubooru\Services\AuthService::class); $this->timeServiceMock = $this->mock(\Szurubooru\Services\TimeService::class); $this->fileServiceMock = $this->mock(\Szurubooru\Services\FileService::class); + $this->tagService = \Szurubooru\Injector::get(\Szurubooru\Services\TagService::class); $this->historyServiceMock = $this->mock(\Szurubooru\Services\HistoryService::class); $this->configMock->set('database/maxPostSize', 1000000); $this->imageManipulatorMock = $this->mock(\Szurubooru\Services\ImageManipulation\ImageManipulator::class); @@ -189,6 +192,7 @@ class PostServiceTest extends \Szurubooru\Tests\AbstractTestCase $this->authServiceMock, $this->timeServiceMock, $this->fileServiceMock, + $this->tagService, $this->historyServiceMock, $this->imageManipulatorMock); } diff --git a/tests/Services/TagServiceTest.php b/tests/Services/TagServiceTest.php new file mode 100644 index 00000000..d171bed9 --- /dev/null +++ b/tests/Services/TagServiceTest.php @@ -0,0 +1,71 @@ +databaseConnection->getPDO(); + $tagService = $this->getTagService(); + $result = $tagService->createTags([]); + $this->assertEquals(0, count($result)); + } + + public function testCreatingTagsWhenNoneExist() + { + $pdo = $this->databaseConnection->getPDO(); + $tag = new \Szurubooru\Entities\Tag(); + $tag->setName('test'); + + $tagService = $this->getTagService(); + $result = $tagService->createTags([$tag]); + $this->assertEquals(1, count($result)); + $this->assertEquals(1, $result[0]->getId()); + $this->assertEquals('test', $result[0]->getName()); + } + + public function testCreatingTagsWhenAllExist() + { + $pdo = $this->databaseConnection->getPDO(); + $pdo->exec('INSERT INTO tags(id, name) VALUES (1, \'test1\')'); + $pdo->exec('INSERT INTO tags(id, name) VALUES (2, \'test2\')'); + + $tag1 = new \Szurubooru\Entities\Tag(); + $tag1->setName('test1'); + $tag2 = new \Szurubooru\Entities\Tag(); + $tag2->setName('test2'); + + $tagService = $this->getTagService(); + $result = $tagService->createTags([$tag1, $tag2]); + $this->assertEquals(2, count($result)); + $this->assertEquals(1, $result[0]->getId()); + $this->assertEquals(2, $result[1]->getId()); + $this->assertEquals('test1', $result[0]->getName()); + $this->assertEquals('test2', $result[1]->getName()); + } + + public function testCreatingTagsWhenSomeExist() + { + $pdo = $this->databaseConnection->getPDO(); + $pdo->exec('INSERT INTO tags(id, name) VALUES (1, \'test1\')'); + $pdo->exec('INSERT INTO tags(id, name) VALUES (2, \'test2\')'); + + $tag1 = new \Szurubooru\Entities\Tag(); + $tag1->setName('test1'); + $tag2 = new \Szurubooru\Entities\Tag(); + $tag2->setName('test3'); + + $tagService = $this->getTagService(); + $result = $tagService->createTags([$tag1, $tag2]); + $this->assertEquals(2, count($result)); + $this->assertEquals(1, $result[0]->getId()); + $this->assertEquals(3, $result[1]->getId()); + $this->assertEquals('test1', $result[0]->getName()); + $this->assertEquals('test3', $result[1]->getName()); + } + + private function getTagService() + { + return \Szurubooru\Injector::get(\Szurubooru\Services\TagService::class); + } +}