prepare("SELECT t.*, f.name AS fname, f.is_locked AS flocked FROM topics t JOIN forums f ON f.id=t.forum_id WHERE t.id=?"); $s->execute([$tid]); $t = $s->fetch(); if (!$t) bail('Topic', 'No such topic.', '/forum.php'); $locked = $t['is_locked'] || $t['flocked']; // reply / delete post $err = ''; if ($_SERVER['REQUEST_METHOD'] === 'POST') { $me = require_login(); require_csrf(); $act = $_POST['act'] ?? 'reply'; if ($act === 'delpost' && $me['is_admin']) { db()->prepare("DELETE FROM posts WHERE id=? AND topic_id=?") ->execute([(int)($_POST['pid'] ?? 0), $tid]); redirect('/topic.php', ['t' => $tid]); } if ($locked && !$me['is_admin']) bail('Topic', 'Topic is locked.', '/forum.php'); $body = trim((string)($_POST['body'] ?? '')); if ($body === '') { $err = 'Message cannot be empty.'; } else { $now = time(); db()->prepare("INSERT INTO posts (topic_id,user_id,body,created_at) VALUES (?,?,?,?)") ->execute([$tid, $me['id'], mb_substr($body, 0, 4000), $now]); db()->prepare("UPDATE topics SET bumped_at=? WHERE id=?")->execute([$now, $tid]); // jump to the last page $c = db()->prepare("SELECT COUNT(*) FROM posts WHERE topic_id=?"); $c->execute([$tid]); $last = max(1, (int)ceil(((int)$c->fetchColumn()) / PER_PAGE)); redirect('/topic.php', ['t' => $tid, 'p' => $last]); } } $page = max(1, (int)($_GET['p'] ?? 1)); $off = ($page - 1) * PER_PAGE; $s = db()->prepare("SELECT p.*, u.username FROM posts p LEFT JOIN users u ON u.id=p.user_id WHERE p.topic_id=? ORDER BY p.id LIMIT ? OFFSET ?"); $s->execute([$tid, PER_PAGE + 1, $off]); $rows = $s->fetchAll(); $more = count($rows) > PER_PAGE; if ($more) array_pop($rows); page_start($t['title'], ['back' => '/forum.php?f=' . $t['forum_id']]); if ($err) p_err($err); p_para('In ' . $t['fname'] . ($locked ? ' [locked]' : '')); p_rule(); foreach ($rows as $r) { p_para('-- ' . ($r['username'] ?? '[deleted]') . ', ' . ago((int)$r['created_at']) . ' ago:'); p_para(wtrim($r['body'])); if ($me && $me['is_admin']) { p_form('/topic.php?t=' . $tid, [ ['name' => 'act', 'type' => 'hidden', 'value' => 'delpost'], ['name' => 'pid', 'type' => 'hidden', 'value' => (string)$r['id']], ], 'Del post'); } p_rule(); } p_pager('/topic.php', $page, $more, ['t' => $tid]); if ($me && (!$locked || $me['is_admin'])) { p_para('Reply:'); p_form('/topic.php?t=' . $tid, [ ['name' => 'body', 'label' => 'Message', 'type' => is_wml() ? 'text' : 'textarea', 'maxlength' => is_wml() ? 200 : 4000], ], 'Reply'); } elseif (!$me) { p_links([['/login.php', 'Log in to reply']]); } p_links([ ['/forum.php', 'Back to ' . $t['fname'], ['f' => $t['forum_id']]], ['/forum.php', 'All forums'], ['/index.php', 'Home'], ]); page_end();