feat(blog): hide comment
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Baoshuo Ren 2023-02-07 18:38:24 +08:00
parent e350a96dd7
commit d6e47f1de5
Signed by: baoshuo
GPG Key ID: 00CB9680AB29F51A
6 changed files with 137 additions and 15 deletions

View File

@ -323,12 +323,12 @@ if (UOJContest::cur()) {
</div>
<div class="tab-pane" id="submit">
<?php if ($pre_submit_check_ret !== true) : ?>
<p class="text-warning h4"><?= $pre_submit_check_ret ?></p>
<p class="text-warning-emphasis h4"><?= $pre_submit_check_ret ?></p>
<?php elseif ($no_more_submission) : ?>
<p class="text-warning h4"><?= $no_more_submission ?></p>
<p class="text-warning-emphasis h4"><?= $no_more_submission ?></p>
<?php else : ?>
<?php if ($submission_warning) : ?>
<p class="text-warning h4"><?= $submission_warning ?></p>
<p class="text-warning-emphasis h4"><?= $submission_warning ?></p>
<?php endif ?>
<?php if (isset($zip_answer_form)) : ?>
<?php $zip_answer_form->printHTML(); ?>

View File

@ -13,6 +13,8 @@ $blog = UOJBlog::info();
function getCommentContentToDisplay($comment) {
if (!$comment['is_hidden']) {
return $comment['content'];
} else if (UOJUserBlog::userHasManagePermission(Auth::user())) {
return '<span class="text-muted mb-3">【' . HTML::escape($comment['reason_to_hide']) . '】</span>' . $comment['content'];
} else {
return '<span class="text-muted">【' . HTML::escape($comment['reason_to_hide']) . '】</span>';
}
@ -162,6 +164,34 @@ $reply_form->handle = function (&$vdata) {
$reply_form->config['ctrl_enter_submit'] = true;
$reply_form->runAtServer();
if (UOJUserBlog::userHasManagePermission(Auth::user())) {
$hide_form = new UOJForm('hide');
$hide_form->addHidden('comment_hide_id', '', 'validateCommentId', null);
$hide_form->addSelect('comment_hide_type', [
'label' => '隐藏理由',
'options' => UOJBlogComment::HIDE_REASONS,
'default_value' => 'spam',
]);
$hide_form->addInput('comment_hide_reason', [
'div_class' => 'mt-3',
'label' => '自定义隐藏理由',
'default_value' => '该评论由于违反社区规定,已被管理员隐藏',
'validator_php' => 'validateString',
]);
$hide_form->handle = function (&$vdata) {
if ($_POST['comment_hide_type'] == 'unhide') {
$reason = '';
} else if ($_POST['comment_hide_type'] == 'other') {
$reason = $_POST['comment_hide_reason'];
} else {
$reason = '该评论由于' . UOJBlogComment::HIDE_REASONS[$_POST['comment_hide_type']] . ',已被管理员隐藏';
}
$vdata['comment_hide_id']->hide($reason);
};
$hide_form->runAtServer();
}
$comments_pag = new Paginator([
'col_names' => ['*'],
'table_name' => 'blogs_comments',
@ -170,9 +200,38 @@ $comments_pag = new Paginator([
'page_len' => 20
]);
?>
<?php echoUOJPageHeader(HTML::stripTags($blog['title']) . ' - 博客') ?>
<script>
var user_can_hide_comment = <?= json_encode(isset($hide_form)) ?>;
</script>
<?php UOJBlog::cur()->echoView(['show_title_only' => isset($_GET['page']) && $_GET['page'] != 1]) ?>
<?php if (isset($hide_form)) : ?>
<div class="modal fade" id="HideCommentModal" tabindex="-1" aria-labelledby="HideCommentModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="HideCommentModalLabel">隐藏评论</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<div class="mb-2">原评论ID: <span id="span-comment_hide_id"></span></div>
<blockquote id="HideCommentModalOriginalComment" class="border-start border-3 ps-3 text-muted"></blockquote>
</div>
<hr>
<?php $hide_form->printHTML(); ?>
</div>
</div>
</div>
</div>
<?php endif ?>
<h2>
评论
<i class="bi bi-chat-fill"></i>
@ -216,13 +275,20 @@ $comments_pag = new Paginator([
<?= ClickZans::getBlock('BC', $comment['id'], $comment['zan']) ?>
</div>
</div>
<div class="comment-content my-2"><?= $comment['content'] ?></div>
<div class="comment-content my-2" id="comment-content-<?= $comment['id'] ?>"><?= getCommentContentToDisplay($comment) ?></div>
<ul class="list-inline mb-0 text-end">
<li class="list-inline-item small text-muted">
<?= $comment['post_time'] ?>
</li>
<?php if (isset($hide_form)) : ?>
<li class="list-inline-item">
<a href="#" class="text-warning-emphasis text-decoration-none p-0 uoj-blog-hide-comment-btn" data-comment-id="<?= $comment['id'] ?>">
隐藏
</a>
</li>
<?php endif ?>
<li class="list-inline-item">
<a class="text-decoration-none" id="reply-to-<?= $comment['id'] ?>" href="#">
<a id="reply-to-<?= $comment['id'] ?>" href="#">
回复
</a>
</li>
@ -249,4 +315,14 @@ $comments_pag = new Paginator([
<?php $reply_form->printHTML() ?>
</div>
<script>
$('.uoj-blog-hide-comment-btn').each(function() {
$(this).click(function() {
var comment_id = $(this).data('comment-id');
toggleModalHideComment(comment_id, $('#comment-content-' + comment_id).html());
});
})
</script>
<?php echoUOJPageFooter() ?>

View File

@ -75,8 +75,8 @@ function validateURL($url) {
return filter_var($url, FILTER_VALIDATE_URL) !== false;
}
function validateString($str) {
return preg_match('/[^0-9a-zA-Z]/', $str) !== true;
function validateString($x) {
return is_string($x) ? '' : '不合法的字符串';
}
function validateGitHubUsername($username) {
@ -95,6 +95,20 @@ function validateUserAndStoreByUsername($username, &$vdata) {
return '';
}
function validateCommentId($id) {
if (!validateUInt($id)) {
return 'ID 不合法';
}
$comment = UOJBlogComment::query($id);
if (!$comment) {
return '评论不存在';
}
return ['error' => '', 'store' => $comment];
}
function is_short_string($str) {
return is_string($str) && strlen($str) <= 256;
}

View File

@ -3,13 +3,22 @@
class UOJBlogComment {
use UOJDataTrait;
const HIDE_REASONS = [
'unhide' => '解除隐藏',
'spam' => '疑似为垃圾信息',
'garbage' => '疑似为无意义的乱码',
'insult' => '包含不和谐内容',
'violate' => '违反法律法规',
'other' => '其他(请在下方说明)',
];
public static function query($id) {
if (!isset($id) || !validateUInt($id)) {
return null;
}
$info = DB::selectFirst([
"select * from blogs_comments",
"where", ['id' => $id]
"where", ['id' => $id]
]);
if (!$info) {
return null;
@ -23,12 +32,12 @@ class UOJBlogComment {
public function hide($reason) {
DB::update([
"update blogs_comments",
"set", [
'is_hidden' => ($reason !== ''),
'reason_to_hide' => $reason
],
"where", ['id' => $this->info['id']]
"update blogs_comments",
"set", [
'is_hidden' => ($reason !== ''),
'reason_to_hide' => $reason
],
"where", ['id' => $this->info['id']]
]);
$blog = UOJBlog::query($this->info['blog_id']);

View File

@ -33,6 +33,14 @@ class UOJUserBlog {
return self::$user['username'] === $user['username'];
}
public static function userHasManagePermission(?array $user) {
if ($user === null) {
return false;
}
return isSuperUser($user) || UOJUser::checkPermission($user, 'blogs.manage');
}
public static function userCanManage(?array $user, ?string $whose_blog = null) {
if ($whose_blog === null) {
$whose_blog = self::id();

View File

@ -1577,6 +1577,14 @@ function custom_test_onsubmit(response_text, div_result, url) {
setTimeout(update, 500);
}
// hide comment
function toggleModalHideComment(id, content) {
$('#input-comment_hide_id').val(id);
$('#span-comment_hide_id').text(id);
$('#HideCommentModalOriginalComment').html(content);
$('#HideCommentModal').modal('show');
}
// comment
function showCommentReplies(id, replies) {
var toggleFormReply = function(from, text) {
@ -1596,7 +1604,6 @@ function showCommentReplies(id, replies) {
$(r).val(text).focus();
});
});
} else if ($(q).css('display') != 'none') {
$(q).appendTo(p).hide('fast');
} else {
@ -1629,6 +1636,14 @@ function showCommentReplies(id, replies) {
).append(
$('<ul class="text-end mb-0 list-inline" />').append(
'<li class="list-inline-item small text-muted">' + reply.post_time + '</li>'
).append(
user_can_hide_comment
? $('<li class="list-inline-item" />').append(
$('<a href="#" class="text-warning-emphasis text-decoration-none p-0" />').data('comment-id', reply.id).text('隐藏').click(function() {
toggleModalHideComment(reply.id, reply.content);
})
)
: ''
).append(
$('<li class="list-inline-item" />').append(
$('<a href="#">回复</a>').click(function (e) {