Refactored comment model, fixed anonymous previews

This commit is contained in:
Marcin Kurczewski 2014-05-06 00:54:15 +02:00
parent fb7119b235
commit 8009c16f0c
12 changed files with 197 additions and 59 deletions

View file

@ -5,13 +5,13 @@ class AddCommentJob extends AbstractJob
{
$user = Auth::getCurrentUser();
$post = PostModel::findById($this->getArgument(self::POST_ID));
$text = CommentModel::validateText($this->getArgument(self::TEXT));
$text = $this->getArgument(self::TEXT);
$comment = CommentModel::spawn();
$comment->setCommenter($user);
$comment->setPost($post);
$comment->commentDate = time();
$comment->text = $text;
$comment->setDateTime(time());
$comment->setText($text);
CommentModel::save($comment);
Logger::log('{user} commented on {post}', [

View file

@ -12,8 +12,8 @@ class EditCommentJob extends AbstractJob
{
$comment = $this->comment;
$comment->commentDate = time();
$comment->text = CommentModel::validateText($this->getArgument(self::TEXT));
$comment->setDateTime(time());
$comment->setText($this->getArgument(self::TEXT));
CommentModel::save($comment);
Logger::log('{user} edited comment in {post}', [

View file

@ -4,12 +4,17 @@ class PreviewCommentJob extends AbstractJob
public function execute()
{
$user = Auth::getCurrentUser();
$text = CommentModel::validateText($this->getArgument(self::TEXT));
$text = $this->getArgument(self::TEXT);
$post = PostModel::findById($this->getArgument(self::POST_ID));
$comment = CommentModel::spawn();
$comment->setCommenter($user);
$comment->commentDate = time();
$comment->text = $text;
$comment->setDateTime(time());
$comment->setText($text);
$comment->setPost($post);
$comment->validate();
return $comment;
}
@ -20,7 +25,7 @@ class PreviewCommentJob extends AbstractJob
public function requiresAuthentication()
{
return true;
return false;
}
public function requiresConfirmedEmail()

View file

@ -19,10 +19,11 @@ class CommentController
$comment = Api::run(
new PreviewCommentJob(),
[
PreviewCommentJob::POST_ID => InputHelper::get('post-id'),
PreviewCommentJob::TEXT => InputHelper::get('text')
]);
getContext()->transport->textPreview = $comment->getText();
getContext()->transport->textPreview = $comment->getTextMarkdown();
}
public function addAction()

View file

@ -2,7 +2,7 @@
use \Chibi\Sql as Sql;
use \Chibi\Database as Database;
class CommentModel extends AbstractCrudModel
final class CommentModel extends AbstractCrudModel
{
public static function getTableName()
{
@ -12,7 +12,7 @@ class CommentModel extends AbstractCrudModel
public static function spawn()
{
$comment = new CommentEntity;
$comment->commentDate = time();
$comment->setDateTime(time());
return $comment;
}
@ -25,10 +25,10 @@ class CommentModel extends AbstractCrudModel
self::forgeId($comment);
$bindings = [
'text' => $comment->text,
'post_id' => $comment->postId,
'comment_date' => $comment->commentDate,
'commenter_id' => $comment->commenterId];
'text' => $comment->getText(),
'post_id' => $comment->getPostId(),
'comment_date' => $comment->getDateTime(),
'commenter_id' => $comment->getCommenterId()];
$stmt = new Sql\UpdateStatement();
$stmt->setTable('comment');
@ -74,7 +74,7 @@ class CommentModel extends AbstractCrudModel
public static function preloadCommenters($comments)
{
self::preloadOneToMany($comments,
function($comment) { return $comment->commenterId; },
function($comment) { return $comment->getCommenterId(); },
function($user) { return $user->getId(); },
function($userIds) { return UserModel::findByIds($userIds); },
function($comment, $user) { return $comment->setCache('commenter', $user); });
@ -83,25 +83,9 @@ class CommentModel extends AbstractCrudModel
public static function preloadPosts($comments)
{
self::preloadOneToMany($comments,
function($comment) { return $comment->postId; },
function($comment) { return $comment->getPostId(); },
function($post) { return $post->getId(); },
function($postIds) { return PostModel::findByIds($postIds); },
function($comment, $post) { $comment->setCache('post', $post); });
}
public static function validateText($text)
{
$text = trim($text);
$config = getConfig();
if (strlen($text) < $config->comments->minLength)
throw new SimpleException('Comment must have at least %d characters', $config->comments->minLength);
if (strlen($text) > $config->comments->maxLength)
throw new SimpleException('Comment must have at most %d characters', $config->comments->maxLength);
return $text;
}
}

View file

@ -1,48 +1,93 @@
<?php
class CommentEntity extends AbstractEntity implements IValidatable
final class CommentEntity extends AbstractEntity implements IValidatable
{
public $text;
public $postId;
public $commentDate;
public $commenterId;
protected $text;
protected $postId;
protected $commentDate;
protected $commenterId;
public function validate()
{
//todo
$text = trim($this->getText());
$config = getConfig();
if (strlen($text) < $config->comments->minLength)
throw new SimpleException('Comment must have at least %d characters', $config->comments->minLength);
if (strlen($text) > $config->comments->maxLength)
throw new SimpleException('Comment must have at most %d characters', $config->comments->maxLength);
if (!$this->getPostId())
throw new SimpleException('Trying to save comment that doesn\'t refer to any post');
if (!$this->getDateTime())
throw new SimpleException('Trying to save comment that has no creation date specified');
$this->setText($text);
}
public function getText()
{
return TextHelper::parseMarkdown($this->text);
return $this->text;
}
public function setPost($post)
public function getTextMarkdown()
{
$this->setCache('post', $post);
$this->postId = $post->id;
return TextHelper::parseMarkdown($this->getText());
}
public function setCommenter($user)
public function setText($text)
{
$this->setCache('commenter', $user);
$this->commenterId = $user ? $user->id : null;
$this->text = $text;
}
public function getPost()
{
if ($this->hasCache('post'))
return $this->getCache('post');
$post = PostModel::findById($this->postId);
$post = PostModel::findById($this->getPostId());
$this->setCache('post', $post);
return $post;
}
public function getPostId()
{
return $this->postId;
}
public function setPost($post)
{
$this->setCache('post', $post);
$this->postId = $post->getId();
}
public function getDateTime()
{
return $this->commentDate;
}
public function setDateTime($dateTime)
{
$this->commentDate = $dateTime;
}
public function getCommenter()
{
if ($this->hasCache('commenter'))
return $this->getCache('commenter');
$user = UserModel::findById($this->commenterId, false);
$user = UserModel::findById($this->getCommenterId(), false);
$this->setCache('commenter', $user);
return $user;
}
public function getCommenterId()
{
return $this->commenterId;
}
public function setCommenter($user)
{
$this->setCache('commenter', $user);
$this->commenterId = $user ? $user->getId() : null;
}
}

View file

@ -16,7 +16,7 @@ Assets::addScript('comment-edit.js');
<div class="form-row text">
<div class="input-wrapper">
<textarea name="text" cols="50" rows="3"><?= $this->context->transport->comment->text ?></textarea>
<textarea name="text" cols="50" rows="3"><?= $this->context->transport->comment->getText() ?></textarea>
</div>
</div>

View file

@ -32,8 +32,8 @@ Assets::addScript('comment-edit.js');
<?php endif ?>
</span>
<span class="date" title="<?= TextHelper::formatDate($this->context->comment->commentDate, true) ?>">
<?= TextHelper::formatDate($this->context->comment->commentDate, false) ?>
<span class="date" title="<?= TextHelper::formatDate($this->context->comment->getDateTime(), true) ?>">
<?= TextHelper::formatDate($this->context->comment->getDateTime(), false) ?>
</span>
<?php if (Access::check(new Privilege(
@ -64,7 +64,7 @@ Assets::addScript('comment-edit.js');
</div>
<div class="content">
<?= $this->context->comment->getText() ?>
<?= $this->context->comment->getTextMarkdown() ?>
</div>
</div>

View file

@ -35,7 +35,7 @@ class AbstractTest
$comment = CommentModel::spawn();
$comment->setPost($post);
$comment->setCommenter($owner);
$comment->text = 'test test';
$comment->setText('test test');
return CommentModel::save($comment);
}
}

View file

@ -14,10 +14,10 @@ class CommentAddTest extends AbstractTest
});
$this->assert->areEqual(1, CommentModel::getCount());
$this->assert->areEqual($text, $comment->text);
$this->assert->areEqual($text, $comment->getText());
$this->assert->areEqual(Auth::getCurrentUser()->getId(), $comment->getCommenter()->getId());
$this->assert->areEqual(1, $comment->getPost()->getId());
$this->assert->isNotNull($comment->commentDate);
$this->assert->isNotNull($comment->getDateTime());
$this->assert->doesNotThrow(function() use ($comment)
{
CommentModel::findById($comment->getId());
@ -101,7 +101,7 @@ class CommentAddTest extends AbstractTest
return $this->runApi($text);
});
$this->assert->areEqual($text, $comment->text);
$this->assert->areEqual($text, $comment->getText());
$this->assert->areEqual(Auth::getCurrentUser()->getId(), $comment->getCommenter()->getId());
$this->assert->areEqual(UserModel::getAnonymousName(), $comment->getCommenter()->getName());
}

View file

@ -11,10 +11,10 @@ class CommentEditTest extends AbstractTest
return $this->runApi($text);
});
$this->assert->areEqual($text, $comment->text);
$this->assert->areEqual($text, $comment->getText());
$this->assert->areEqual(Auth::getCurrentUser()->getId(), $comment->getCommenter()->getId());
$this->assert->areEqual(1, $comment->getPost()->getId());
$this->assert->isNotNull($comment->commentDate);
$this->assert->isNotNull($comment->getDateTime());
$this->assert->doesNotThrow(function() use ($comment)
{
CommentModel::findById($comment->getId());

View file

@ -0,0 +1,103 @@
<?php
class CommentPreviewTest extends AbstractTest
{
public function testPreview()
{
$this->prepare();
$text = 'alohaaaaaaa';
$comment = $this->assert->doesNotThrow(function() use ($text)
{
return $this->runApi($text);
});
$this->assert->areEqual(0, CommentModel::getCount());
$this->assert->areEqual($text, $comment->getText());
$this->assert->areEqual(Auth::getCurrentUser()->getId(), $comment->getCommenter()->getId());
$this->assert->isNotNull($comment->getDateTime());
$this->assert->throws(function() use ($comment)
{
CommentModel::findById($comment->getId());
}, 'Invalid comment ID');
}
public function testAlmostTooShortText()
{
$this->prepare();
$this->assert->doesNotThrow(function()
{
return $this->runApi(str_repeat('b', getConfig()->comments->minLength));
});
}
public function testAlmostTooLongText()
{
$this->prepare();
$this->assert->doesNotThrow(function()
{
return $this->runApi(str_repeat('b', getConfig()->comments->maxLength));
});
}
public function testTooShortText()
{
$this->prepare();
$this->assert->throws(function()
{
return $this->runApi(str_repeat('b', getConfig()->comments->minLength - 1));
}, 'Comment must have at least');
}
public function testTooLongText()
{
$this->prepare();
$this->assert->throws(function()
{
return $this->runApi(str_repeat('b', getConfig()->comments->maxLength + 1));
}, 'Comment must have at most');
}
public function testNoAuth()
{
$this->prepare();
Auth::setCurrentUser(null);
$this->assert->throws(function()
{
$this->assert->isFalse(Auth::isLoggedIn());
return $this->runApi('alohaaaaaaa');
}, 'Insufficient privileges');
}
public function testAccessDenial()
{
$this->prepare();
getConfig()->privileges->addComment = 'nobody';
Access::init();
$this->assert->isFalse(Access::check(new Privilege(Privilege::AddComment)));
$this->assert->throws(function()
{
return $this->runApi('alohaaaaaaa');
}, 'Insufficient privileges');
}
protected function runApi($text)
{
$post = $this->mockPost();
return Api::run(
new PreviewCommentJob(),
[
PreviewCommentJob::POST_ID => $post->getId(),
PreviewCommentJob::TEXT => $text,
]);
}
protected function prepare()
{
$this->login($this->mockUser());
}
}