findById((int)$_GET['postid']); if (is_null($post)) { error(404); } if (!isset($_GET['threadid'])) { header("Location: {$post->location()}"); exit; } $thread = $post->thread(); } elseif (isset($_GET['threadid'])) { $post = null; $thread = (new Gazelle\Manager\ForumThread())->findById((int)$_GET['threadid']); if (is_null($thread)) { error(404); } } else { error(404); } $threadId = $thread->id(); $forum = $thread->forum(); if (!$Viewer->readAccess($forum)) { error(403); } //Escape strings for later display $ForumName = display_str($forum->name()); $IsDonorForum = ($forum->id() == DONOR_FORUM); $PerPage = $Viewer->postsPerPage(); //Post links utilize the catalogue & key params to prevent issues with custom posts per page $PostNum = match (true) { isset($_GET['post']) => (int)$_GET['post'], $post && !$post->isPinned() => $post->priorPostTotal(), default => 1, }; $Page = max(1, (int)($_GET['page'] ?? (int)ceil(min($thread->postTotal(), $PostNum) / $PerPage))); if (($Page - 1) * $PerPage > $thread->postTotal()) { $Page = (int)ceil($thread->postTotal() / $PerPage); } $slice = $thread->slice(perPage: $PerPage, page: $Page); $paginator = new Gazelle\Util\Paginator($PerPage, $Page); $paginator->setTotal($thread->postTotal()); $firstOnPage = current($slice)['ID'] ?? 0; $lastOnPage = count($slice) ? end($slice)['ID'] : 0; if ($lastOnPage <= $thread->pinnedPostId() && $thread->postTotal() <= $PerPage * $Page) { $lastOnPage = $thread->pinnedPostId(); } $quote = new Gazelle\User\Quote($Viewer); if ($quote->unreadTotal()) { $quote->clearThread($threadId, $firstOnPage, $lastOnPage); } $lastRead = $thread->userLastReadPost($Viewer); if ($lastRead < $lastOnPage) { $thread->catchup($Viewer, $lastOnPage); } $isSubscribed = (new Gazelle\User\Subscription($Viewer))->isSubscribed($threadId); if ($isSubscribed) { $Cache->delete_value('subscriptions_user_new_' . $Viewer->id()); } $userMan = new Gazelle\Manager\User(); $avatarFilter = Gazelle\Util\Twig::factory()->createTemplate('{{ user|avatar(viewer)|raw }}'); $transitions = (new Gazelle\Manager\ForumTransition())->threadTransitionList($Viewer, $thread); $department = $forum->departmentList($Viewer); $auth = $Viewer->auth(); View::show_header("Forums › $ForumName › {$thread->title()}", ['js' => 'comments,subscriptions,bbcode' . ($IsDonorForum ? ',donor_titles' : '')] ); echo $Twig->render('forum/thread-header.twig', [ 'is_subbed' => $isSubscribed, 'paginator' => $paginator, 'thread' => $thread, 'transition_list' => $transitions, 'viewer' => $Viewer, ]); echo $Twig->render('forum/poll.twig', [ 'poll' => $thread->hasPoll() ? new Gazelle\ForumPoll($threadId) : false, 'user_man' => $userMan, 'viewer' => $Viewer, ]); // Squeeze in stickypost if ($thread->pinnedPostId()) { if (!$slice) { $slice = [$thread->pinnedPostInfo()]; } else { if ($thread->pinnedPostId() != current($slice)['ID']) { array_unshift($slice, $thread->pinnedPostInfo()); } if ($thread->pinnedPostId() != $slice[count($slice) - 1]['ID']) { $slice[] = $thread->pinnedPostInfo(); } } } // Enable TOC Text::$TOC = true; foreach ($slice as $Key => $Post) { [$PostID, $AuthorID, $AddedTime, $Body, $EditedUserID, $EditedTime] = array_values($Post); $author = new Gazelle\User($AuthorID); $tableClass = ['forum_post', 'wrap_overflow', 'box vertical_margin']; if ( (!$thread->isLocked() || $thread->isPinned()) && $PostID > $lastRead && strtotime($AddedTime) > $Viewer->forumCatchupEpoch() ) { $tableClass[] = 'forum_unread'; } if (!$Viewer->showAvatars()) { $tableClass[] = 'noavatar'; } if ($AuthorID == $thread->authorId()) { $tableClass[] = 'important_user'; } if ($PostID == $thread->pinnedPostId()) { $tableClass[] = 'sticky_post'; } ?> showAvatars()) { ?> showAvatars()) { ?>
# isLocked() && !$Viewer->disablePosting()) { ?> - Quote isLocked() && $Viewer->writeAccess($forum) && $AuthorID == $Viewer->id()) && !$Viewer->disablePosting() || $Viewer->permitted('site_moderate_forums')) { ?> - Edit permitted('site_forum_post_delete') && $thread->postTotal() > 1) { ?> - Delete pinnedPostId()) { ?> permitted('site_moderate_forums')) { ?> - X permitted('site_moderate_forums')) { ?> - 📌 Report permitted('users_warn') && $Viewer->id() != $AuthorID && $Viewer->classLevel() >= $author->classLevel()) { ?> - Warn   ↑
render(['user' => $author, 'viewer' => $Viewer]) ?> showAvatars()) { echo ' colspan="2"'; } ?>>


permitted('site_admin_forums')) { ?> « Last edited by
linkbox(); $lastPost = end($slice); if ($Viewer->permitted('site_moderate_forums') || ($Viewer->writeAccess($forum) && !$thread->isLocked())) { echo $Twig->render('reply.twig', [ 'action' => 'reply', 'forum' => $forum->id(), 'id' => $threadId, 'merge' => strtotime($lastPost['AddedTime']) > time() - 3600 && $lastPost['AuthorID'] == $Viewer->id(), 'name' => 'threadid', 'subbed' => $isSubscribed, 'textarea' => (new Gazelle\Util\Textarea('quickpost', '', 90, 8))->setPreviewManual(true), 'userMan' => $userMan, 'viewer' => $Viewer, ]); } echo $Twig->render('forum/thread-footer.twig', [ 'forum_list' => $forumMan->forumList(), 'page' => $Page, 'thread' => $thread, 'transition_list' => $transitions, 'viewer' => $Viewer, ]);