Moved tag synchronization to TagService
This commit is contained in:
parent
3cb9955ec6
commit
9379b4945a
8 changed files with 158 additions and 47 deletions
|
@ -203,21 +203,14 @@ class PostDao extends AbstractDao implements ICrudDao
|
||||||
|
|
||||||
private function syncTags(\Szurubooru\Entities\Post $post)
|
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(
|
$tagIds = array_map(
|
||||||
function ($tag)
|
function ($tag)
|
||||||
{
|
{
|
||||||
|
if (!$tag->getId())
|
||||||
|
throw new \RuntimeException('Unsaved entities found');
|
||||||
return $tag->getId();
|
return $tag->getId();
|
||||||
},
|
},
|
||||||
$this->tagDao->findByNames($tagNames));
|
$post->getTags());
|
||||||
|
|
||||||
$existingTagRelationIds = array_map(
|
$existingTagRelationIds = array_map(
|
||||||
function ($arrayEntity)
|
function ($arrayEntity)
|
||||||
|
|
|
@ -48,31 +48,6 @@ class TagDao extends AbstractDao implements ICrudDao
|
||||||
$this->fileService->save('tags.json', $json);
|
$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)
|
protected function afterBatchSave(array $entities)
|
||||||
{
|
{
|
||||||
if (count($entities) > 0)
|
if (count($entities) > 0)
|
||||||
|
|
|
@ -11,6 +11,7 @@ class PostService
|
||||||
private $timeService;
|
private $timeService;
|
||||||
private $authService;
|
private $authService;
|
||||||
private $fileService;
|
private $fileService;
|
||||||
|
private $tagService;
|
||||||
private $historyService;
|
private $historyService;
|
||||||
private $imageManipulator;
|
private $imageManipulator;
|
||||||
|
|
||||||
|
@ -23,6 +24,7 @@ class PostService
|
||||||
\Szurubooru\Services\AuthService $authService,
|
\Szurubooru\Services\AuthService $authService,
|
||||||
\Szurubooru\Services\TimeService $timeService,
|
\Szurubooru\Services\TimeService $timeService,
|
||||||
\Szurubooru\Services\FileService $fileService,
|
\Szurubooru\Services\FileService $fileService,
|
||||||
|
\Szurubooru\Services\TagService $tagService,
|
||||||
\Szurubooru\Services\HistoryService $historyService,
|
\Szurubooru\Services\HistoryService $historyService,
|
||||||
\Szurubooru\Services\ImageManipulation\ImageManipulator $imageManipulator)
|
\Szurubooru\Services\ImageManipulation\ImageManipulator $imageManipulator)
|
||||||
{
|
{
|
||||||
|
@ -34,6 +36,7 @@ class PostService
|
||||||
$this->timeService = $timeService;
|
$this->timeService = $timeService;
|
||||||
$this->authService = $authService;
|
$this->authService = $authService;
|
||||||
$this->fileService = $fileService;
|
$this->fileService = $fileService;
|
||||||
|
$this->tagService = $tagService;
|
||||||
$this->historyService = $historyService;
|
$this->historyService = $historyService;
|
||||||
$this->imageManipulator = $imageManipulator;
|
$this->imageManipulator = $imageManipulator;
|
||||||
}
|
}
|
||||||
|
@ -267,6 +270,7 @@ class PostService
|
||||||
$tag->setName($tagName);
|
$tag->setName($tagName);
|
||||||
$tags[] = $tag;
|
$tags[] = $tag;
|
||||||
}
|
}
|
||||||
|
$tags = $this->tagService->createTags($tags);
|
||||||
$post->setTags($tags);
|
$post->setTags($tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
60
src/Services/TagService.php
Normal file
60
src/Services/TagService.php
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
<?php
|
||||||
|
namespace Szurubooru\Services;
|
||||||
|
|
||||||
|
class TagService
|
||||||
|
{
|
||||||
|
private $transactionManager;
|
||||||
|
private $tagDao;
|
||||||
|
private $timeService;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
\Szurubooru\Dao\TransactionManager $transactionManager,
|
||||||
|
\Szurubooru\Dao\TagDao $tagDao,
|
||||||
|
\Szurubooru\Services\TimeService $timeService)
|
||||||
|
{
|
||||||
|
$this->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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,7 +13,11 @@ final class PostDaoTest extends \Szurubooru\Tests\AbstractDatabaseTestCase
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
$this->fileServiceMock = $this->mock(\Szurubooru\Services\FileService::class);
|
$this->fileServiceMock = $this->mock(\Szurubooru\Services\FileService::class);
|
||||||
$this->thumbnailServiceMock = $this->mock(\Szurubooru\Services\ThumbnailService::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->userDao = new \Szurubooru\Dao\UserDao(
|
||||||
$this->databaseConnection,
|
$this->databaseConnection,
|
||||||
$this->fileServiceMock,
|
$this->fileServiceMock,
|
||||||
|
@ -141,6 +145,8 @@ final class PostDaoTest extends \Szurubooru\Tests\AbstractDatabaseTestCase
|
||||||
$tag1->setName('tag1');
|
$tag1->setName('tag1');
|
||||||
$tag2 = new \Szurubooru\Entities\Tag();
|
$tag2 = new \Szurubooru\Entities\Tag();
|
||||||
$tag2->setName('tag2');
|
$tag2->setName('tag2');
|
||||||
|
$this->tagDao->save($tag1);
|
||||||
|
$this->tagDao->save($tag2);
|
||||||
$testTags = ['tag1' => $tag1, 'tag2' => $tag2];
|
$testTags = ['tag1' => $tag1, 'tag2' => $tag2];
|
||||||
|
|
||||||
$postDao = $this->getPostDao();
|
$postDao = $this->getPostDao();
|
||||||
|
|
|
@ -14,16 +14,14 @@ final class TagDaoTest extends \Szurubooru\Tests\AbstractDatabaseTestCase
|
||||||
public function testFindByPostIds()
|
public function testFindByPostIds()
|
||||||
{
|
{
|
||||||
$pdo = $this->databaseConnection->getPDO();
|
$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 tags(id, name) VALUES (1, \'test1\')');
|
$pdo->exec('INSERT INTO postTags(postId, tagId) VALUES (5, 1)');
|
||||||
$pdo->exec('INSERT INTO tags(id, name) VALUES (2, \'test2\')');
|
$pdo->exec('INSERT INTO postTags(postId, tagId) VALUES (6, 1)');
|
||||||
$pdo->exec('INSERT INTO postTags(postId, tagId) VALUES (5, 1)');
|
$pdo->exec('INSERT INTO postTags(postId, tagId) VALUES (5, 2)');
|
||||||
$pdo->exec('INSERT INTO postTags(postId, tagId) VALUES (6, 1)');
|
$pdo->exec('INSERT INTO postTags(postId, tagId) VALUES (6, 2)');
|
||||||
$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 = new \Szurubooru\Entities\Tag(1);
|
||||||
$tag1->setName('test1');
|
$tag1->setName('test1');
|
||||||
$tag2 = new \Szurubooru\Entities\Tag(2);
|
$tag2 = new \Szurubooru\Entities\Tag(2);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
namespace Szurubooru\Tests\Services;
|
namespace Szurubooru\Tests\Services;
|
||||||
|
|
||||||
class PostServiceTest extends \Szurubooru\Tests\AbstractTestCase
|
class PostServiceTest extends \Szurubooru\Tests\AbstractDatabaseTestCase
|
||||||
{
|
{
|
||||||
private $configMock;
|
private $configMock;
|
||||||
private $validatorMock;
|
private $validatorMock;
|
||||||
|
@ -11,11 +11,13 @@ class PostServiceTest extends \Szurubooru\Tests\AbstractTestCase
|
||||||
private $authServiceMock;
|
private $authServiceMock;
|
||||||
private $timeServiceMock;
|
private $timeServiceMock;
|
||||||
private $fileServiceMock;
|
private $fileServiceMock;
|
||||||
|
private $tagService;
|
||||||
private $historyServiceMock;
|
private $historyServiceMock;
|
||||||
private $imageManipulatorMock;
|
private $imageManipulatorMock;
|
||||||
|
|
||||||
public function setUp()
|
public function setUp()
|
||||||
{
|
{
|
||||||
|
parent::setUp();
|
||||||
$this->configMock = $this->mockConfig();
|
$this->configMock = $this->mockConfig();
|
||||||
$this->validatorMock = $this->mock(\Szurubooru\Validator::class);
|
$this->validatorMock = $this->mock(\Szurubooru\Validator::class);
|
||||||
$this->transactionManagerMock = $this->mockTransactionManager();
|
$this->transactionManagerMock = $this->mockTransactionManager();
|
||||||
|
@ -24,6 +26,7 @@ class PostServiceTest extends \Szurubooru\Tests\AbstractTestCase
|
||||||
$this->authServiceMock = $this->mock(\Szurubooru\Services\AuthService::class);
|
$this->authServiceMock = $this->mock(\Szurubooru\Services\AuthService::class);
|
||||||
$this->timeServiceMock = $this->mock(\Szurubooru\Services\TimeService::class);
|
$this->timeServiceMock = $this->mock(\Szurubooru\Services\TimeService::class);
|
||||||
$this->fileServiceMock = $this->mock(\Szurubooru\Services\FileService::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->historyServiceMock = $this->mock(\Szurubooru\Services\HistoryService::class);
|
||||||
$this->configMock->set('database/maxPostSize', 1000000);
|
$this->configMock->set('database/maxPostSize', 1000000);
|
||||||
$this->imageManipulatorMock = $this->mock(\Szurubooru\Services\ImageManipulation\ImageManipulator::class);
|
$this->imageManipulatorMock = $this->mock(\Szurubooru\Services\ImageManipulation\ImageManipulator::class);
|
||||||
|
@ -189,6 +192,7 @@ class PostServiceTest extends \Szurubooru\Tests\AbstractTestCase
|
||||||
$this->authServiceMock,
|
$this->authServiceMock,
|
||||||
$this->timeServiceMock,
|
$this->timeServiceMock,
|
||||||
$this->fileServiceMock,
|
$this->fileServiceMock,
|
||||||
|
$this->tagService,
|
||||||
$this->historyServiceMock,
|
$this->historyServiceMock,
|
||||||
$this->imageManipulatorMock);
|
$this->imageManipulatorMock);
|
||||||
}
|
}
|
||||||
|
|
71
tests/Services/TagServiceTest.php
Normal file
71
tests/Services/TagServiceTest.php
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
<?php
|
||||||
|
namespace Szurubooru\Tests\Services;
|
||||||
|
|
||||||
|
class TagServiceTest extends \Szurubooru\Tests\AbstractDatabaseTestCase
|
||||||
|
{
|
||||||
|
public function testCreatingEmpty()
|
||||||
|
{
|
||||||
|
$pdo = $this->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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue