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/Forum.php
2016-12-22 19:10:09 +01:00

349 lines
8.8 KiB
PHP

<?php
/**
* Holds the forum object class.
* @package Sakura
*/
namespace Sakura\Forum;
use Sakura\DB;
use Sakura\CurrentSession;
/**
* Used to serve forums.
* @package Sakura
* @author Julian van de Groep <me@flash.moe>
*/
class Forum
{
/**
* The ID of the forum.
* @var int
*/
public $id = 0;
/**
* The order of the forum.
* @var int
*/
public $order = 0;
/**
* The name of the forum.
* @var string
*/
public $name = "Forum";
/**
* The description of the forum.
* @var string
*/
public $description = "";
/**
* The link of the forum (if the type is 2).
* @var string
*/
public $link = "";
/**
* The ID of the parent forum.
* @var int
*/
public $category = 0;
/**
* The type of forum.
* @var int
*/
public $type = 0;
/**
* The icon of this forum.
* @var string
*/
public $icon = "";
/**
* Amount of topics in this forum.
* @var int
*/
public $countTopics = 0;
/**
* Amount of posts in this forum.
* @var int
*/
public $countPosts = 0;
/**
* Id of the last post made in this forum.
* @var int
*/
public $lastPostId = 0;
/**
* Title of the last post made in this forum.
* @var string
*/
public $lastPostTitle = "";
/**
* Post time of the last post made in this forum.
* @var int
*/
public $lastPostTime = 0;
/**
* User id which last posted in this forum.
* @var int
*/
public $lastPostUserId = 0;
/**
* Username which last posted in this forum.
* @var string
*/
public $lastPostUsername = "";
/**
* Colour of user which last posted in this forum.
* @var string
*/
public $lastPostUserColour = "";
/**
* Holds the permission handler.
* @var ForumPerms
*/
public $perms;
/**
* A cached instance of the last post in this forum.
* @var Post
*/
private $lastPostCache = null;
/**
* Cached instances of the subforums.
* @var array
*/
private $forumsCache = [];
/**
* Cached instances of the topics in this forum.
* @var array
*/
private $topicsCache = [];
/**
* Constructor.
* @param int $forumId
*/
public function __construct(int $forumId = 0)
{
// Get the row from the database
$forumRow = DB::table('forums')
->where('forum_id', $forumId)
->first();
// Populate the variables
if ($forumRow) {
$this->id = intval($forumRow->forum_id);
$this->order = intval($forumRow->forum_order);
$this->name = $forumRow->forum_name;
$this->description = $forumRow->forum_desc;
$this->link = $forumRow->forum_link;
$this->category = intval($forumRow->forum_category);
$this->type = intval($forumRow->forum_type);
$this->icon = $forumRow->forum_icon;
$this->countTopics = intval($forumRow->forum_count_topics);
$this->countPosts = intval($forumRow->forum_count_posts);
$this->lastPostId = intval($forumRow->last_post_id);
$this->lastPostTitle = $forumRow->last_post_title;
$this->lastPostTime = intval($forumRow->last_post_time);
$this->lastPostUserId = intval($forumRow->last_post_user_id);
$this->lastPostUsername = $forumRow->last_post_username;
$this->lastPostUserColour = $forumRow->last_post_user_colour;
} elseif ($forumId !== 0) {
$this->id = -1;
}
$this->perms = new ForumPerms($this, CurrentSession::$user);
}
/**
* Gets all subforums of this forum.
* @return array
*/
public function forums(): array
{
// Check if forumsCache is populated
if (!count($this->forumsCache)) {
// Get all rows with the category id set to the forum id
$forumRows = DB::table('forums')
->where('forum_category', $this->id)
->orderBy('forum_order')
->get(['forum_id']);
// Create a storage array
$forums = [];
// Create new objects for each forum
foreach ($forumRows as $forum) {
$forums[$forum->forum_id] = new Forum($forum->forum_id);
}
$this->forumsCache = $forums;
}
return $this->forumsCache;
}
/**
* Gets the topics in this forum.
* @return array
*/
public function topics(): array
{
// Check if topicsCache is populated
if (!count($this->topicsCache)) {
// Get all rows with the forum id for this forum
$topicRows = DB::table('topics')
->where('forum_id', $this->id)
->orderBy('topic_type', 'desc')
->orderBy('topic_last_reply', 'desc')
->get(['topic_id']);
// Create a storage array
$topics = [];
// Create new objects for each topic
foreach ($topicRows as $topic) {
$topics[$topic->topic_id] = new Topic($topic->topic_id);
}
$this->topicsCache = $topics;
} else {
$topics = $this->topicsCache;
}
// Return the topic objects
return $topics;
}
/**
* Increment counts.
* @param bool $topic
* @param int $amount_posts
* @param int $amount_topics
*/
public function incrementPostsCount(bool $topic = false, int $amount_posts = 1, int $amount_topics = 1): void
{
$this->countPosts = (int) DB::table('forums')
->where('forum_id', $this->id)
->increment('forum_count_posts', $amount_posts);
if ($topic) {
$this->countTopics = (int) DB::table('forums')
->where('forum_id', $this->id)
->increment('forum_count_topics', $amount_topics);
}
}
/**
* Decrement counts.
* @param bool $topic
* @param int $amount_posts
* @param int $amount_topics
*/
public function decrementPostsCount(bool $topic = false, int $amount_posts = 1, int $amount_topics = 1): void
{
$this->countPosts = (int) DB::table('forums')
->where('forum_id', $this->id)
->decrement('forum_count_posts', $amount_posts);
if ($topic) {
$this->countTopics = (int) DB::table('forums')
->where('forum_id', $this->id)
->decrement('forum_count_topics', $amount_topics);
}
}
/**
* Updates last post information for this forum.
* @param Post $post
*/
public function updateLastPost(Post $post = null): void
{
if ($post === null) {
$post_id = DB::table('posts')
->where('forum_id', $this->id)
->orderBy('post_id', 'desc')
->take(1)
->value('post_id');
$post = new Post($post_id);
}
DB::table('forums')
->where('forum_id', $this->id)
->update([
'last_post_id' => $this->lastPostId = $post->id,
'last_post_title' => $this->lastPostTitle = $post->subject,
'last_post_time' => $this->lastPostTime = $post->time,
'last_post_user_id' => $this->lastPostUserId = $post->poster->id,
'last_post_username' => $this->lastPostUsername = $post->poster->username,
'last_post_user_colour' => $this->lastPostUserColour = $post->poster->colour,
]);
}
/**
* Checks if a user has read every post in the specified forum.
* @param int $user
* @return bool
*/
public function unread(int $user): bool
{
// Return false if the user id is less than 1
if ($user < 1) {
return false;
}
// Check forums
foreach ($this->forums() as $forum) {
if ($forum->unread($user)) {
return true;
}
}
// Check each topic
foreach ($this->topics() as $topic) {
if ($topic->unread($user)) {
return true;
}
}
// Return false if negative
return false;
}
/**
* Update the read status of all topics in this forum at once.
* @param int $user
*/
public function trackUpdateAll(int $user): void
{
// Iterate over every forum
foreach ($this->forums() as $forum) {
// Update every forum
$forum->trackUpdateAll($user);
}
// Iterate over every topic
foreach ($this->topics() as $topic) {
// Update every topic
$topic->trackUpdate($user);
}
}
}