*/ class TopicController extends Controller { /** * Views a topic. * @param int $id * @throws HttpRouteNotFoundException * @return string */ public function view(int $id = 0): string { $topic = new Topic($id); $forum = new Forum($topic->forum); // Check if the forum exists if ($topic->id === 0 || !$forum->perms->view) { throw new HttpRouteNotFoundException; } $topic->trackUpdate(CurrentSession::$user->id); $topic->viewsUpdate(); return view('forum/topic', compact('forum', 'topic')); } /** * Checks if a user can moderate the topic. * @param int $id * @throws HttpRouteNotFoundException * @return array */ private function modBase(int $id): array { $topic = new Topic($id); $forum = new Forum($topic->forum); if ($topic->id !== 0 || $forum->perms->view || session_check()) { return compact('topic', 'forum'); } throw new HttpRouteNotFoundException; } /** * Sticky a topic. * @param int $id * @throws HttpMethodNotAllowedException * @return string */ public function sticky(int $id): string { extract($this->modBase($id)); if (!$forum->perms->changeType) { throw new HttpMethodNotAllowedException; } $topic->type = $topic->type !== 1 ? 1 : 0; $topic->update(); return redirect(route('forums.topic', $topic->id)); } /** * Announce a topic. * @param int $id * @throws HttpMethodNotAllowedException * @return string */ public function announce(int $id): string { extract($this->modBase($id)); if (!$forum->perms->changeType) { throw new HttpMethodNotAllowedException; } $topic->type = $topic->type !== 2 ? 2 : 0; $topic->update(); return redirect(route('forums.topic', $topic->id)); } /** * Lock a topic. * @param int $id * @throws HttpMethodNotAllowedException * @return string */ public function lock(int $id): string { extract($this->modBase($id)); if (!$forum->perms->changeStatus) { throw new HttpMethodNotAllowedException; } $topic->status = $topic->status !== 1 ? 1 : 0; $topic->update(); return redirect(route('forums.topic', $topic->id)); } /** * Delete an entire topic. * @param int $id * @throws HttpMethodNotAllowedException * @return string */ public function delete(int $id): string { extract($this->modBase($id)); $trash = intval(config('forum.trash')); if ($topic->forum === $trash && $forum->perms->deleteAny) { $redirect = route('forums.forum', $trash); $topic->delete(); } elseif ($forum->perms->topicMove) { $redirect = route('forums.topic', $topic->id); $topic->move($trash); } else { throw new HttpMethodNotAllowedException; } return redirect($redirect); } /** * Restore a topic to its previous location. * @param int $id * @throws HttpMethodNotAllowedException * @return string */ public function restore(int $id): string { extract($this->modBase($id)); if (!$forum->perms->topicMove) { throw new HttpMethodNotAllowedException; } if ($topic->oldForum) { $topic->move($topic->oldForum, false); } return redirect(route('forums.topic', $topic->id)); } /** * Move a topic. * @param int $id * @throws HttpRouteNotFoundException * @throws HttpMethodNotAllowedException * @return string */ public function move(int $id): string { extract($this->modBase($id)); $dest_forum = new Forum($_POST['destination'] ?? 0); if ($dest_forum->id === 0 || !$dest_forum->perms->view) { throw new HttpRouteNotFoundException; } if (!$forum->perms->topicMove) { throw new HttpMethodNotAllowedException; } $topic->move($dest_forum->id); return route('forums.topic', $topic->id); } /** * Reply to a topic. * @param int $id * @return string */ public function reply(int $id = 0): string { $text = $_POST['text'] ?? null; $topic = new Topic($id); $forum = new Forum($topic->forum); if (!session_check() || $topic->id === 0 || $forum->type !== 0 || !$forum->perms->view) { return $this->json(['error' => "This post doesn't exist or you don't have access to it!"]); } if (!$forum->perms->reply || ( $topic->status === 1 && !$forum->perms->changeStatus )) { return $this->json(['error' => "You are not allowed to post in this topic!"]); } $length = strlen($text); $minLen = config('forum.min_post_length'); $maxLen = config('forum.max_post_length'); $tooShort = $length < $minLen; $tooLong = $length > $maxLen; if ($tooShort || $tooLong) { return $this->json([ 'error' => "Your post is " . ( $tooShort ? "too short, add some more text! Make it at least {$minLen}." : "too long, you're gonna have to cut a little! Keep it under {$maxLen}." ) ]); } $post = Post::create( "Re: {$topic->title}", $text, CurrentSession::$user, $topic->id, $forum->id ); return $this->json(['error' => null, 'go' => route('forums.post', $post->id)]); } /** * Create a topic. * @param int $id * @throws HttpMethodNotAllowedException * @return string */ public function create(int $id = 0): string { $title = $_POST['title'] ?? null; $text = $_POST['text'] ?? null; // And attempt to get the forum $forum = new Forum($id); // Check if the forum exists if ($forum->id === 0 || $forum->type !== 0 || !$forum->perms->view || !$forum->perms->reply || !$forum->perms->topicCreate) { if ($_SERVER['REQUEST_METHOD'] === 'POST') { return $this->json(['error' => "This forum doesn't exist or you don't have access to it!"]); } else { throw new HttpMethodNotAllowedException; } } if ($text !== null && $title !== null) { if (!session_check()) { return $this->json(['error' => 'Your session expired, please refresh!']); } $titleLength = strlen($title); $textLength = strlen($text); $titleMin = config('forum.min_title_length'); $titleMax = config('forum.max_title_length'); $textMin = config('forum.min_post_length'); $textMax = config('forum.max_post_length'); $titleTooShort = $titleLength < $titleMin; $titleTooLong = $titleLength > $titleMax; $textTooShort = $textLength < $textMin; $textTooLong = $textLength > $textMax; if ($titleTooShort || $titleTooLong || $textTooShort || $textTooLong) { $error = ""; if ($titleTooShort) { $error = "This title is too short, it has to be longer than {$titleMin} characters!"; } elseif ($titleTooLong) { $error = "This title is too long, keep it under {$titleMax} characters!"; } elseif ($textTooShort) { $error = "Please make your post a little bit longer, at least {$textMin} characters!"; } elseif ($textTooLong) { $error = "Your post is too long, you're gonna have to cut a little!" . " Can't be more than {$textMax} characters."; } return $this->json(compact('error')); } unset($_SESSION['replyText']["f{$forum->id}"]); $post = Post::create( $title, $text, CurrentSession::$user, 0, $forum->id ); return $this->json(['error' => null, 'go' => route('forums.post', $post->id)]); } return view('forum/topic', compact('forum')); } }