*/ class Topic { /** * The ID of this topic. * * @var int */ public $id = 0; /** * The ID of the forum this topic is a part of. * * @var int */ public $forum = 0; /** * Is this forum hidden from the listing? * * @var bool */ public $hidden = false; /** * The title of the topic. * * @var string */ public $title = ""; /** * The UNIX timestamp of when this topic was created. * * @var int */ public $time = 0; /** * The UNIX timestamp of when this topic should be autolocked (currently unused). * * @var int */ public $timeLimit = 0; /** * The amount of times this topic has been viewed. * * @var int */ public $views = 0; /** * The status of this topic. * 0 - Unlocked * 1 - Locked * * @var int */ public $status = 0; /** * The UNIX timestamp of when the status was last changed. * * @var int */ public $statusChange = 0; /** * The topic type * 0 - Normal topic * 1 - Sticky topic * 2 - Announcement * * @var int */ public $type = 0; /** * The ID of the forum this topic was a part of before the last move. * * @var int */ public $oldForum = 0; /** * The post object cache. * * @var array */ private $postsCache = []; /** * A cached instance of opening post. * * @var Post */ private $firstPostCache = null; /** * A cached instance of the last reply. * * @var Post */ private $lastPostCache = null; /** * Constructor. * * @param mixed $topicId ID of the topic that should be constructed. */ public function __construct($topicId) { // Attempt to get the database row $topicRow = DB::table('topics') ->where('topic_id', $topicId) ->get(); // Assign data if a row was returned if ($topicRow) { $topicRow = $topicRow[0]; $this->id = $topicRow->topic_id; $this->forum = $topicRow->forum_id; $this->hidden = (bool) $topicRow->topic_hidden; $this->title = $topicRow->topic_title; $this->time = $topicRow->topic_time; $this->timeLimit = $topicRow->topic_time_limit; $this->views = $topicRow->topic_views; $this->status = $topicRow->topic_status; $this->statusChange = $topicRow->topic_status_change; $this->type = $topicRow->topic_type; $this->oldForum = $topicRow->topic_old_forum; } } /** * Create a new topic. * * @param mixed $forum ID of the forum this topic is part of. * @param mixed $title Title of the topic. * @param mixed $status Status of the topic. * @param mixed $type Type of topic. * * @return self The new topic instance. */ public static function create($forum, $title, $status = 0, $type = 0) { // Create the database entry $id = DB::table('topics') ->insertGetId([ 'forum_id' => $forum, 'topic_title' => $title, 'topic_time' => time(), 'topic_status' => $status, 'topic_type' => $type, ]); // Return the topic object return new Topic($id); } /** * Delete the current topic. */ public function delete() { // Delete all posts DB::table('posts') ->where('topic_id', $this->id) ->delete(); // Delete topic meta DB::table('topics') ->where('topic_id', $this->id) ->delete(); } /** * Move the topic. * * @param mixed $forum The new forum ID. * @param mixed $setOld Remember the forum ID prior to the move for restoration. */ public function move($forum, $setOld = true) { // Update all posts DB::table('posts') ->where('topic_id', $this->id) ->update(['forum_id' => $forum]); // Update topic meta DB::table('topics') ->where('topic_id', $this->id) ->update([ 'forum_id' => $forum, 'topic_old_forum' => ($setOld ? $this->forum : 0), ]); } /** * Update the topic data. * * @return self The updated topic. */ public function update() { // Update row DB::table('topics') ->where('topic_id', $this->id) ->update([ 'topic_hidden' => $this->hidden, 'topic_title' => $this->title, 'topic_time_limit' => $this->timeLimit, 'topic_status' => $this->status, 'topic_status_change' => $this->statusChange, 'topic_type' => $this->type, 'topic_old_forum' => $this->oldForum, ]); // Return new object return new Topic($this->id); } /** * Get the replies to this topic. * * @return array Array containing Post instances. */ public function posts() { // Check if postsCache is something if (!count($this->postsCache)) { // Get all rows with the topic id $postRows = DB::table('posts') ->where('topic_id', $this->id) ->get(['post_id']); // Create a storage array $posts = []; // Create new post objects for each post foreach ($postRows as $post) { $posts[$post->post_id] = new Post($post->post_id); } $this->postsCache = $posts; } else { $posts = $this->postsCache; } // Return the post objects return $posts; } /** * Get the opening post. * * @return Post A Post instance of the opening post. */ public function firstPost() { // Check if the cache var is set if ($this->firstPostCache !== null) { return $this->firstPostCache; } // Get the row from the database $post = DB::table('posts') ->where('topic_id', $this->id) ->orderBy('post_id') ->limit(1) ->get(['post_id']); // Create the post class $post = new Post($post ? $post[0]->post_id : 0); // Assign it to the cache var $this->firstPostCache = $post; // Return return $post; } /** * Get the latest reply. * * @return Post A Post instance of the latest reply. */ public function lastPost() { // Check if the cache var is set if ($this->lastPostCache !== null) { return $this->lastPostCache; } // Get the row from the database $post = DB::table('posts') ->where('topic_id', $this->id) ->orderBy('post_id', 'desc') ->limit(1) ->get(['post_id']); // Create the post class $post = new Post($post ? $post[0]->post_id : 0); // Assign it to the cache var $this->lastPostCache = $post; // Return return $post; } /** * Get the amount of replies. * * @return int The number of replies to this topic. */ public function replyCount() { return DB::table('posts') ->where('topic_id', $this->id) ->count(); } /** * Check if a user has read this topic before. * * @param mixed $user The id of the user in question. * * @return bool A boolean indicating the read status. */ public function unread($user) { // Return false if the user id is less than 1 if ($user < 1) { return false; } // Attempt to get track row from the database $track = DB::table('topics_track') ->where('user_id', $user) ->where('topic_id', $this->id) ->where('mark_time', '>', $this->lastPost()->time) ->count(); // If nothing was returned it's obvious that the status is unread if (!$track) { return true; } // Else just return false meaning everything is read return false; } /** * Update the read status. * * @param mixed $user The id of the user in question. */ public function trackUpdate($user) { // Check if we already have a track record $track = DB::table('topics_track') ->where('user_id', $user) ->where('topic_id', $this->id) ->where('forum_id', $this->forum) ->count(); // Adding a second to this to avoid own posts getting marked unread $time = time() + 1; // If so update it if ($track) { DB::table('topics_track') ->where('user_id', $user) ->where('topic_id', $this->id) ->update(['mark_time' => $time]); } else { // If not create a new record DB::table('topics_track') ->insert([ 'user_id' => $user, 'topic_id' => $this->id, 'forum_id' => $this->forum, 'mark_time' => $time, ]); } } /** * Update the view count. */ public function viewsUpdate() { DB::table('topics') ->where('topic_id', $this->id) ->increment('topic_views'); } /** * Update the timestamp of when this topic was last replied to. */ public function lastUpdate() { DB::table('topics') ->where('topic_id', $this->id) ->update(['topic_last_reply' => time()]); } }