diff --git a/libraries/ActionCode.php b/libraries/ActionCode.php index 5eabe4e..ca4f420 100644 --- a/libraries/ActionCode.php +++ b/libraries/ActionCode.php @@ -51,7 +51,7 @@ class ActionCode public static function invalidate($code) { Database::delete('actioncodes', [ - 'code_action' => [$code, '='], + 'code_action' => [$code, '='], ]); } } diff --git a/libraries/Forum/Post.php b/libraries/Forum/Post.php index 2f76a5e..ff3b02d 100644 --- a/libraries/Forum/Post.php +++ b/libraries/Forum/Post.php @@ -104,7 +104,8 @@ class Post } // Update a post - public function update() { + public function update() + { // Check if the data meets the requirements if (strlen($this->subject) < Config::get('forum_title_min') || strlen($this->subject) > Config::get('forum_title_max') diff --git a/libraries/Forum/Thread.php b/libraries/Forum/Thread.php index 79b29a0..d8c6cf3 100644 --- a/libraries/Forum/Thread.php +++ b/libraries/Forum/Thread.php @@ -25,6 +25,7 @@ class Thread public $status = 0; public $statusChange = 0; public $type = 0; + public $oldForum = 0; private $_posts = []; private $_firstPost = null; private $_lastPost = null; @@ -47,6 +48,7 @@ class Thread $this->status = $threadRow['topic_status']; $this->statusChange = $threadRow['topic_status_change']; $this->type = $threadRow['topic_type']; + $this->oldForum = $threadRow['topic_old_forum']; } } @@ -66,6 +68,68 @@ class Thread return new Thread(Database::lastInsertID()); } + // Delete the thread + public function delete() + { + // Delete all posts + Database::delete('posts', [ + 'topic_id' => [$this->id, '='], + ]); + + // Delete thread meta + Database::delete('topics', [ + 'topic_id' => [$this->id, '='], + ]); + } + + // Move the thread + public function move($forum, $setOld = true) + { + // Update all posts + Database::update('posts', [ + [ + 'forum_id' => $forum, + ], + [ + 'topic_id' => [$this->id, '='], + ] + ]); + + // Update thread meta + Database::update('topics', [ + [ + 'forum_id' => $forum, + 'topic_old_forum' => ($setOld ? $this->forum : 0), + ], + [ + 'topic_id' => [$this->id, '='], + ] + ]); + } + + // Update the thread + public function update() + { + // Update row + Database::update('topics', [ + [ + '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, + ], + [ + 'topic_id' => [$this->id, '='], + ] + ]); + + // Return new object + return new Thread($this->id); + } + // Posts public function posts() { diff --git a/libraries/Perms/Forum.php b/libraries/Perms/Forum.php index a35bd1b..63b2cb2 100644 --- a/libraries/Perms/Forum.php +++ b/libraries/Perms/Forum.php @@ -20,4 +20,6 @@ class Forum const ANNOUNCEMENT = 64; // Can announce threads const EDIT_ANY = 128; // Can edit any post const DELETE_ANY = 256; // Can delete any post + const LOCK = 512; // Can (un)lock threads + const MOVE = 1024; // Can move threads } diff --git a/libraries/Perms/Manage.php b/libraries/Perms/Manage.php index 111844c..c494658 100644 --- a/libraries/Perms/Manage.php +++ b/libraries/Perms/Manage.php @@ -12,4 +12,5 @@ namespace Sakura\Perms; class Manage { const USE_MANAGE = 1; // Can use manage + const CAN_RESTRICT_USERS = 2; // Can change the status of users to restricted } diff --git a/libraries/Urls.php b/libraries/Urls.php index 8ad2816..72a6cc0 100644 --- a/libraries/Urls.php +++ b/libraries/Urls.php @@ -143,6 +143,30 @@ class Urls '/posting.php?p=%1$u"e=%1$u', '/forum/post/%u/quote', ], + 'FORUM_LOCK' => [ + '/viewtopic.php?t=%u&lock=%s', + '/forum/thread/%u?lock=%s', + ], + 'FORUM_STICKY' => [ + '/viewtopic.php?t=%u&sticky=%s', + '/forum/thread/%u?sticky=%s', + ], + 'FORUM_ANNOUNCE' => [ + '/viewtopic.php?t=%u&announce=%s', + '/forum/thread/%u?announce=%s', + ], + 'FORUM_RESTORE' => [ + '/viewtopic.php?t=%u&restore=%s', + '/forum/thread/%u?restore=%s', + ], + 'FORUM_TRASH' => [ + '/viewtopic.php?t=%u&trash=%s', + '/forum/thread/%u?trash=%s', + ], + 'FORUM_PRUNE' => [ + '/viewtopic.php?t=%u&prune=%s', + '/forum/thread/%u?prune=%s', + ], // Image serve references 'IMAGE_AVATAR' => [ diff --git a/libraries/User.php b/libraries/User.php index 0d17236..4934eca 100644 --- a/libraries/User.php +++ b/libraries/User.php @@ -119,7 +119,7 @@ class User $this->data['user_data'] = json_decode(!empty($this->data['user_data']) ? $this->data['user_data'] : '[]', true); // Get all ranks - $ranks = array_map(function($a) { + $ranks = array_map(function ($a) { return $a['rank_id']; }, Database::fetch('user_ranks', true, ['user_id' => [$this->data['user_id'], '=']])); diff --git a/public/imageserve.php b/public/imageserve.php index 0effbf1..88ea97b 100644 --- a/public/imageserve.php +++ b/public/imageserve.php @@ -46,13 +46,13 @@ if (isset($_GET['m'])) { $user = User::construct($_GET['u']); // If user is deactivated use deactive avatar - if ($user->hasRanks([0, 1])) { + if ($user->permission(Perms\Site::DEACTIVATED)) { $serveImage = $deactiveAvatar; break; } // Check if user is banned - if ($user->checkBan()) { + if ($user->checkBan() || $user->permission(Perms\Site::RESTRICTED)) { $serveImage = $bannedAvatar; break; } @@ -81,13 +81,13 @@ if (isset($_GET['m'])) { $user = User::construct($_GET['u']); // If user is deactivated use deactive avatar - if ($user->hasRanks([0, 1])) { + if ($user->permission(Perms\Site::DEACTIVATED)) { $serveImage = $noBackground; break; } // Check if user is banned - if (Bans::checkBan($_GET['u'])) { + if (Bans::checkBan($_GET['u']) || $user->permission(Perms\Site::RESTRICTED)) { $serveImage = $noBackground; break; } @@ -117,13 +117,13 @@ if (isset($_GET['m'])) { $user = User::construct($_GET['u']); // If user is deactivated use deactive avatar - if ($user->hasRanks([0, 1])) { + if ($user->permission(Perms\Site::DEACTIVATED)) { $serveImage = $noHeader; break; } // Check if user is banned - if (Bans::checkBan($_GET['u'])) { + if (Bans::checkBan($_GET['u']) || $user->permission(Perms\Site::RESTRICTED)) { $serveImage = $noHeader; break; } diff --git a/public/posting.php b/public/posting.php index a1f69e7..ec9d560 100644 --- a/public/posting.php +++ b/public/posting.php @@ -55,6 +55,22 @@ if (!$forum->permission(ForumPerms::VIEW, $currentUser->id()) || !$forum->permis exit; } +// Check if the user has access to the forum +if (!isset($thread) && !$forum->permission(ForumPerms::CREATE_THREADS, $currentUser->id())) { + // Set render data + $renderData['page'] = [ + 'title' => 'Information', + 'message' => 'You are not allowed to create threads in this forum.', + ]; + + // Set parse variables + $template->setVariables($renderData); + + // Print page contents + echo $template->render('global/information'); + exit; +} + $mode = isset($_GET['f']) ? 'f' : (isset($_GET['t']) ? 't' : (isset($_GET['p']) ? 'p' : null)); // Include emotes and bbcodes @@ -83,6 +99,22 @@ if ($mode != 'f') { exit; } + // Prompt an error if the topic doesn't exist + if ($thread->status == 1 && !$forum->permission(ForumPerms::LOCK, $currentUser->id())) { + // Add page specific things + $renderData['page'] = [ + 'redirect' => (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : $urls->format('FORUM_INDEX')), + 'message' => 'The thread you tried to reply to is locked.', + ]; + + // Set parse variables + $template->setVariables($renderData); + + // Print page contents + echo $template->render('global/information'); + exit; + } + // Check if we're in quote mode if ($mode == 'p' && isset($_GET['quote']) && $_GET['quote'] == $_GET['p'] && array_key_exists($_GET['p'], $thread->posts())) { // Reassign post for ease @@ -93,8 +125,23 @@ if ($mode != 'f') { // Post editing } elseif ($mode == 'p' && isset($_GET['edit']) && $_GET['edit'] == $_GET['p'] && array_key_exists($_GET['p'], $thread->posts())) { + // Permissions + if (!$currentUser->permission(ForumPerms::EDIT_OWN, Perms::FORUM)) { + // Add page specific things + $renderData['page'] = [ + 'redirect' => (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : $urls->format('FORUM_INDEX')), + 'message' => 'You are not allowed to edit posts!', + ]; + + // Set parse variables + $template->setVariables($renderData); + + // Print page contents + echo $template->render('global/information'); + exit; + } // Checks - if ($thread->posts()[$_GET['p']]->poster->id() != $currentUser->id()) { + if ($thread->posts()[$_GET['p']]->poster->id() != $currentUser->id() && !$forum->permission(ForumPerms::EDIT_ANY, $currentUser->id())) { // Add page specific things $renderData['page'] = [ 'redirect' => (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : $urls->format('FORUM_INDEX')), @@ -120,12 +167,12 @@ if ($mode != 'f') { ]); // Post deletion } elseif ($mode == 'p' && isset($_GET['delete']) && $_GET['delete'] == $_GET['p'] && array_key_exists($_GET['p'], $thread->posts())) { - // Checks - if ($thread->posts()[$_GET['p']]->poster->id() != $currentUser->id() || !$forum->permission(ForumPerms::DELETE_ANY, $currentUser->id())) { + // Permissions + if (!$currentUser->permission(ForumPerms::DELETE_OWN, Perms::FORUM)) { // Add page specific things $renderData['page'] = [ 'redirect' => (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : $urls->format('FORUM_INDEX')), - 'message' => 'You can only delete your own posts!', + 'message' => 'You are not allowed to delete posts!', ]; // Set parse variables @@ -136,8 +183,8 @@ if ($mode != 'f') { exit; } - // Permissions - if ($currentUser->permission(ForumPerms::DELETE_OWN, Perms::FORUM)) { + // Checks + if ($thread->posts()[$_GET['p']]->poster->id() != $currentUser->id() && !$forum->permission(ForumPerms::DELETE_ANY, $currentUser->id())) { // Add page specific things $renderData['page'] = [ 'redirect' => (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : $urls->format('FORUM_INDEX')), @@ -226,7 +273,7 @@ if (isset($_POST['post'])) { $post->editTime = time(); $post->editReason = ''; $post->editUser = $currentUser; - $post->update(); + $post = $post->update(); } else { $post = null; } diff --git a/public/profile.php b/public/profile.php index f75bc2c..31e6821 100644 --- a/public/profile.php +++ b/public/profile.php @@ -21,9 +21,9 @@ $profile = User::construct(isset($_GET['u']) ? $_GET['u'] : 0); // Views array $views = [ 'index', - 'friends', + /*'friends', 'threads', - 'posts', + 'posts',*/ 'comments', ]; @@ -39,9 +39,8 @@ if ($profile->id() == 0) { // Redirect if so if ($check) { $renderData['page'] = [ - 'title' => 'Information', 'message' => 'The user this profile belongs to changed their username, you are being redirected.', - 'redirect' => $urls->format('USER_PROFILE', [$check['user_id']]), + 'redirect' => $urls->format('USER_PROFILE', [$check['user_id']]), ]; // Set parse variables @@ -53,6 +52,31 @@ if ($profile->id() == 0) { } } +// If the user id is zero check if there was a namechange +if (isset($_GET['restrict']) && $_GET['restrict'] == session_id() && $currentUser->permission(Perms\Manage::CAN_RESTRICT_USERS, Perms::MANAGE)) { + // Check restricted status + $restricted = $profile->permission(Perms\Site::RESTRICTED); + + if ($restricted) { + $profile->removeRanks([Config::get('restricted_rank_id')]); + } else { + $profile->addRanks([Config::get('restricted_rank_id')]); + $profile->removeRanks($profile->ranks()); + } + + $renderData['page'] = [ + 'message' => 'Toggled the restricted status of the user.', + 'redirect' => $urls->format('USER_PROFILE', [$profile->id()]), + ]; + + // Set parse variables + $template->setVariables($renderData); + + // Print page contents + echo $template->render('global/information'); + exit; +} + // Set parse variables $template->setVariables($renderData); diff --git a/public/viewtopic.php b/public/viewtopic.php index 3a38a3a..458b06b 100644 --- a/public/viewtopic.php +++ b/public/viewtopic.php @@ -32,6 +32,7 @@ if (!$thread) { // Set render data $renderData['page'] = [ 'message' => 'The topic you tried to access does not exist.', + 'redirect' => $urls->format('FORUM_THREAD', [$thread->id]), ]; // Set parse variables @@ -46,8 +47,8 @@ if (!$thread) { if (!$forum->permission(ForumPerms::VIEW, $currentUser->id())) { // Set render data $renderData['page'] = [ - 'title' => 'Information', 'message' => 'You do not have access to this thread.', + 'redirect' => $urls->format('FORUM_THREAD', [$thread->id]), ]; // Set parse variables @@ -58,6 +59,164 @@ if (!$forum->permission(ForumPerms::VIEW, $currentUser->id())) { exit; } +// Sticky thread +if (isset($_GET['sticky']) && $_GET['sticky'] == session_id() && $forum->permission(ForumPerms::STICKY, $currentUser->id())) { + // Check the status + if ($thread->type == 1) { + $thread->type = 0; + } else { + $thread->type = 1; + } + + // Update the thread + $thread->update(); + + // Set render data + $renderData['page'] = [ + 'message' => 'Changed the thread type.', + 'redirect' => $urls->format('FORUM_THREAD', [$thread->id]), + ]; + + // Set parse variables + $template->setVariables($renderData); + + // Print page contents + echo $template->render('global/information'); + exit; +} + +// Announce thread +if (isset($_GET['announce']) && $_GET['announce'] == session_id() && $forum->permission(ForumPerms::ANNOUNCEMENT, $currentUser->id())) { + // Check the status + if ($thread->type == 2) { + $thread->type = 0; + } else { + $thread->type = 2; + } + + // Update the thread + $thread->update(); + // Set render data + $renderData['page'] = [ + 'message' => 'Changed the thread type.', + 'redirect' => $urls->format('FORUM_THREAD', [$thread->id]), + ]; + + // Set parse variables + $template->setVariables($renderData); + + // Print page contents + echo $template->render('global/information'); + exit; +} + +// Lock thread +if (isset($_GET['lock']) && $_GET['lock'] == session_id() && $forum->permission(ForumPerms::LOCK, $currentUser->id())) { + // Check the status + if ($thread->status == 1) { + $thread->status = 0; + } else { + $thread->status = 1; + } + + // Update the thread + $thread->update(); + // Set render data + $renderData['page'] = [ + 'message' => 'Changed the thread status.', + 'redirect' => $urls->format('FORUM_THREAD', [$thread->id]), + ]; + + // Set parse variables + $template->setVariables($renderData); + + // Print page contents + echo $template->render('global/information'); + exit; +} + +// Trash thread +if (isset($_GET['trash']) && $_GET['trash'] == session_id() && $forum->permission(ForumPerms::MOVE, $currentUser->id())) { + // Check the status + if ($thread->forum != Config::get('forum_trash_id')) { + $thread->move(Config::get('forum_trash_id')); + + // Set render data + $renderData['page'] = [ + 'message' => 'Moved thread to the trash.', + 'redirect' => $urls->format('FORUM_THREAD', [$thread->id]), + ]; + } else { + // Set render data + $renderData['page'] = [ + 'message' => 'This thread is already trashed.', + 'redirect' => $urls->format('FORUM_THREAD', [$thread->id]), + ]; + } + + // Set parse variables + $template->setVariables($renderData); + + // Print page contents + echo $template->render('global/information'); + exit; +} + +// Restore thread +if (isset($_GET['restore']) && $_GET['restore'] == session_id() && $forum->permission(ForumPerms::MOVE, $currentUser->id())) { + // Check the status + if ($thread->oldForum) { + // Move thread + $thread->move($thread->oldForum, false); + + // Set render data + $renderData['page'] = [ + 'message' => 'Restored the thread to its previous location.', + 'redirect' => $urls->format('FORUM_THREAD', [$thread->id]), + ]; + } else { + // Set render data + $renderData['page'] = [ + 'message' => 'This thread has never been moved.', + 'redirect' => $urls->format('FORUM_THREAD', [$thread->id]), + ]; + } + + // Set parse variables + $template->setVariables($renderData); + + // Print page contents + echo $template->render('global/information'); + exit; +} + +// Prune thread +if (isset($_GET['prune']) && $_GET['prune'] == session_id() && $forum->permission(ForumPerms::DELETE_ANY, $currentUser->id())) { + // Check the status + if ($thread->forum == Config::get('forum_trash_id')) { + $thread->delete(); + + // Set render data + $renderData['page'] = [ + 'message' => 'The thread has been pruned.', + 'redirect' => $urls->format('FORUM_SUB', [$thread->forum]), + ]; + } else { + // Set render data + $renderData['page'] = [ + 'message' => 'You can only prune trashed threads.', + 'redirect' => $urls->format('FORUM_THREAD', [$thread->id]), + ]; + } + + // Set parse variables + $template->setVariables($renderData); + + // Print page contents + echo $template->render('global/information'); + exit; +} + // Update the tracking status $thread->trackUpdate($currentUser->id()); diff --git a/sakura.php b/sakura.php index 096c036..d537c7d 100644 --- a/sakura.php +++ b/sakura.php @@ -8,7 +8,7 @@ namespace Sakura; // Define Sakura version -define('SAKURA_VERSION', '20160109'); +define('SAKURA_VERSION', '20160110'); define('SAKURA_VLABEL', 'Eminence'); define('SAKURA_COLOUR', '#6C3082'); @@ -153,6 +153,7 @@ if (!defined('SAKURA_NO_TPL')) { 'onlineTimeout' => Config::get('max_online_time'), 'announcementImage' => Config::get('header_announcement_image'), 'announcementLink' => Config::get('header_announcement_link'), + 'trashForumId' => Config::get('forum_trash_id'), 'recaptchaPublic' => Config::get('recaptcha_public'), 'recaptchaEnabled' => Config::get('recaptcha'), diff --git a/templates/yuuno/forum/forumBtns.twig b/templates/yuuno/forum/forumBtns.twig index 08e6987..71d030e 100644 --- a/templates/yuuno/forum/forumBtns.twig +++ b/templates/yuuno/forum/forumBtns.twig @@ -7,7 +7,6 @@ {% endif %} {% if forumReplyLink %} Reply - Refresh {% endif %} {% if forumNewLink %} New Thread @@ -15,6 +14,29 @@ {% if forumMarkRead %} Mark as Read {% endif %} + {% if forumSticky %} + Stick + {% elseif forumUnsticky %} + Unstick + {% endif %} + {% if forumAnnounce %} + Announce + {% elseif forumUnannounce %} + Unannounce + {% endif %} + {% if forumLock %} + Lock + {% elseif forumUnlock %} + Unlock + {% endif %} + {% if forumRestore %} + Restore + {% endif %} + {% if forumTrash %} + Trash + {% elseif forumPrune %} + Prune + {% endif %} {% include 'elements/pagination.twig' %}
diff --git a/templates/yuuno/forum/topicEntry.twig b/templates/yuuno/forum/topicEntry.twig index bb6bfa2..efe584b 100644 --- a/templates/yuuno/forum/topicEntry.twig +++ b/templates/yuuno/forum/topicEntry.twig @@ -1,6 +1,6 @@