This repository has been archived on 2024-06-26. You can view files and clone it, but cannot push or open issues or pull requests.
sakura/app/Forum/Topic.php

426 lines
10 KiB
PHP
Raw Normal View History

<?php
2016-02-03 22:22:56 +00:00
/**
2016-07-30 13:48:09 +00:00
* Holds the topic object class.
2016-03-08 23:07:58 +00:00
*
2016-02-03 22:22:56 +00:00
* @package Sakura
*/
namespace Sakura\Forum;
2016-02-18 23:28:44 +00:00
use Sakura\DB;
/**
2016-07-30 13:48:09 +00:00
* Used to serve, create and update topics.
2016-03-08 23:07:58 +00:00
*
* @package Sakura
2016-02-02 21:04:15 +00:00
* @author Julian van de Groep <me@flash.moe>
*/
2016-07-30 13:48:09 +00:00
class Topic
{
2016-02-02 21:04:15 +00:00
/**
2016-07-30 13:48:09 +00:00
* The ID of this topic.
2016-03-08 23:07:58 +00:00
*
2016-02-02 21:04:15 +00:00
* @var int
*/
public $id = 0;
2016-02-02 21:04:15 +00:00
/**
2016-07-30 13:48:09 +00:00
* The ID of the forum this topic is a part of.
2016-03-08 23:07:58 +00:00
*
2016-02-02 21:04:15 +00:00
* @var int
*/
public $forum = 0;
2016-02-02 21:04:15 +00:00
/**
* Is this forum hidden from the listing?
2016-03-08 23:07:58 +00:00
*
2016-02-02 21:04:15 +00:00
* @var bool
*/
public $hidden = false;
/**
2016-07-30 13:48:09 +00:00
* The title of the topic.
2016-03-08 23:07:58 +00:00
*
2016-02-02 21:04:15 +00:00
* @var string
*/
public $title = "";
2016-02-02 21:04:15 +00:00
/**
2016-07-30 13:48:09 +00:00
* The UNIX timestamp of when this topic was created.
2016-03-08 23:07:58 +00:00
*
2016-02-02 21:04:15 +00:00
* @var int
*/
public $time = 0;
2016-02-02 21:04:15 +00:00
/**
2016-07-30 13:48:09 +00:00
* The UNIX timestamp of when this topic should be autolocked (currently unused).
2016-03-08 23:07:58 +00:00
*
2016-02-02 21:04:15 +00:00
* @var int
*/
public $timeLimit = 0;
2016-02-02 21:04:15 +00:00
/**
2016-07-30 13:48:09 +00:00
* The amount of times this topic has been viewed.
2016-03-08 23:07:58 +00:00
*
2016-02-02 21:04:15 +00:00
* @var int
*/
public $views = 0;
2016-02-02 21:04:15 +00:00
/**
2016-07-30 13:48:09 +00:00
* The status of this topic.
2016-02-02 21:04:15 +00:00
* 0 - Unlocked
* 1 - Locked
2016-03-08 23:07:58 +00:00
*
2016-02-02 21:04:15 +00:00
* @var int
*/
public $status = 0;
2016-02-02 21:04:15 +00:00
/**
* The UNIX timestamp of when the status was last changed.
2016-03-08 23:07:58 +00:00
*
2016-02-02 21:04:15 +00:00
* @var int
*/
public $statusChange = 0;
2016-02-02 21:04:15 +00:00
/**
2016-07-30 13:48:09 +00:00
* The topic type
* 0 - Normal topic
* 1 - Sticky topic
2016-02-02 21:04:15 +00:00
* 2 - Announcement
2016-03-08 23:07:58 +00:00
*
2016-02-02 21:04:15 +00:00
* @var int
*/
public $type = 0;
2016-02-02 21:04:15 +00:00
/**
2016-07-30 13:48:09 +00:00
* The ID of the forum this topic was a part of before the last move.
2016-03-08 23:07:58 +00:00
*
2016-02-02 21:04:15 +00:00
* @var int
*/
2016-01-10 18:24:47 +00:00
public $oldForum = 0;
2016-02-02 21:04:15 +00:00
/**
* The post object cache.
2016-03-08 23:07:58 +00:00
*
2016-02-02 21:04:15 +00:00
* @var array
*/
private $postsCache = [];
2016-02-02 21:04:15 +00:00
/**
* A cached instance of opening post.
2016-03-08 23:07:58 +00:00
*
2016-02-02 21:04:15 +00:00
* @var Post
*/
private $firstPostCache = null;
2016-02-02 21:04:15 +00:00
/**
* A cached instance of the last reply.
2016-03-08 23:07:58 +00:00
*
2016-02-02 21:04:15 +00:00
* @var Post
*/
private $lastPostCache = null;
2016-02-02 21:04:15 +00:00
/**
* Constructor.
2016-03-08 23:07:58 +00:00
*
2016-07-30 13:48:09 +00:00
* @param mixed $topicId ID of the topic that should be constructed.
2016-02-02 21:04:15 +00:00
*/
2016-07-30 13:48:09 +00:00
public function __construct($topicId)
{
// Attempt to get the database row
2016-07-30 13:48:09 +00:00
$topicRow = DB::table('topics')
->where('topic_id', $topicId)
2016-02-25 16:06:29 +00:00
->get();
// Assign data if a row was returned
2016-07-30 13:48:09 +00:00
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;
}
}
2016-02-02 21:04:15 +00:00
/**
2016-07-30 13:48:09 +00:00
* Create a new topic.
2016-03-08 23:07:58 +00:00
*
2016-07-30 13:48:09 +00:00
* @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.
2016-03-08 23:07:58 +00:00
*
2016-07-30 13:48:09 +00:00
* @return self The new topic instance.
2016-02-02 21:04:15 +00:00
*/
public static function create($forum, $title, $status = 0, $type = 0)
{
// Create the database entry
2016-02-25 16:06:29 +00:00
$id = DB::table('topics')
->insertGetId([
'forum_id' => $forum,
'topic_title' => $title,
'topic_time' => time(),
'topic_status' => $status,
'topic_type' => $type,
]);
2016-07-30 13:48:09 +00:00
// Return the topic object
return new Topic($id);
}
2016-02-02 21:04:15 +00:00
/**
2016-07-30 13:48:09 +00:00
* Delete the current topic.
2016-02-02 21:04:15 +00:00
*/
2016-01-10 18:24:47 +00:00
public function delete()
{
// Delete all posts
2016-02-25 16:06:29 +00:00
DB::table('posts')
->where('topic_id', $this->id)
->delete();
2016-01-10 18:24:47 +00:00
2016-07-30 13:48:09 +00:00
// Delete topic meta
2016-02-25 16:06:29 +00:00
DB::table('topics')
->where('topic_id', $this->id)
->delete();
2016-01-10 18:24:47 +00:00
}
2016-02-02 21:04:15 +00:00
/**
2016-07-30 13:48:09 +00:00
* Move the topic.
2016-03-08 23:07:58 +00:00
*
2016-02-02 21:04:15 +00:00
* @param mixed $forum The new forum ID.
* @param mixed $setOld Remember the forum ID prior to the move for restoration.
*/
2016-01-10 18:24:47 +00:00
public function move($forum, $setOld = true)
{
// Update all posts
2016-02-25 16:06:29 +00:00
DB::table('posts')
->where('topic_id', $this->id)
->update(['forum_id' => $forum]);
2016-01-10 18:24:47 +00:00
2016-07-30 13:48:09 +00:00
// Update topic meta
2016-02-25 16:06:29 +00:00
DB::table('topics')
->where('topic_id', $this->id)
->update([
'forum_id' => $forum,
'topic_old_forum' => ($setOld ? $this->forum : 0),
]);
2016-01-10 18:24:47 +00:00
}
2016-02-02 21:04:15 +00:00
/**
2016-07-30 13:48:09 +00:00
* Update the topic data.
2016-03-08 23:07:58 +00:00
*
2016-07-30 13:48:09 +00:00
* @return self The updated topic.
2016-02-02 21:04:15 +00:00
*/
2016-01-10 18:24:47 +00:00
public function update()
{
// Update row
2016-02-25 16:06:29 +00:00
DB::table('topics')
->where('topic_id', $this->id)
->update([
'topic_hidden' => $this->hidden,
'topic_title' => $this->title,
2016-03-10 18:54:36 +00:00
'topic_time_limit' => $this->timeLimit,
2016-02-25 16:06:29 +00:00
'topic_status' => $this->status,
'topic_status_change' => $this->statusChange,
'topic_type' => $this->type,
'topic_old_forum' => $this->oldForum,
]);
2016-01-10 18:24:47 +00:00
// Return new object
2016-07-30 13:48:09 +00:00
return new Topic($this->id);
2016-01-10 18:24:47 +00:00
}
2016-02-02 21:04:15 +00:00
/**
2016-07-30 13:48:09 +00:00
* Get the replies to this topic.
2016-03-08 23:07:58 +00:00
*
2016-02-02 21:04:15 +00:00
* @return array Array containing Post instances.
*/
public function posts()
{
// Check if postsCache is something
if (!count($this->postsCache)) {
2016-07-30 13:48:09 +00:00
// Get all rows with the topic id
2016-02-25 16:06:29 +00:00
$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) {
2016-02-18 23:28:44 +00:00
$posts[$post->post_id] = new Post($post->post_id);
}
$this->postsCache = $posts;
} else {
$posts = $this->postsCache;
}
// Return the post objects
return $posts;
}
2016-02-02 21:04:15 +00:00
/**
* Get the opening post.
2016-03-08 23:07:58 +00:00
*
2016-02-02 21:04:15 +00:00
* @return Post A Post instance of the opening post.
*/
2015-12-04 13:52:57 +00:00
public function firstPost()
{
// Check if the cache var is set
if ($this->firstPostCache !== null) {
return $this->firstPostCache;
}
// Get the row from the database
2016-02-25 16:06:29 +00:00
$post = DB::table('posts')
->where('topic_id', $this->id)
->orderBy('post_id')
->limit(1)
->get(['post_id']);
// Create the post class
2016-02-25 16:06:29 +00:00
$post = new Post($post ? $post[0]->post_id : 0);
// Assign it to the cache var
$this->firstPostCache = $post;
// Return
return $post;
}
2016-02-02 21:04:15 +00:00
/**
* Get the latest reply.
2016-03-08 23:07:58 +00:00
*
2016-02-02 21:04:15 +00:00
* @return Post A Post instance of the latest reply.
*/
2015-12-04 13:52:57 +00:00
public function lastPost()
{
// Check if the cache var is set
if ($this->lastPostCache !== null) {
return $this->lastPostCache;
}
// Get the row from the database
2016-02-25 16:06:29 +00:00
$post = DB::table('posts')
->where('topic_id', $this->id)
->orderBy('post_id', 'desc')
->limit(1)
->get(['post_id']);
// Create the post class
2016-02-25 16:06:29 +00:00
$post = new Post($post ? $post[0]->post_id : 0);
// Assign it to the cache var
$this->lastPostCache = $post;
// Return
return $post;
}
2016-02-02 21:04:15 +00:00
/**
* Get the amount of replies.
2016-03-08 23:07:58 +00:00
*
2016-07-30 13:48:09 +00:00
* @return int The number of replies to this topic.
2016-02-02 21:04:15 +00:00
*/
public function replyCount()
{
2016-02-25 16:06:29 +00:00
return DB::table('posts')
->where('topic_id', $this->id)
->count();
}
2016-02-02 21:04:15 +00:00
/**
2016-07-30 13:48:09 +00:00
* Check if a user has read this topic before.
2016-03-08 23:07:58 +00:00
*
2016-02-02 21:04:15 +00:00
* @param mixed $user The id of the user in question.
2016-03-08 23:07:58 +00:00
*
2016-02-02 21:04:15 +00:00
* @return bool A boolean indicating the read status.
*/
public function unread($user)
{
2016-04-25 02:01:14 +00:00
// Return false if the user id is less than 1
if ($user < 1) {
return false;
}
// Attempt to get track row from the database
2016-02-25 16:06:29 +00:00
$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
2016-02-25 16:06:29 +00:00
if (!$track) {
return true;
}
// Else just return false meaning everything is read
return false;
}
2016-02-02 21:04:15 +00:00
/**
* Update the read status.
2016-03-08 23:07:58 +00:00
*
2016-02-02 21:04:15 +00:00
* @param mixed $user The id of the user in question.
*/
public function trackUpdate($user)
{
// Check if we already have a track record
2016-02-25 16:06:29 +00:00
$track = DB::table('topics_track')
->where('user_id', $user)
->where('topic_id', $this->id)
->where('forum_id', $this->forum)
->count();
2016-04-02 13:14:07 +00:00
// Adding a second to this to avoid own posts getting marked unread
$time = time() + 1;
// If so update it
2016-02-25 16:06:29 +00:00
if ($track) {
DB::table('topics_track')
->where('user_id', $user)
->where('topic_id', $this->id)
2016-04-02 13:14:07 +00:00
->update(['mark_time' => $time]);
} else {
// If not create a new record
2016-02-25 16:06:29 +00:00
DB::table('topics_track')
->insert([
'user_id' => $user,
'topic_id' => $this->id,
'forum_id' => $this->forum,
2016-04-02 13:14:07 +00:00
'mark_time' => $time,
2016-02-25 16:06:29 +00:00
]);
}
}
2016-02-02 21:04:15 +00:00
/**
* Update the view count.
*/
public function viewsUpdate()
{
2016-02-25 16:06:29 +00:00
DB::table('topics')
->where('topic_id', $this->id)
->increment('topic_views');
}
2016-02-02 21:04:15 +00:00
/**
2016-07-30 13:48:09 +00:00
* Update the timestamp of when this topic was last replied to.
2016-02-02 21:04:15 +00:00
*/
public function lastUpdate()
{
2016-02-25 16:06:29 +00:00
DB::table('topics')
->where('topic_id', $this->id)
->update(['topic_last_reply' => time()]);
}
}