Improved handling of soft deleted comments.

This commit is contained in:
flash 2018-12-15 23:15:35 +01:00
parent 0eff566259
commit 8fa8eaa1f9
5 changed files with 75 additions and 32 deletions

View file

@ -13,6 +13,15 @@
display: none;
}
&--deleted > &__container {
opacity: .5;
transition: opacity .2s;
&:hover {
opacity: .9;
}
}
&__container {
display: flex;
margin-bottom: 3px;
@ -123,10 +132,6 @@
font: 12px/20px @mio-font-regular;
margin-right: 1px;
}
&--deleted {
font-style: italic;
}
}
&__user {

View file

@ -114,6 +114,48 @@ switch ($_GET['m'] ?? null) {
]);
break;
case 'restore':
if (!$commentPerms['can_delete_any']) {
echo render_info_or_json($isXHR, "You're not allowed to restore deleted comments.", 403);
break;
}
$comment = (int)($_GET['c'] ?? 0);
$commentInfo = comments_post_get($comment, false);
if (!$commentInfo) {
echo render_info_or_json($isXHR, "This comment doesn't exist.", 400);
break;
}
$currentUserId = user_session_current('user_id', 0);
if ($commentInfo['comment_deleted'] === null) {
echo render_info_or_json($isXHR, "This comment isn't in a deleted state.", 400);
break;
}
if (!comments_post_delete($comment, false)) {
echo render_info_or_json($isXHR, 'Failed to restore comment.', 500);
break;
}
audit_log(MSZ_AUDIT_COMMENT_ENTRY_RESTORE, $currentUserId, [
$comment,
(int)($commentInfo['user_id'] ?? 0),
$commentInfo['username'] ?? '(Deleted User)',
]);
if ($redirect) {
header('Location: ' . $redirect . '#comment-' . $comment);
break;
}
echo json_encode([
'id' => $comment,
]);
break;
case 'create':
if (!$commentPerms['can_comment']) {
echo render_info_or_json($isXHR, "You're not allowed to post comments.", 403);

View file

@ -14,6 +14,7 @@ define('MSZ_AUDIT_CHANGELOG_ACTION_CREATE', 'CHANGELOG_ACTION_CREATE');
define('MSZ_AUDIT_CHANGELOG_ACTION_EDIT', 'CHANGELOG_ACTION_EDIT');
define('MSZ_AUDIT_COMMENT_ENTRY_DELETE', 'COMMENT_ENTRY_DELETE');
define('MSZ_AUDIT_COMMENT_ENTRY_DELETE_MOD', 'COMMENT_ENTRY_DELETE_MOD');
define('MSZ_AUDIT_COMMENT_ENTRY_RESTORE', 'COMMENT_ENTRY_RESTORE');
define('MSZ_AUDIT_NEWS_POST_CREATE', 'NEWS_POST_CREATE');
define('MSZ_AUDIT_NEWS_POST_EDIT', 'NEWS_POST_EDIT');
define('MSZ_AUDIT_NEWS_CATEGORY_CREATE', 'NEWS_CATEGORY_CREATE');
@ -36,6 +37,7 @@ define('MSZ_AUDIT_LOG_STRINGS', [
MSZ_AUDIT_CHANGELOG_ACTION_EDIT => 'Edited changelog action #%d.',
MSZ_AUDIT_COMMENT_ENTRY_DELETE => 'Deleted comment #%d.',
MSZ_AUDIT_COMMENT_ENTRY_DELETE_MOD => 'Deleted comment #%d by user #%d %s.',
MSZ_AUDIT_COMMENT_ENTRY_RESTORE => 'Restored comment #%d by user #%d %s.',
MSZ_AUDIT_NEWS_POST_CREATE => 'Created news post #%d.',
MSZ_AUDIT_NEWS_POST_EDIT => 'Edited news post #%d.',
MSZ_AUDIT_NEWS_CATEGORY_CREATE => 'Created news category #%d.',

View file

@ -213,29 +213,22 @@ define('MSZ_COMMENTS_CATEGORY_QUERY', '
LEFT JOIN `msz_roles` as r
ON r.`role_id` = u.`display_role`
WHERE p.`category_id` = :category
AND p.`comment_deleted` IS NULL
%s
ORDER BY p.`comment_pinned` DESC, p.`comment_id` %s
%1$s
ORDER BY p.`comment_deleted` ASC, p.`comment_pinned` DESC, p.`comment_id` %2$s
');
define('MSZ_COMMENTS_CATEGORY_QUERY_ROOT', sprintf(
MSZ_COMMENTS_CATEGORY_QUERY,
'AND p.`comment_reply_to` IS NULL',
'DESC'
));
define('MSZ_COMMENTS_CATEGORY_QUERY_REPLIES', sprintf(
MSZ_COMMENTS_CATEGORY_QUERY,
'AND p.`comment_reply_to` = :parent',
'ASC'
));
// heavily recursive
// The $parent param should never be used outside of this function itself and should always remain the last of the list.
function comments_category_get(int $category, int $user, ?int $parent = null): array
{
if ($parent !== null) {
$getComments = db_prepare(MSZ_COMMENTS_CATEGORY_QUERY_REPLIES);
$isParent = $parent === null;
$getComments = db_prepare(sprintf(
MSZ_COMMENTS_CATEGORY_QUERY,
$isParent ? 'AND p.`comment_reply_to` IS NULL' : 'AND p.`comment_reply_to` = :parent',
$isParent ? 'DESC' : 'ASC'
));
if (!$isParent) {
$getComments->bindValue('parent', $parent);
} else {
$getComments = db_prepare(MSZ_COMMENTS_CATEGORY_QUERY_ROOT);
}
$getComments->bindValue('user', $user);

View file

@ -42,8 +42,8 @@
{% macro comments_entry(comment, indent, category, user, perms) %}
{% from '_layout/input.twig' import input_checkbox_raw %}
{% if comment.comment_deleted is null or comment.comment_replies|length > 0 %}
<div class="comment" id="comment-{{ comment.comment_id }}">
{% if perms.can_delete_any or (comment.comment_deleted is null or comment.comment_replies|length > 0) %}
<div class="comment{% if comment.comment_deleted is not null %} comment--deleted{% endif %}" id="comment-{{ comment.comment_id }}">
<div class="comment__container">
<a class="avatar comment__avatar"
href="/profile.php?u={{ comment.user_id }}"
@ -73,11 +73,11 @@
{% endspaceless %}</span>
{% endif %}
</div>
<div class="comment__text{{ comment.comment_deleted is null ? '' : ' comment__text--deleted' }}">
{{ comment.comment_deleted is null ? (comment.comment_html is defined ? comment.comment_html|raw : comment.comment_text|nl2br) : 'deleted' }}
<div class="comment__text">
{{ comment.comment_deleted is null or perms.can_delete_any ? (comment.comment_html is defined ? comment.comment_html|raw : comment.comment_text|nl2br) : '(deleted)' }}
</div>
{% if comment.comment_deleted is null and user is not null %}
<div class="comment__actions">
<div class="comment__actions">
{% if comment.comment_deleted is null and user is not null %}
{% if perms.can_vote %}
<a class="comment__action comment__action--link comment__action--vote comment__action--like{% if comment.comment_user_vote == 'Like' %} comment__action--voted{% endif %}" data-comment-id="{{ comment.comment_id }}" data-comment-vote="{{ comment.comment_user_vote == 'Like' ? '0' : '1' }}"
href="/comments.php?m=vote&amp;c={{ comment.comment_id }}&amp;v={{ comment.comment_user_vote == 'Like' ? '0' : '1' }}&amp;csrf={{ csrf_token('comments') }}">
@ -100,14 +100,15 @@
<label class="comment__action comment__action--link" for="comment-reply-toggle-{{ comment.comment_id }}">Reply</label>
{% endif %}
{% if perms.can_delete_any or (comment.user_id == user.user_id and perms.can_delete) %}
<a class="comment__action comment__action--link comment__action--hide comment__action--delete" data-comment-id="{{ comment.comment_id }}"
href="/comments.php?m=delete&amp;c={{ comment.comment_id }}&amp;csrf={{ csrf_token('comments') }}">Delete</a>
<a class="comment__action comment__action--link comment__action--hide comment__action--delete" data-comment-id="{{ comment.comment_id }}" href="/comments.php?m=delete&amp;c={{ comment.comment_id }}&amp;csrf={{ csrf_token('comments') }}">Delete</a>
{% endif %}
{# if user is not null %}
<a class="comment__action comment__action--link comment__action--hide" href="#">Report</a>
{% endif #}
</div>
{% endif %}
{% elseif perms.can_delete_any %}
<a class="comment__action comment__action--link comment__action--restore" data-comment-id="{{ comment.comment_id }}" href="/comments.php?m=restore&amp;c={{ comment.comment_id }}&amp;csrf={{ csrf_token('comments') }}">Restore</a>
{% endif %}
</div>
</div>
</div>