From 8569d2b65d5fd4e38f83eb805efdafb0dda1f1aa Mon Sep 17 00:00:00 2001 From: flashwave Date: Fri, 20 Dec 2024 00:29:14 +0000 Subject: [PATCH] Moved topic listing into the router. --- public-legacy/forum/topic.php | 174 ---------------------------- src/Forum/ForumCategoriesRoutes.php | 8 +- src/Forum/ForumPostsRoutes.php | 1 + src/Forum/ForumTopicsRoutes.php | 126 +++++++++++++++++++- src/LegacyRoutes.php | 15 ++- 5 files changed, 141 insertions(+), 183 deletions(-) delete mode 100644 public-legacy/forum/topic.php diff --git a/public-legacy/forum/topic.php b/public-legacy/forum/topic.php deleted file mode 100644 index 2d32148..0000000 --- a/public-legacy/forum/topic.php +++ /dev/null @@ -1,174 +0,0 @@ -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, -]); diff --git a/src/Forum/ForumCategoriesRoutes.php b/src/Forum/ForumCategoriesRoutes.php index 148c7fe..3470885 100644 --- a/src/Forum/ForumCategoriesRoutes.php +++ b/src/Forum/ForumCategoriesRoutes.php @@ -314,10 +314,6 @@ class ForumCategoriesRoutes implements RouteHandler, UrlSource { } } - $perms = $perms->checkMany([ - 'can_create_topic' => Perm::F_TOPIC_CREATE, - ]); - return Template::renderRaw('forum.forum', [ 'forum_breadcrumbs' => iterator_to_array($this->forum->categories->getCategoryAncestry($category)), 'global_accent_colour' => $this->forum->categories->getCategoryColour($category), @@ -326,7 +322,9 @@ class ForumCategoriesRoutes implements RouteHandler, UrlSource { 'forum_topics' => $topics, 'forum_pagination' => $pagination, 'forum_show_mark_as_read' => $this->authInfo->isLoggedIn, - 'forum_perms' => $perms, + 'forum_perms' => $perms->checkMany([ + 'can_create_topic' => Perm::F_TOPIC_CREATE, + ]), ]); } diff --git a/src/Forum/ForumPostsRoutes.php b/src/Forum/ForumPostsRoutes.php index a841db5..216ca6a 100644 --- a/src/Forum/ForumPostsRoutes.php +++ b/src/Forum/ForumPostsRoutes.php @@ -22,6 +22,7 @@ class ForumPostsRoutes implements RouteHandler, UrlSource { ) {} #[HttpGet('/forum/posts/([0-9]+)')] + #[UrlFormat('forum-post', '/forum/posts/')] public function getPost(HttpResponseBuilder $response, HttpRequest $request, string $postId) { try { $post = $this->forum->posts->getPost(postId: $postId); diff --git a/src/Forum/ForumTopicsRoutes.php b/src/Forum/ForumTopicsRoutes.php index 96ee786..b18b59f 100644 --- a/src/Forum/ForumTopicsRoutes.php +++ b/src/Forum/ForumTopicsRoutes.php @@ -1,11 +1,12 @@ ', ['page' => ''], '')] public function getTopic(HttpResponseBuilder $response, HttpRequest $request, string $topicId) { - $response->redirect($this->urls->format('forum-topic', ['topic' => $topicId])); + try { + $isNuked = $deleted = $canDeleteAny = false; + $topic = $this->forum->topics->getTopic(topicId: $topicId); + } catch(RuntimeException $ex) { + $isNuked = true; + } + + if(!$isNuked) { + $deleted = $topic->deleted; + + $perms = $this->authInfo->getPerms('forum', $topic->categoryId); + if($this->usersCtx->hasActiveBan($this->authInfo->userInfo)) + $perms = $perms->apply(fn($calc) => $calc & (Perm::F_CATEGORY_LIST | Perm::F_CATEGORY_VIEW)); + + $canDeleteAny = $perms->check(Perm::F_POST_DELETE_ANY); + } + + if($isNuked || $deleted) { + if($this->forum->topicRedirects->hasTopicRedirect($topicId)) { + $redirect = $this->forum->topicRedirects->getTopicRedirect($topicId); + Template::set('topic_redir_info', $redirect); + + if($isNuked || !$canDeleteAny) { + $response->redirect($redirect->linkTarget); + return; + } + } + + if(empty($redirect) && !$canDeleteAny) + return 404; + } + + if(!$perms->check(Perm::F_CATEGORY_VIEW)) + return 403; + + $postsCount = $topic->postsCount; + if($canDeleteAny) + $postsCount += $topic->deletedPostsCount; + + $pagination = Pagination::fromRequest($request, $postsCount, 10); + if(!$pagination->validOffset) + return 404; + + // Maximum amount of posts a topic may contain to still be deletable by the author + // this should be in the config + $deletePostThreshold = 1; + + $categoryInfo = $this->forum->categories->getCategory(topicInfo: $topic); + $isFrozen = $categoryInfo->archived || $deleted; + $canDeleteOwn = !$isFrozen && !$topic->locked && $perms->check(Perm::F_POST_DELETE_OWN); + $canBump = !$isFrozen && $perms->check(Perm::F_TOPIC_BUMP); + $canLock = !$isFrozen && $perms->check(Perm::F_TOPIC_LOCK); + $canNukeOrRestore = $canDeleteAny && $deleted; + $canReply = !$isFrozen && !$topic->locked && $perms->check(Perm::F_POST_CREATE); + $canDelete = !$deleted && ( + $canDeleteAny || ( + $topic->totalPostsCount > 0 + && $topic->totalPostsCount <= $deletePostThreshold + && $canDeleteOwn + && $topic->userId === $this->authInfo->userId + ) + ); + + $postInfos = $this->forum->posts->getPosts( + topicInfo: $topic, + deleted: $perms->check(Perm::F_POST_DELETE_ANY) ? null : false, + pagination: $pagination, + ); + if(empty($postInfos)) + return 404; + + try { + $originalPostInfo = $this->forum->posts->getPost(topicInfo: $topic); + } catch(RuntimeException $ex) { + return 404; + } + + $posts = []; + + foreach($postInfos as $postInfo) { + $posts[] = $post = new stdClass; + $post->info = $postInfo; + + if($postInfo->userId !== null) { + $post->user = $this->usersCtx->getUserInfo($postInfo->userId); + $post->colour = $this->usersCtx->getUserColour($post->user); + $post->postsCount = $this->forum->countTotalUserPosts($post->user); + } + + $post->isOriginalPost = $originalPostInfo->id == $postInfo->id; + $post->isOriginalPoster = $originalPostInfo->userId !== null && $postInfo->userId !== null + && $originalPostInfo->userId === $postInfo->userId; + } + + if(!$this->forum->topics->checkUserHasReadTopic($this->authInfo->userInfo, $topic)) + $this->forum->topics->incrementTopicViews($topic); + + $this->forum->topics->updateUserReadTopic($this->authInfo->userInfo, $topic); + + return Template::renderRaw('forum.topic', [ + 'topic_breadcrumbs' => iterator_to_array($this->forum->categories->getCategoryAncestry($topic)), + 'global_accent_colour' => $this->forum->categories->getCategoryColour($topic), + 'topic_info' => $topic, + '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' => $canBump, + 'topic_can_lock' => $canLock, + 'topic_user_id' => $this->authInfo->userId, + 'topic_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, + ]), + ]); } #[HttpDelete('/forum/topics/([0-9]+)')] diff --git a/src/LegacyRoutes.php b/src/LegacyRoutes.php index e35fdce..49cd128 100644 --- a/src/LegacyRoutes.php +++ b/src/LegacyRoutes.php @@ -32,9 +32,7 @@ class LegacyRoutes implements RouteHandler, UrlSource { $urls->register('forum-leaderboard', '/forum/leaderboard.php', ['id' => '', 'mode' => '']); $urls->register('forum-topic-new', '/forum/posting.php', ['f' => '']); $urls->register('forum-reply-new', '/forum/posting.php', ['t' => '']); - $urls->register('forum-topic', '/forum/topic.php', ['t' => '', 'page' => ''], ''); $urls->register('forum-topic-create', '/forum/posting.php', ['f' => '']); - $urls->register('forum-post', '/forum/topic.php', ['p' => ''], 'p'); $urls->register('forum-post-create', '/forum/posting.php', ['t' => '']); $urls->register('forum-post-quote', '/forum/posting.php', ['q' => '']); $urls->register('forum-post-edit', '/forum/posting.php', ['p' => '', 'm' => 'edit']); @@ -195,6 +193,19 @@ class LegacyRoutes implements RouteHandler, UrlSource { ]), true); } + #[HttpGet('/forum/topic.php')] + public function getForumTopicPHP(HttpResponseBuilder $response, HttpRequest $request): void { + if($request->hasParam('p')) + $response->redirect($this->urls->format('forum-post', [ + 'post' => $request->getParam('p', FILTER_SANITIZE_NUMBER_INT), + ]), true); + else + $response->redirect($this->urls->format('forum-topic', [ + 'topic' => $request->getParam('t', FILTER_SANITIZE_NUMBER_INT), + 'page' => $request->getParam('page', FILTER_SANITIZE_NUMBER_INT), + ]), true); + } + #[HttpGet('/forum/post.php')] public function getForumPostPHP(HttpResponseBuilder $response, HttpRequest $request): void { $response->redirect($this->urls->format('forum-post', [