Added note CRUD to backend
This commit is contained in:
parent
5124733ee6
commit
f169bef0eb
11 changed files with 251 additions and 7 deletions
|
@ -57,6 +57,10 @@ changePostThumbnail = powerUser, moderator, administrator
|
||||||
changePostRelations = regularUser, powerUser, moderator, administrator
|
changePostRelations = regularUser, powerUser, moderator, administrator
|
||||||
changePostFlags = regularUser, powerUser, moderator, administrator
|
changePostFlags = regularUser, powerUser, moderator, administrator
|
||||||
|
|
||||||
|
addPostNotes = powerUser, moderator, administrator
|
||||||
|
editPostNotes = powerUser, moderator, administrator
|
||||||
|
deletePostNotes = powerUser, moderator, administrator
|
||||||
|
|
||||||
listTags = regularUser, powerUser, moderator, administrator
|
listTags = regularUser, powerUser, moderator, administrator
|
||||||
massTag = powerUser, moderator, administrator
|
massTag = powerUser, moderator, administrator
|
||||||
changeTagName = moderator, administrator
|
changeTagName = moderator, administrator
|
||||||
|
|
|
@ -35,6 +35,10 @@ App.Auth = function(_, jQuery, util, api, appState, promise) {
|
||||||
changePostRelations: 'changePostRelations',
|
changePostRelations: 'changePostRelations',
|
||||||
changePostFlags: 'changePostFlags',
|
changePostFlags: 'changePostFlags',
|
||||||
|
|
||||||
|
addPostNotes: 'addPostNotes',
|
||||||
|
editPostNotes: 'editPostNotes',
|
||||||
|
deletePostNotes: 'deletePostNotes',
|
||||||
|
|
||||||
listComments: 'listComments',
|
listComments: 'listComments',
|
||||||
addComments: 'addComments',
|
addComments: 'addComments',
|
||||||
editOwnComments: 'editOwnComments',
|
editOwnComments: 'editOwnComments',
|
||||||
|
|
77
src/Controllers/PostNotesController.php
Normal file
77
src/Controllers/PostNotesController.php
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
<?php
|
||||||
|
namespace Szurubooru\Controllers;
|
||||||
|
use Szurubooru\Controllers\ViewProxies\PostNoteViewProxy;
|
||||||
|
use Szurubooru\FormData\PostNoteFormData;
|
||||||
|
use Szurubooru\Helpers\InputReader;
|
||||||
|
use Szurubooru\Privilege;
|
||||||
|
use Szurubooru\Router;
|
||||||
|
use Szurubooru\Services\PostNotesService;
|
||||||
|
use Szurubooru\Services\PostService;
|
||||||
|
use Szurubooru\Services\PrivilegeService;
|
||||||
|
|
||||||
|
final class PostNotesController extends AbstractController
|
||||||
|
{
|
||||||
|
private $inputReader;
|
||||||
|
private $postService;
|
||||||
|
private $postNotesService;
|
||||||
|
private $privilegeService;
|
||||||
|
private $postNoteViewProxy;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
InputReader $inputReader,
|
||||||
|
PostService $postService,
|
||||||
|
PostNotesService $postNotesService,
|
||||||
|
PrivilegeService $privilegeService,
|
||||||
|
PostNoteViewProxy $postNoteViewProxy)
|
||||||
|
{
|
||||||
|
$this->inputReader = $inputReader;
|
||||||
|
$this->postService = $postService;
|
||||||
|
$this->postNotesService = $postNotesService;
|
||||||
|
$this->privilegeService = $privilegeService;
|
||||||
|
$this->postNoteViewProxy = $postNoteViewProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function registerRoutes(Router $router)
|
||||||
|
{
|
||||||
|
$router->get('/api/notes/:postNameOrId', [$this, 'getPostNotes']);
|
||||||
|
$router->post('/api/notes/:postNameOrId', [$this, 'addPostNote']);
|
||||||
|
$router->put('/api/notes/:postNoteId', [$this, 'editPostNote']);
|
||||||
|
$router->delete('/api/notes/:postNoteId', [$this, 'deletePostNote']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPostNotes($postNameOrId)
|
||||||
|
{
|
||||||
|
$post = $this->postService->getByNameOrId($postNameOrId);
|
||||||
|
$postNotes = $this->postNotesService->getByPost($post);
|
||||||
|
return $this->postNoteViewProxy->fromArray($postNotes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addPostNote($postNameOrId)
|
||||||
|
{
|
||||||
|
$post = $this->postService->getByNameOrId($postNameOrId);
|
||||||
|
|
||||||
|
$this->privilegeService->assertPrivilege(Privilege::ADD_POST_NOTES);
|
||||||
|
|
||||||
|
$formData = new PostNoteFormData($this->inputReader);
|
||||||
|
$postNote = $this->postNotesService->createPostNote($post, $formData);
|
||||||
|
return $this->postNoteViewProxy->fromEntity($postNote);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function editPostNote($postNoteId)
|
||||||
|
{
|
||||||
|
$postNote = $this->postNotesService->getById($postNoteId);
|
||||||
|
|
||||||
|
$this->privilegeService->assertPrivilege(Privilege::EDIT_POST_NOTES);
|
||||||
|
|
||||||
|
$formData = new PostNoteFormData($this->inputReader);
|
||||||
|
$postNote = $this->postNotesService->updatePostNote($postNote, $formData);
|
||||||
|
return $this->postNoteViewProxy->fromEntity($postNote);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deletePostNote($postNoteId)
|
||||||
|
{
|
||||||
|
$postNote = $this->postNotesService->getById($postNoteId);
|
||||||
|
$this->privilegeService->assertPrivilege(Privilege::DELETE_POST_NOTES);
|
||||||
|
return $this->postNotesService->deletePostNote($postNote);
|
||||||
|
}
|
||||||
|
}
|
|
@ -114,7 +114,7 @@ class PostViewProxy extends AbstractViewProxy
|
||||||
$result->favorites = $this->userViewProxy->fromArray($this->favoritesService->getFavoriteUsers($post));
|
$result->favorites = $this->userViewProxy->fromArray($this->favoritesService->getFavoriteUsers($post));
|
||||||
|
|
||||||
if (!empty($config[self::FETCH_NOTES]))
|
if (!empty($config[self::FETCH_NOTES]))
|
||||||
$result->notes = $this->postNoteViewProxy->fromArray($this->postNotesService->getPostNotes($post));
|
$result->notes = $this->postNoteViewProxy->fromArray($this->postNotesService->getByPost($post));
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,19 +2,38 @@
|
||||||
namespace Szurubooru\Dao;
|
namespace Szurubooru\Dao;
|
||||||
use Szurubooru\Dao\EntityConverters\PostNoteEntityConverter;
|
use Szurubooru\Dao\EntityConverters\PostNoteEntityConverter;
|
||||||
use Szurubooru\DatabaseConnection;
|
use Szurubooru\DatabaseConnection;
|
||||||
|
use Szurubooru\Dao\PostDao;
|
||||||
|
use Szurubooru\Entities\Entity;
|
||||||
|
use Szurubooru\Entities\PostNote;
|
||||||
|
|
||||||
class PostNoteDao extends AbstractDao implements ICrudDao
|
class PostNoteDao extends AbstractDao implements ICrudDao
|
||||||
{
|
{
|
||||||
public function __construct(DatabaseConnection $databaseConnection)
|
private $postDao;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
DatabaseConnection $databaseConnection,
|
||||||
|
PostDao $postDao)
|
||||||
{
|
{
|
||||||
parent::__construct(
|
parent::__construct(
|
||||||
$databaseConnection,
|
$databaseConnection,
|
||||||
'postNotes',
|
'postNotes',
|
||||||
new PostNoteEntityConverter());
|
new PostNoteEntityConverter());
|
||||||
|
|
||||||
|
$this->postDao = $postDao;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function findByPostId($postId)
|
public function findByPostId($postId)
|
||||||
{
|
{
|
||||||
return $this->findBy('postId', $postId);
|
return $this->findBy('postId', $postId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function afterLoad(Entity $postNote)
|
||||||
|
{
|
||||||
|
$postNote->setLazyLoader(
|
||||||
|
PostNote::LAZY_LOADER_POST,
|
||||||
|
function (PostNote $postNote)
|
||||||
|
{
|
||||||
|
return $this->postDao->findById($postNote->getPostId());
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,8 @@ final class PostNote extends Entity
|
||||||
private $height;
|
private $height;
|
||||||
private $text;
|
private $text;
|
||||||
|
|
||||||
|
const LAZY_LOADER_POST = 'post';
|
||||||
|
|
||||||
public function getPostId()
|
public function getPostId()
|
||||||
{
|
{
|
||||||
return $this->postId;
|
return $this->postId;
|
||||||
|
@ -69,4 +71,15 @@ final class PostNote extends Entity
|
||||||
{
|
{
|
||||||
$this->text = $text;
|
$this->text = $text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getPost()
|
||||||
|
{
|
||||||
|
return $this->lazyLoad(self::LAZY_LOADER_POST, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPost(Post $post)
|
||||||
|
{
|
||||||
|
$this->lazySave(self::LAZY_LOADER_POST, $post);
|
||||||
|
$this->postId = $post->getId();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
30
src/FormData/PostNoteFormData.php
Normal file
30
src/FormData/PostNoteFormData.php
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
namespace Szurubooru\FormData;
|
||||||
|
use Szurubooru\IValidatable;
|
||||||
|
use Szurubooru\Validator;
|
||||||
|
|
||||||
|
class PostNoteFormData implements IValidatable
|
||||||
|
{
|
||||||
|
public $left;
|
||||||
|
public $top;
|
||||||
|
public $width;
|
||||||
|
public $height;
|
||||||
|
public $text;
|
||||||
|
|
||||||
|
public function __construct($inputReader = null)
|
||||||
|
{
|
||||||
|
if ($inputReader !== null)
|
||||||
|
{
|
||||||
|
$this->left = intval($inputReader->left);
|
||||||
|
$this->top = intval($inputReader->top);
|
||||||
|
$this->width = intval($inputReader->width);
|
||||||
|
$this->height = intval($inputReader->height);
|
||||||
|
$this->text = trim($inputReader->text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function validate(Validator $validator)
|
||||||
|
{
|
||||||
|
$validator->validateMinLength($this->text, 3, 'Post note content');
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,6 +35,10 @@ class Privilege
|
||||||
const CHANGE_POST_RELATIONS = 'changePostRelations';
|
const CHANGE_POST_RELATIONS = 'changePostRelations';
|
||||||
const CHANGE_POST_FLAGS = 'changePostFlags';
|
const CHANGE_POST_FLAGS = 'changePostFlags';
|
||||||
|
|
||||||
|
const ADD_POST_NOTES = 'addPostNotes';
|
||||||
|
const EDIT_POST_NOTES = 'editPostNotes';
|
||||||
|
const DELETE_POST_NOTES = 'deletePostNotes';
|
||||||
|
|
||||||
const LIST_TAGS = 'listTags';
|
const LIST_TAGS = 'listTags';
|
||||||
const MASS_TAG = 'massTag';
|
const MASS_TAG = 'massTag';
|
||||||
const CHANGE_TAG_NAME = 'changeTagName';
|
const CHANGE_TAG_NAME = 'changeTagName';
|
||||||
|
|
|
@ -1,19 +1,98 @@
|
||||||
<?php
|
<?php
|
||||||
namespace Szurubooru\Services;
|
namespace Szurubooru\Services;
|
||||||
|
use Szurubooru\Dao\TransactionManager;
|
||||||
use Szurubooru\Dao\PostNoteDao;
|
use Szurubooru\Dao\PostNoteDao;
|
||||||
use Szurubooru\Entities\Post;
|
use Szurubooru\Entities\Post;
|
||||||
|
use Szurubooru\Entities\PostNote;
|
||||||
|
use Szurubooru\FormData\PostNoteFormData;
|
||||||
|
use Szurubooru\Services\HistoryService;
|
||||||
|
use Szurubooru\Validator;
|
||||||
|
|
||||||
class PostNotesService
|
class PostNotesService
|
||||||
{
|
{
|
||||||
|
private $validator;
|
||||||
|
private $transactionManager;
|
||||||
private $postNoteDao;
|
private $postNoteDao;
|
||||||
|
private $historyService;
|
||||||
|
|
||||||
public function __construct(PostNoteDao $postNoteDao)
|
public function __construct(
|
||||||
|
Validator $validator,
|
||||||
|
TransactionManager $transactionManager,
|
||||||
|
PostNoteDao $postNoteDao,
|
||||||
|
HistoryService $historyService)
|
||||||
{
|
{
|
||||||
|
$this->validator = $validator;
|
||||||
|
$this->transactionManager = $transactionManager;
|
||||||
$this->postNoteDao = $postNoteDao;
|
$this->postNoteDao = $postNoteDao;
|
||||||
|
$this->historyService = $historyService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPostNotes(Post $post)
|
public function getById($postNoteId)
|
||||||
{
|
{
|
||||||
return $this->postNoteDao->findByPostId($post->getId());
|
$transactionFunc = function() use ($postNoteId)
|
||||||
|
{
|
||||||
|
$postNote = $this->postNoteDao->findById($postNoteId);
|
||||||
|
if (!$postNote)
|
||||||
|
throw new \InvalidArgumentException('Post note with ID "' . $postNoteId . '" was not found.');
|
||||||
|
return $postNote;
|
||||||
|
};
|
||||||
|
return $this->transactionManager->rollback($transactionFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getByPost(Post $post)
|
||||||
|
{
|
||||||
|
$transactionFunc = function() use ($post)
|
||||||
|
{
|
||||||
|
return $this->postNoteDao->findByPostId($post->getId());
|
||||||
|
};
|
||||||
|
return $this->transactionManager->rollback($transactionFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createPostNote(Post $post, PostNoteFormData $formData)
|
||||||
|
{
|
||||||
|
$transactionFunc = function() use ($post, $formData)
|
||||||
|
{
|
||||||
|
$postNote = new PostNote();
|
||||||
|
$postNote->setPostId($post->getId());
|
||||||
|
|
||||||
|
$this->updatePostNoteWithFormData($postNote, $formData);
|
||||||
|
$this->postNoteDao->save($postNote);
|
||||||
|
|
||||||
|
$this->historyService->saveSnapshot($this->historyService->getPostChangeSnapshot($post));
|
||||||
|
return $postNote;
|
||||||
|
};
|
||||||
|
return $this->transactionManager->commit($transactionFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updatePostNote(PostNote $postNote, PostNoteFormData $formData)
|
||||||
|
{
|
||||||
|
$transactionFunc = function() use ($postNote, $formData)
|
||||||
|
{
|
||||||
|
$this->updatePostNoteWithFormData($postNote, $formData);
|
||||||
|
$this->postNoteDao->save($postNote);
|
||||||
|
|
||||||
|
$this->historyService->saveSnapshot($this->historyService->getPostChangeSnapshot($postNote->getPost()));
|
||||||
|
return $postNote;
|
||||||
|
};
|
||||||
|
return $this->transactionManager->commit($transactionFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deletePostNote(PostNote $postNote)
|
||||||
|
{
|
||||||
|
$transactionFunc = function() use ($postNote)
|
||||||
|
{
|
||||||
|
$this->postNoteDao->deleteById($postNote->getId());
|
||||||
|
};
|
||||||
|
$this->transactionManager->commit($transactionFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function updatePostNoteWithFormData(PostNote $postNote, PostNoteFormData $formData)
|
||||||
|
{
|
||||||
|
$formData->validate($this->validator);
|
||||||
|
$postNote->setLeft($formData->left);
|
||||||
|
$postNote->setTop($formData->top);
|
||||||
|
$postNote->setWidth($formData->width);
|
||||||
|
$postNote->setHeight($formData->height);
|
||||||
|
$postNote->setText($formData->text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@ return [
|
||||||
$container->get(\Szurubooru\Controllers\UserAvatarController::class),
|
$container->get(\Szurubooru\Controllers\UserAvatarController::class),
|
||||||
$container->get(\Szurubooru\Controllers\PostController::class),
|
$container->get(\Szurubooru\Controllers\PostController::class),
|
||||||
$container->get(\Szurubooru\Controllers\PostContentController::class),
|
$container->get(\Szurubooru\Controllers\PostContentController::class),
|
||||||
|
$container->get(\Szurubooru\Controllers\PostNotesController::class),
|
||||||
$container->get(\Szurubooru\Controllers\GlobalParamController::class),
|
$container->get(\Szurubooru\Controllers\GlobalParamController::class),
|
||||||
$container->get(\Szurubooru\Controllers\HistoryController::class),
|
$container->get(\Szurubooru\Controllers\HistoryController::class),
|
||||||
$container->get(\Szurubooru\Controllers\FavoritesController::class),
|
$container->get(\Szurubooru\Controllers\FavoritesController::class),
|
||||||
|
|
|
@ -1,11 +1,20 @@
|
||||||
<?php
|
<?php
|
||||||
namespace Szurubooru\Tests\Dao;
|
namespace Szurubooru\Tests\Dao;
|
||||||
|
use Szurubooru\Dao\PostDao;
|
||||||
use Szurubooru\Dao\PostNoteDao;
|
use Szurubooru\Dao\PostNoteDao;
|
||||||
use Szurubooru\Entities\PostNote;
|
use Szurubooru\Entities\PostNote;
|
||||||
use Szurubooru\Tests\AbstractDatabaseTestCase;
|
use Szurubooru\Tests\AbstractDatabaseTestCase;
|
||||||
|
|
||||||
final class PostNoteDaoTest extends AbstractDatabaseTestCase
|
final class PostNoteDaoTest extends AbstractDatabaseTestCase
|
||||||
{
|
{
|
||||||
|
private $postDaoMock;
|
||||||
|
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
$this->postDaoMock = $this->mock(PostDao::class);
|
||||||
|
}
|
||||||
|
|
||||||
public function testSettingValues()
|
public function testSettingValues()
|
||||||
{
|
{
|
||||||
$expected = new PostNote();
|
$expected = new PostNote();
|
||||||
|
@ -21,11 +30,15 @@ final class PostNoteDaoTest extends AbstractDatabaseTestCase
|
||||||
|
|
||||||
$actual = $postNoteDao->findById($expected->getId());
|
$actual = $postNoteDao->findById($expected->getId());
|
||||||
$this->assertEntitiesEqual($actual, $expected);
|
$this->assertEntitiesEqual($actual, $expected);
|
||||||
|
|
||||||
|
$this->postDaoMock->expects($this->once())->method('findById')->with(5)->willReturn('lazy post');
|
||||||
|
$this->assertEquals('lazy post', $actual->getPost());
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getPostNoteDao()
|
private function getPostNoteDao()
|
||||||
{
|
{
|
||||||
return new PostNoteDao($this->databaseConnection);
|
return new PostNoteDao(
|
||||||
|
$this->databaseConnection,
|
||||||
|
$this->postDaoMock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue