misuzu/public/forum/topic.php

311 lines
10 KiB
PHP
Raw Normal View History

2018-05-18 03:20:27 +02:00
<?php
namespace Misuzu;
2020-05-21 15:05:30 +00:00
use Misuzu\AuditLog;
use Misuzu\Forum\ForumTopic;
use Misuzu\Forum\ForumTopicNotFoundException;
use Misuzu\Forum\ForumPost;
use Misuzu\Forum\ForumPostNotFoundException;
2020-05-25 19:58:06 +00:00
use Misuzu\Users\User;
use Misuzu\Users\UserSession;
2020-05-21 15:05:30 +00:00
require_once '../../misuzu.php';
2018-05-18 03:20:27 +02:00
$postId = (int)filter_input(INPUT_GET, 'p', FILTER_SANITIZE_NUMBER_INT);
$topicId = (int)filter_input(INPUT_GET, 't', FILTER_SANITIZE_NUMBER_INT);
$moderationMode = (string)filter_input(INPUT_GET, 'm', FILTER_SANITIZE_STRING);
$submissionConfirmed = filter_input(INPUT_GET, 'confirm') === '1';
2018-05-20 22:12:45 +02:00
2020-05-25 19:58:06 +00:00
$topicUser = User::getCurrent();
2020-05-25 22:38:17 +00:00
$topicUserId = $topicUser === null ? 0 : $topicUser->getId();
if($topicId < 1 && $postId > 0)
try {
$postInfo = ForumPost::byId($postId);
$topicId = $postInfo->getTopicId();
} catch(ForumPostNotFoundException $ex) {
echo render_error(404);
return;
}
2018-05-20 22:12:45 +02:00
try {
$topicInfo = ForumTopic::byId($topicId);
} catch(ForumTopicNotFoundException $ex) {
echo render_error(404);
return;
}
$perms = forum_perms_get_user($topicInfo->getCategory()->getId(), $topicUserId)[MSZ_FORUM_PERMS_GENERAL];
2018-05-20 22:12:45 +02:00
2020-06-11 20:30:19 +00:00
if(isset($topicUser) && $topicUser->hasActiveWarning())
$perms &= ~MSZ_FORUM_PERM_SET_WRITE;
2019-01-12 00:00:53 +01:00
$canDeleteAny = perms_check($perms, MSZ_FORUM_PERM_DELETE_ANY_POST);
if($topicInfo->isDeleted() && !$canDeleteAny) {
echo render_error(404);
2018-05-20 22:12:45 +02:00
return;
}
2019-06-10 19:04:53 +02:00
if(!perms_check($perms, MSZ_FORUM_PERM_VIEW_FORUM)) {
echo render_error(403);
return;
}
$topicPostsTotal = $topicInfo->getActualPostCount(true);
$topicIsFrozen = $topicInfo->isArchived() || $topicInfo->isDeleted();
$canDeleteOwn = !$topicIsFrozen && !$topicInfo->isLocked() && perms_check($perms, MSZ_FORUM_PERM_DELETE_POST);
2019-01-12 00:00:53 +01:00
$canBumpTopic = !$topicIsFrozen && perms_check($perms, MSZ_FORUM_PERM_BUMP_TOPIC);
$canLockTopic = !$topicIsFrozen && perms_check($perms, MSZ_FORUM_PERM_LOCK_TOPIC);
$canNukeOrRestore = $canDeleteAny && $topicInfo->isDeleted();
$canDelete = !$topicInfo->isDeleted() && (
2019-01-12 00:00:53 +01:00
$canDeleteAny || (
$topicPostsTotal > 0
2020-10-21 00:58:36 +00:00
&& $topicPostsTotal <= ForumTopic::DELETE_POST_LIMIT
2019-01-12 00:00:53 +01:00
&& $canDeleteOwn
&& $topicInfo->getUserId() === $topicUserId
2019-01-12 00:00:53 +01:00
)
);
$validModerationModes = [
'delete', 'restore', 'nuke',
'bump', 'lock', 'unlock',
];
2019-06-10 17:21:53 +02:00
if(in_array($moderationMode, $validModerationModes, true)) {
2019-01-12 00:00:53 +01:00
$redirect = !empty($_SERVER['HTTP_REFERER']) && empty($_SERVER['HTTP_X_MISUZU_XHR']) ? $_SERVER['HTTP_REFERER'] : '';
$isXHR = !$redirect;
2019-06-10 17:21:53 +02:00
if($isXHR) {
2019-01-12 00:00:53 +01:00
header('Content-Type: application/json; charset=utf-8');
2019-06-10 17:21:53 +02:00
} elseif(!is_local_url($redirect)) {
2019-01-12 00:00:53 +01:00
echo render_info('Possible request forgery detected.', 403);
return;
}
2019-12-11 19:10:54 +01:00
if(!CSRF::validateRequest()) {
2019-01-12 00:00:53 +01:00
echo render_info_or_json($isXHR, "Couldn't verify this request, please refresh the page and try again.", 403);
return;
}
2019-12-11 19:10:54 +01:00
header(CSRF::header());
2019-01-12 00:00:53 +01:00
2020-05-25 19:58:06 +00:00
if(!UserSession::hasCurrent()) {
2019-01-12 00:00:53 +01:00
echo render_info_or_json($isXHR, 'You must be logged in to manage posts.', 401);
return;
}
if($topicUser->isBanned()) {
2019-01-12 00:00:53 +01:00
echo render_info_or_json($isXHR, 'You have been banned, check your profile for more information.', 403);
return;
}
if($topicUser->isSilenced()) {
2019-01-12 00:00:53 +01:00
echo render_info_or_json($isXHR, 'You have been silenced, check your profile for more information.', 403);
return;
}
2019-06-10 19:04:53 +02:00
switch($moderationMode) {
2019-01-12 00:00:53 +01:00
case 'delete':
2020-10-21 00:58:36 +00:00
$canDeleteCodes = [
'view' => 404,
'deleted' => 404,
'owner' => 403,
'age' => 403,
'permission' => 403,
'posts' => 403,
'' => 200,
];
$canDelete = $topicInfo->canBeDeleted($topicUser);
$canDeleteMsg = ForumTopic::canBeDeletedErrorString($canDelete);
2020-10-21 00:58:36 +00:00
$responseCode = $canDeleteCodes[$canDelete] ?? 500;
if($canDelete !== '') {
2019-06-10 19:04:53 +02:00
if($isXHR) {
2019-01-12 00:00:53 +01:00
http_response_code($responseCode);
echo json_encode([
'success' => false,
'topic_id' => $topicInfo->getId(),
2019-01-12 00:00:53 +01:00
'code' => $canDeleteCode,
'message' => $canDeleteMsg,
]);
break;
}
echo render_info($canDeleteMsg, $responseCode);
break;
}
2019-06-10 19:04:53 +02:00
if(!$isXHR) {
if(!isset($_GET['confirm'])) {
Template::render('forum.confirm', [
2019-01-12 00:00:53 +01:00
'title' => 'Confirm topic deletion',
'class' => 'far fa-trash-alt',
'message' => sprintf('You are about to delete topic #%d. Are you sure about that?', $topicInfo->getId()),
2019-01-12 00:00:53 +01:00
'params' => [
't' => $topicInfo->getId(),
2019-01-12 00:00:53 +01:00
'm' => 'delete',
],
]);
break;
2019-06-10 19:04:53 +02:00
} elseif(!$submissionConfirmed) {
url_redirect(
2019-06-02 00:44:01 +02:00
'forum-topic',
['topic' => $topicInfo->getId()]
);
2019-06-02 00:44:01 +02:00
break;
2019-01-12 00:00:53 +01:00
}
}
2020-10-21 00:58:36 +00:00
$topicInfo->delete();
AuditLog::create(AuditLog::FORUM_TOPIC_DELETE, [$topicInfo->getId()]);
2019-01-22 15:24:30 +01:00
2019-06-10 19:04:53 +02:00
if($isXHR) {
2019-01-12 00:00:53 +01:00
echo json_encode([
2020-10-21 00:58:36 +00:00
'success' => true,
'topic_id' => $topicInfo->getId(),
2020-10-21 00:58:36 +00:00
'message' => 'Topic deleted!',
2019-01-12 00:00:53 +01:00
]);
break;
}
url_redirect('forum-category', [
'forum' => $topicInfo->getCategoryId(),
]);
2019-01-12 00:00:53 +01:00
break;
case 'restore':
2019-06-10 19:04:53 +02:00
if(!$canNukeOrRestore) {
2019-01-12 00:00:53 +01:00
echo render_error(403);
break;
}
2019-06-10 19:04:53 +02:00
if(!$isXHR) {
if(!isset($_GET['confirm'])) {
Template::render('forum.confirm', [
2019-01-12 00:00:53 +01:00
'title' => 'Confirm topic restore',
'class' => 'fas fa-magic',
'message' => sprintf('You are about to restore topic #%d. Are you sure about that?', $topicInfo->getId()),
2019-01-12 00:00:53 +01:00
'params' => [
't' => $topicInfo->getId(),
2019-01-12 00:00:53 +01:00
'm' => 'restore',
],
]);
break;
2019-06-10 19:04:53 +02:00
} elseif(!$submissionConfirmed) {
url_redirect('forum-topic', [
'topic' => $topicInfo->getId(),
]);
2019-06-02 00:44:01 +02:00
break;
2019-01-12 00:00:53 +01:00
}
}
2020-10-21 00:58:36 +00:00
$topicInfo->restore();
AuditLog::create(AuditLog::FORUM_TOPIC_RESTORE, [$topicInfo->getId()]);
2019-01-12 00:00:53 +01:00
http_response_code(204);
2019-06-10 19:04:53 +02:00
if(!$isXHR) {
url_redirect('forum-category', [
'forum' => $topicInfo->getCategoryId(),
]);
2019-01-12 00:00:53 +01:00
}
break;
case 'nuke':
2019-06-10 19:04:53 +02:00
if(!$canNukeOrRestore) {
2019-01-12 00:00:53 +01:00
echo render_error(403);
break;
}
2019-06-10 19:04:53 +02:00
if(!$isXHR) {
if(!isset($_GET['confirm'])) {
Template::render('forum.confirm', [
2019-01-12 00:00:53 +01:00
'title' => 'Confirm topic nuke',
'class' => 'fas fa-radiation',
'message' => sprintf('You are about to PERMANENTLY DELETE topic #%d. Are you sure about that?', $topicInfo->getId()),
2019-01-12 00:00:53 +01:00
'params' => [
't' => $topicInfo->getId(),
2019-01-12 00:00:53 +01:00
'm' => 'nuke',
],
]);
break;
2019-06-10 19:04:53 +02:00
} elseif(!$submissionConfirmed) {
url_redirect('forum-topic', [
'topic' => $topicInfo->getId(),
]);
2019-06-02 00:44:01 +02:00
break;
2019-01-12 00:00:53 +01:00
}
}
2020-10-21 00:58:36 +00:00
$topicInfo->nuke();
AuditLog::create(AuditLog::FORUM_TOPIC_NUKE, [$topicInfo->getId()]);
2019-01-12 00:00:53 +01:00
http_response_code(204);
2019-06-10 19:04:53 +02:00
if(!$isXHR) {
url_redirect('forum-category', [
'forum' => $topicInfo->getCategoryId(),
]);
2019-01-12 00:00:53 +01:00
}
break;
case 'bump':
2020-10-03 16:54:51 +00:00
if($canBumpTopic) {
$topicInfo->bumpTopic();
AuditLog::create(AuditLog::FORUM_TOPIC_BUMP, [$topicInfo->getId()]);
2019-01-12 00:00:53 +01:00
}
url_redirect('forum-topic', [
'topic' => $topicInfo->getId(),
]);
2019-01-12 00:00:53 +01:00
break;
case 'lock':
2020-10-03 16:54:51 +00:00
if($canLockTopic && !$topicInfo->isLocked()) {
$topicInfo->setLocked(true);
AuditLog::create(AuditLog::FORUM_TOPIC_LOCK, [$topicInfo->getId()]);
2019-01-12 00:00:53 +01:00
}
url_redirect('forum-topic', [
'topic' => $topicInfo->getId(),
]);
2019-01-12 00:00:53 +01:00
break;
case 'unlock':
2020-10-03 16:54:51 +00:00
if($canLockTopic && $topicInfo->isLocked()) {
$topicInfo->setLocked(false);
AuditLog::create(AuditLog::FORUM_TOPIC_UNLOCK, [$topicInfo->getId()]);
2019-01-12 00:00:53 +01:00
}
url_redirect('forum-topic', [
'topic' => $topicInfo->getId(),
]);
2019-01-12 00:00:53 +01:00
break;
}
return;
}
2020-10-05 09:59:10 +00:00
$topicPagination = new Pagination($topicInfo->getActualPostCount($canDeleteAny), \Misuzu\Forum\ForumPost::PER_PAGE, 'page');
2019-01-03 01:33:02 +01:00
if(isset($postInfo))
$topicPagination->setPage($postInfo->getTopicPage($canDeleteAny, $topicPagination->getRange()));
2019-01-03 01:33:02 +01:00
if(!$topicPagination->hasValidOffset()) {
2019-01-03 01:33:02 +01:00
echo render_error(404);
return;
}
$canReply = !$topicInfo->isArchived() && !$topicInfo->isLocked() && !$topicInfo->isDeleted() && perms_check($perms, MSZ_FORUM_PERM_CREATE_POST);
$topicInfo->markRead($topicUser);
Template::render('forum.topic', [
'topic_perms' => $perms,
'topic_info' => $topicInfo,
'can_reply' => $canReply,
2019-01-03 01:33:02 +01:00
'topic_pagination' => $topicPagination,
2019-01-12 00:00:53 +01:00
'topic_can_delete' => $canDelete,
'topic_can_view_deleted' => $canDeleteAny,
2019-01-12 00:00:53 +01:00
'topic_can_nuke_or_restore' => $canNukeOrRestore,
'topic_can_bump' => $canBumpTopic,
'topic_can_lock' => $canLockTopic,
2018-05-20 22:12:45 +02:00
]);