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(); $forumId = $forum->id(); if (!$Viewer->readAccess($forum)) { error(403); } //Escape strings for later display $ForumName = display_str($forum->name()); $IsDonorForum = ($forumId == 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->isSticky() => $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->id()); if ($lastRead < $lastOnPage) { $thread->catchup($Viewer->id(), $lastOnPage); } $isSubscribed = (new Gazelle\User\Subscription($Viewer))->isSubscribed($threadId); if ($isSubscribed) { $Cache->delete_value('subscriptions_user_new_'.$Viewer->id()); } $userMan = new Gazelle\Manager\User; $transitions = $forumMan->threadTransitionList($Viewer, $forumId); $department = $forum->departmentList($Viewer); $auth = $Viewer->auth(); View::show_header("Forums › $ForumName › " . display_str($thread->title()), ['js' => 'comments,subscriptions,bbcode' . ($IsDonorForum ? ',donor' : '')] ); echo $Twig->render('forum/header-thread.twig', [ 'auth' => $auth, 'forum' => $forum, 'dept_list' => $forum->departmentList($Viewer), 'is_subbed' => $isSubscribed, 'paginator' => $paginator, 'thread_id' => $threadId, 'thread_title' => $thread->title(), 'transition' => $transitions, ]); if ($thread->hasPoll()) { $poll = new Gazelle\ForumPoll($threadId); $RevealVoters = $forum->hasRevealVotes(); $response = $poll->response($Viewer->id()); $answerList = $poll->vote(); if ($response > 0 || (!is_null($response) && $RevealVoters)) { $answerList[$response]['answer'] = '» ' . $answerList[$response]['answer']; } ?>
PollisClosed()) { echo ' [Closed]'; } ?>isFeatured()) { echo ' [Featured]'; } ?> View

question())?>

isClosed() || $thread->isLocked()) { ?>
Votes: total()) ?>


Voted: of total. (You may click on a choice to change your vote).
+
    $choice) { ?>


isStaff() && in_array($forumId, FORUM_REVEAL_VOTE)) { ?> +

permitted('forums_polls_moderate') && !$RevealVoters) { if (!$poll->isFeatured()) { ?>
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   ↑
avatarMarkup($Viewer, $author) ?> 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' => $forumId, '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, ]); } if (count($transitions)) { ?>
Move thread
permitted('site_moderate_forums')) { $Notes = $thread->threadNotes($threadId); ?>

Thread notes

Toggle

Edit thread

isPinned() ? '' : ' class="hidden"' ?>> permitted('site_admin_forums')) { ?>
isPinned()) { echo ' checked="checked"'; } ?> tabindex="4" />
isLocked()) { echo ' checked="checked"'; } ?> tabindex="6" />
permitted('site_moderate_forums') ?>