diff --git a/public_html/data/.gitignore b/public_html/data/.gitignore
index 20c21237..402d9491 100644
--- a/public_html/data/.gitignore
+++ b/public_html/data/.gitignore
@@ -1 +1,2 @@
posts
+tags.json
diff --git a/src/Dao/AbstractDao.php b/src/Dao/AbstractDao.php
index c8fe3395..85d559a8 100644
--- a/src/Dao/AbstractDao.php
+++ b/src/Dao/AbstractDao.php
@@ -34,18 +34,24 @@ abstract class AbstractDao implements ICrudDao
public function save(&$entity)
{
- if ($entity->getId())
- {
- $entity = $this->update($entity);
- }
- else
- {
- $entity = $this->create($entity);
- }
+ $entity = $this->upsert($entity);
$this->afterSave($entity);
+ $this->afterBatchSave([$entity]);
return $entity;
}
+ public function batchSave(array $entities)
+ {
+ foreach ($entities as $key => $entity)
+ {
+ $entities[$key] = $this->upsert($entity);
+ $this->afterSave($entity);
+ }
+ if (count($entities) > 0)
+ $this->afterBatchSave([$entity]);
+ return $entities;
+ }
+
public function findAll()
{
$query = $this->fpdo->from($this->tableName);
@@ -165,6 +171,10 @@ abstract class AbstractDao implements ICrudDao
{
}
+ protected function afterBatchSave(array $entities)
+ {
+ }
+
protected function beforeDelete(\Szurubooru\Entities\Entity $entity)
{
}
@@ -247,4 +257,16 @@ abstract class AbstractDao implements ICrudDao
$orderByString .= $orderColumn . ' ' . ($orderDir === \Szurubooru\SearchServices\Filters\IFilter::ORDER_DESC ? 'DESC' : 'ASC') . ', ';
return substr($orderByString, 0, -2);
}
+
+ private function upsert(\Szurubooru\Entities\Entity $entity)
+ {
+ if ($entity->getId())
+ {
+ return $this->update($entity);
+ }
+ else
+ {
+ return $this->create($entity);
+ }
+ }
}
diff --git a/src/Dao/ICrudDao.php b/src/Dao/ICrudDao.php
index 9e38b127..5c0f5ed5 100644
--- a/src/Dao/ICrudDao.php
+++ b/src/Dao/ICrudDao.php
@@ -9,6 +9,8 @@ interface ICrudDao
public function save(&$object);
+ public function batchSave(array $object);
+
public function deleteById($objectId);
public function deleteAll();
diff --git a/src/Dao/PostDao.php b/src/Dao/PostDao.php
index 1dfec15b..ee68d59f 100644
--- a/src/Dao/PostDao.php
+++ b/src/Dao/PostDao.php
@@ -203,6 +203,8 @@ class PostDao extends AbstractDao implements ICrudDao
{
$this->fpdo->deleteFrom('postTags')->where('postId', $post->getId())->where('tagId', $tagId)->execute();
}
+
+ $this->tagDao->exportJson();
}
private function syncPostRelations(\Szurubooru\Entities\Post $post)
diff --git a/src/Dao/TagDao.php b/src/Dao/TagDao.php
index 8bfa721c..fc16fd36 100644
--- a/src/Dao/TagDao.php
+++ b/src/Dao/TagDao.php
@@ -3,12 +3,18 @@ namespace Szurubooru\Dao;
class TagDao extends AbstractDao implements ICrudDao
{
- public function __construct(\Szurubooru\DatabaseConnection $databaseConnection)
+ private $fileService;
+
+ public function __construct(
+ \Szurubooru\DatabaseConnection $databaseConnection,
+ \Szurubooru\Services\FileService $fileService)
{
parent::__construct(
$databaseConnection,
'tags',
new \Szurubooru\Dao\EntityConverters\TagEntityConverter());
+
+ $this->fileService = $fileService;
}
public function findByNames($tagNames)
@@ -27,6 +33,17 @@ class TagDao extends AbstractDao implements ICrudDao
return $this->findByIds($tagIds);
}
+ public function exportJson()
+ {
+ $tags = [];
+ foreach ($this->findAll() as $tag)
+ {
+ $tags[$tag->getName()] = $tag->getUsages();
+ }
+ $json = json_encode($tags);
+ $this->fileService->save('tags.json', $json);
+ }
+
public function createMissingTags(array $tagNames)
{
$tagNames = array_filter(array_unique($tagNames));
@@ -42,11 +59,19 @@ class TagDao extends AbstractDao implements ICrudDao
$tagNamesToCreate = array_udiff($tagNames, $tagNamesNotToCreate, 'strcasecmp');
+ $tags = [];
foreach ($tagNamesToCreate as $tagName)
{
$tag = new \Szurubooru\Entities\Tag;
$tag->setName($tagName);
- $this->save($tag);
+ $tags[] = $tag;
}
+ $this->batchSave($tags);
+ }
+
+ protected function afterBatchSave(array $entities)
+ {
+ if (count($entities) > 0)
+ $this->exportJson();
}
}
diff --git a/src/Upgrades/Upgrade12.php b/src/Upgrades/Upgrade12.php
new file mode 100644
index 00000000..ff55c46d
--- /dev/null
+++ b/src/Upgrades/Upgrade12.php
@@ -0,0 +1,17 @@
+tagDao = $tagDao;
+ }
+
+ public function run(\Szurubooru\DatabaseConnection $databaseConnection)
+ {
+ $this->tagDao->exportJson();
+ }
+}
diff --git a/src/di.php b/src/di.php
index 41b38339..bb835e0c 100644
--- a/src/di.php
+++ b/src/di.php
@@ -27,6 +27,7 @@ return [
$container->get(\Szurubooru\Upgrades\Upgrade09::class),
$container->get(\Szurubooru\Upgrades\Upgrade10::class),
$container->get(\Szurubooru\Upgrades\Upgrade11::class),
+ $container->get(\Szurubooru\Upgrades\Upgrade12::class),
];
}),
diff --git a/tests/AbstractDatabaseTestCase.php b/tests/AbstractDatabaseTestCase.php
index 7cd9cf6e..cb5ba04c 100644
--- a/tests/AbstractDatabaseTestCase.php
+++ b/tests/AbstractDatabaseTestCase.php
@@ -13,8 +13,10 @@ abstract class AbstractDatabaseTestCase extends \Szurubooru\Tests\AbstractTestCa
$config->set('database/user', '');
$config->set('database/password', '');
+ $fileServiceMock = $this->mock(\Szurubooru\Services\FileService::class);
$this->databaseConnection = new \Szurubooru\DatabaseConnection($config);
\Szurubooru\Injector::set(\Szurubooru\DatabaseConnection::class, $this->databaseConnection);
+ \Szurubooru\Injector::set(\Szurubooru\Services\FileService::class, $fileServiceMock);
$upgradeRepository = \Szurubooru\Injector::get(\Szurubooru\Upgrades\UpgradeRepository::class);
$upgradeService = new \Szurubooru\Services\UpgradeService($config, $this->databaseConnection, $upgradeRepository);
diff --git a/tests/Dao/PostDaoTest.php b/tests/Dao/PostDaoTest.php
index 5bba25c2..afed77e8 100644
--- a/tests/Dao/PostDaoTest.php
+++ b/tests/Dao/PostDaoTest.php
@@ -13,7 +13,7 @@ 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->tagDao = new \Szurubooru\Dao\TagDao($this->databaseConnection, $this->fileServiceMock);
$this->userDao = new \Szurubooru\Dao\UserDao(
$this->databaseConnection,
$this->fileServiceMock,
@@ -243,9 +243,11 @@ final class PostDaoTest extends \Szurubooru\Tests\AbstractDatabaseTestCase
[$post->getThumbnailSourceContentPath()]);
$this->fileServiceMock
- ->expects($this->once())
+ ->expects($this->exactly(2))
->method('save')
- ->with($post->getContentPath(), 'whatever');
+ ->withConsecutive(
+ [$post->getContentPath(), 'whatever'],
+ ['tags.json', '[]']);
$postDao->save($post);
}
@@ -264,11 +266,12 @@ final class PostDaoTest extends \Szurubooru\Tests\AbstractDatabaseTestCase
[$post->getThumbnailSourceContentPath()]);
$this->fileServiceMock
- ->expects($this->exactly(2))
+ ->expects($this->exactly(3))
->method('save')
->withConsecutive(
[$post->getContentPath(), 'whatever'],
- [$post->getThumbnailSourceContentPath(), 'an image of sharks']);
+ [$post->getThumbnailSourceContentPath(), 'an image of sharks'],
+ ['tags.json', '[]']);
$postDao->save($post);
}
diff --git a/tests/Dao/TagDaoTest.php b/tests/Dao/TagDaoTest.php
index 487da63a..a0e8dc5b 100644
--- a/tests/Dao/TagDaoTest.php
+++ b/tests/Dao/TagDaoTest.php
@@ -3,6 +3,14 @@ namespace Szurubooru\Tests\Dao;
final class TagDaoTest extends \Szurubooru\Tests\AbstractDatabaseTestCase
{
+ private $fileServiceMock;
+
+ public function setUp()
+ {
+ parent::setUp();
+ $this->fileServiceMock = $this->mock(\Szurubooru\Services\FileService::class);
+ }
+
public function testFindByPostIds()
{
$pdo = $this->databaseConnection->getPDO();
@@ -29,8 +37,28 @@ final class TagDaoTest extends \Szurubooru\Tests\AbstractDatabaseTestCase
$this->assertEntitiesEqual($expected, $actual);
}
+ public function testExportSingle()
+ {
+ $tag1 = new \Szurubooru\Entities\Tag();
+ $tag1->setName('test');
+ $this->fileServiceMock->expects($this->once())->method('save')->with('tags.json', '{"test":0}');
+ $tagDao = $this->getTagDao();
+ $tagDao->save($tag1);
+ }
+
+ public function testExportMultiple()
+ {
+ $tag1 = new \Szurubooru\Entities\Tag();
+ $tag1->setName('test1');
+ $tag2 = new \Szurubooru\Entities\Tag();
+ $tag2->setName('test2');
+ $this->fileServiceMock->expects($this->once())->method('save')->with('tags.json', '{"test1":0,"test2":0}');
+ $tagDao = $this->getTagDao();
+ $tagDao->batchSave([$tag1, $tag2]);
+ }
+
private function getTagDao()
{
- return new \Szurubooru\Dao\TagDao($this->databaseConnection);
+ return new \Szurubooru\Dao\TagDao($this->databaseConnection, $this->fileServiceMock);
}
}