174 lines
5.8 KiB
PHP
174 lines
5.8 KiB
PHP
<?php
|
|
namespace Misuzu;
|
|
|
|
use stdClass;
|
|
use RuntimeException;
|
|
|
|
if(!isset($msz) || !($msz instanceof \Misuzu\MisuzuContext))
|
|
die('Script must be called through the Misuzu route dispatcher.');
|
|
|
|
$postId = !empty($_GET['p']) && is_string($_GET['p']) ? (int)$_GET['p'] : 0;
|
|
$topicId = !empty($_GET['t']) && is_string($_GET['t']) ? (int)$_GET['t'] : 0;
|
|
$categoryId = null;
|
|
|
|
$currentUser = $msz->authInfo->userInfo;
|
|
$currentUserId = $currentUser === null ? '0' : $currentUser->id;
|
|
|
|
if($topicId < 1 && $postId > 0) {
|
|
try {
|
|
$postInfo = $msz->forumCtx->posts->getPost(postId: (string)$postId);
|
|
} catch(RuntimeException $ex) {
|
|
Template::throwError(404);
|
|
}
|
|
|
|
$categoryId = (int)$postInfo->categoryId;
|
|
$perms = $msz->authInfo->getPerms('forum', $postInfo->categoryId);
|
|
$canDeleteAny = $perms->check(Perm::F_POST_DELETE_ANY);
|
|
|
|
if($postInfo->deleted && !$canDeleteAny)
|
|
Template::throwError(404);
|
|
|
|
$topicId = $postInfo->topicId;
|
|
$preceedingPostCount = $msz->forumCtx->posts->countPosts(
|
|
topicInfo: $topicId,
|
|
upToPostInfo: $postInfo,
|
|
deleted: $canDeleteAny ? null : false
|
|
);
|
|
}
|
|
|
|
try {
|
|
$topicIsNuked = $topicIsDeleted = $canDeleteAny = false;
|
|
$topicInfo = $msz->forumCtx->topics->getTopic(topicId: $topicId);
|
|
} catch(RuntimeException $ex) {
|
|
$topicIsNuked = true;
|
|
}
|
|
|
|
if(!$topicIsNuked) {
|
|
$topicIsDeleted = $topicInfo->deleted;
|
|
|
|
if($categoryId !== (int)$topicInfo->categoryId) {
|
|
$categoryId = (int)$topicInfo->categoryId;
|
|
$perms = $msz->authInfo->getPerms('forum', $topicInfo->categoryId);
|
|
}
|
|
|
|
if($msz->usersCtx->hasActiveBan($currentUser))
|
|
$perms = $perms->apply(fn($calc) => $calc & (Perm::F_CATEGORY_LIST | Perm::F_CATEGORY_VIEW));
|
|
|
|
$canDeleteAny = $perms->check(Perm::F_POST_DELETE_ANY);
|
|
}
|
|
|
|
if($topicIsNuked || $topicIsDeleted) {
|
|
if($msz->forumCtx->topicRedirects->hasTopicRedirect($topicId)) {
|
|
$topicRedirectInfo = $msz->forumCtx->topicRedirects->getTopicRedirect($topicId);
|
|
Template::set('topic_redir_info', $topicRedirectInfo);
|
|
|
|
if($topicIsNuked || !$canDeleteAny) {
|
|
header('Location: ' . $topicRedirectInfo->linkTarget);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if(empty($topicRedirectInfo) && !$canDeleteAny)
|
|
Template::throwError(404);
|
|
}
|
|
|
|
if(!$perms->check(Perm::F_CATEGORY_VIEW))
|
|
Template::throwError(403);
|
|
|
|
// Maximum amount of posts a topic may contain to still be deletable by the author
|
|
// this should be in the config
|
|
$deletePostThreshold = 1;
|
|
|
|
$categoryInfo = $msz->forumCtx->categories->getCategory(topicInfo: $topicInfo);
|
|
$topicIsLocked = $topicInfo->locked;
|
|
$topicIsArchived = $categoryInfo->archived;
|
|
$topicPostsTotal = $topicInfo->totalPostsCount;
|
|
$topicIsFrozen = $topicIsArchived || $topicIsDeleted;
|
|
$canDeleteOwn = !$topicIsFrozen && !$topicIsLocked && $perms->check(Perm::F_POST_DELETE_OWN);
|
|
$canBumpTopic = !$topicIsFrozen && $perms->check(Perm::F_TOPIC_BUMP);
|
|
$canLockTopic = !$topicIsFrozen && $perms->check(Perm::F_TOPIC_LOCK);
|
|
$canNukeOrRestore = $canDeleteAny && $topicIsDeleted;
|
|
$canDelete = !$topicIsDeleted && (
|
|
$canDeleteAny || (
|
|
$topicPostsTotal > 0
|
|
&& $topicPostsTotal <= $deletePostThreshold
|
|
&& $canDeleteOwn
|
|
&& $topicInfo->userId === (string)$currentUserId
|
|
)
|
|
);
|
|
|
|
$topicPosts = $topicInfo->postsCount;
|
|
if($canDeleteAny)
|
|
$topicPosts += $topicInfo->deletedPostsCount;
|
|
|
|
if(isset($preceedingPostCount))
|
|
$pagination = Pagination::fromPage($topicPosts, (int)floor($preceedingPostCount / 10), 10, 0);
|
|
else
|
|
$pagination = Pagination::fromInput($topicPosts, 10, 'page');
|
|
|
|
if(!$pagination->validOffset)
|
|
Template::throwError(404);
|
|
|
|
$postInfos = $msz->forumCtx->posts->getPosts(
|
|
topicInfo: $topicInfo,
|
|
deleted: $perms->check(Perm::F_POST_DELETE_ANY) ? null : false,
|
|
pagination: $pagination,
|
|
);
|
|
|
|
if(empty($postInfos))
|
|
Template::throwError(404);
|
|
|
|
try {
|
|
$originalPostInfo = $msz->forumCtx->posts->getPost(topicInfo: $topicInfo);
|
|
} catch(RuntimeException $ex) {
|
|
Template::throwError(404);
|
|
}
|
|
|
|
$posts = [];
|
|
|
|
foreach($postInfos as $postInfo) {
|
|
$posts[] = $post = new stdClass;
|
|
$post->info = $postInfo;
|
|
|
|
if($postInfo->userId !== null) {
|
|
$post->user = $msz->usersCtx->getUserInfo($postInfo->userId);
|
|
$post->colour = $msz->usersCtx->getUserColour($post->user);
|
|
$post->postsCount = $msz->forumCtx->countTotalUserPosts($post->user);
|
|
}
|
|
|
|
$post->isOriginalPost = $originalPostInfo->id == $postInfo->id;
|
|
$post->isOriginalPoster = $originalPostInfo->userId !== null && $postInfo->userId !== null
|
|
&& $originalPostInfo->userId === $postInfo->userId;
|
|
}
|
|
|
|
$canReply = !$topicIsArchived && !$topicIsLocked && !$topicIsDeleted && $perms->check(Perm::F_POST_CREATE);
|
|
|
|
if(!$msz->forumCtx->topics->checkUserHasReadTopic($currentUser, $topicInfo))
|
|
$msz->forumCtx->topics->incrementTopicViews($topicInfo);
|
|
|
|
$msz->forumCtx->topics->updateUserReadTopic($currentUser, $topicInfo);
|
|
|
|
$perms = $perms->checkMany([
|
|
'can_create_post' => Perm::F_POST_CREATE,
|
|
'can_edit_post' => Perm::F_POST_EDIT_OWN,
|
|
'can_edit_any_post' => Perm::F_POST_EDIT_ANY,
|
|
'can_delete_post' => Perm::F_POST_DELETE_OWN,
|
|
'can_delete_any_post' => Perm::F_POST_DELETE_ANY,
|
|
]);
|
|
|
|
Template::render('forum.topic', [
|
|
'topic_breadcrumbs' => iterator_to_array($msz->forumCtx->categories->getCategoryAncestry($topicInfo)),
|
|
'global_accent_colour' => $msz->forumCtx->categories->getCategoryColour($topicInfo),
|
|
'topic_info' => $topicInfo,
|
|
'category_info' => $categoryInfo,
|
|
'topic_posts' => $posts,
|
|
'can_reply' => $canReply,
|
|
'topic_pagination' => $pagination,
|
|
'topic_can_delete' => $canDelete,
|
|
'topic_can_delete_any' => $canDeleteAny,
|
|
'topic_can_nuke_or_restore' => $canNukeOrRestore,
|
|
'topic_can_bump' => $canBumpTopic,
|
|
'topic_can_lock' => $canLockTopic,
|
|
'topic_user_id' => $currentUserId,
|
|
'topic_perms' => $perms,
|
|
]);
|