From d4d1a194afe6002172b420e664ab55d398efcefb Mon Sep 17 00:00:00 2001 From: samerton Date: Sun, 6 Nov 2022 18:54:45 +0000 Subject: [PATCH 1/4] Various performance improvements --- modules/Core/widgets/ProfilePostsWidget.php | 45 +- modules/Core/widgets/StatsWidget.php | 31 +- modules/Forum/classes/Forum.php | 484 ++++++++++++-------- modules/Forum/pages/forum/delete.php | 2 +- modules/Forum/pages/forum/delete_post.php | 6 +- modules/Forum/pages/forum/merge.php | 19 +- modules/Forum/pages/forum/move.php | 21 +- modules/Forum/widgets/LatestPostsWidget.php | 4 +- 8 files changed, 365 insertions(+), 247 deletions(-) diff --git a/modules/Core/widgets/ProfilePostsWidget.php b/modules/Core/widgets/ProfilePostsWidget.php index bf8157d659..7996ed0676 100644 --- a/modules/Core/widgets/ProfilePostsWidget.php +++ b/modules/Core/widgets/ProfilePostsWidget.php @@ -1,9 +1,8 @@ _cache->isCached('profile_posts_' . $user_id)) { $posts_array = $this->_cache->retrieve('profile_posts_' . $user_id); } else { - $posts = DB::getInstance()->query('SELECT * FROM nl2_user_profile_wall_posts ORDER BY time DESC LIMIT 5')->results(); - foreach ($posts as $post) { - $post_author = new User($post->author_id); - - if ($this->_user->isLoggedIn()) { - if ($this->_user->isBlocked($post->author_id, $this->_user->data()->id)) { - continue; - } - if ($post_author->isPrivateProfile() && !$this->_user->hasPermission('profile.private.bypass')) { - continue; - } - } else if ($post_author->isPrivateProfile()) { - continue; + if ($this->_user->isLoggedIn()) { + if ($this->_user->hasPermission('profile.private.bypass')) { + $posts = DB::getInstance()->query('SELECT * FROM nl2_user_profile_wall_posts ORDER BY `time` DESC LIMIT 5')->results(); + } else { + $posts = DB::getInstance()->query( + <<results(); } + } else { + $posts = DB::getInstance()->query( + <<results(); + } + foreach ($posts as $post) { + $post_author = new User($post->author_id); $post_user = new User($post->user_id); $link = rtrim($post_user->getProfileURL(), '/'); diff --git a/modules/Core/widgets/StatsWidget.php b/modules/Core/widgets/StatsWidget.php index f7f328182f..2a210236f7 100644 --- a/modules/Core/widgets/StatsWidget.php +++ b/modules/Core/widgets/StatsWidget.php @@ -2,7 +2,7 @@ /* * Made by Samerton * https://github.com/NamelessMC/Nameless/ - * NamelessMC version 2.0.0-pr8 + * NamelessMC version 2.0.2 * * License: MIT * @@ -36,28 +36,24 @@ public function initialise(): void { $this->_cache->setCache('statistics'); if ($this->_cache->isCached('statistics')) { - $users_query = $this->_cache->retrieve('statistics'); $users_registered = $users_query['users_registered']; $latest_member = $users_query['latest_member']; } else { + $users_query = DB::getInstance()->query('SELECT `id` FROM nl2_users ORDER BY `joined` DESC LIMIT 1')->first()->id; + $users_registered = DB::getInstance()->query('SELECT COUNT(*) as c FROM nl2_users')->first()->c; - $users_query = DB::getInstance()->orderAll('users', 'joined', 'DESC')->results(); - $users_registered = count($users_query); - - $latest_user = new User($users_query[0]->id); + $latest_user = new User($users_query); $latest_member = [ 'style' => $latest_user->getGroupStyle(), 'profile' => $latest_user->getProfileURL(), 'avatar' => $latest_user->getAvatar(), 'username' => $latest_user->getDisplayname(true), 'nickname' => $latest_user->getDisplayname(), - 'id' => Output::getClean($users_query[0]->id) + 'id' => Output::getClean($users_query) ]; - $users_query = null; - $this->_cache->store( 'statistics', [ @@ -70,8 +66,7 @@ public function initialise(): void { } if (!$this->_cache->isCached('online_users')) { - $online_users = DB::getInstance()->query('SELECT count(*) FROM nl2_users WHERE last_online > ?', [strtotime('-5 minutes')])->first(); - $online_users = $online_users->{'count(*)'}; + $online_users = DB::getInstance()->query('SELECT COUNT(*) as c FROM nl2_users WHERE last_online > ?', [strtotime('-5 minutes')])->first()->c; $this->_cache->store('online_users', $online_users, 60); } else { $online_users = $this->_cache->retrieve('online_users'); @@ -79,8 +74,7 @@ public function initialise(): void { if (!$this->_cache->isCached('online_guests')) { try { - $online_guests = DB::getInstance()->query('SELECT count(*) FROM nl2_online_guests WHERE last_seen > ?', [strtotime('-5 minutes')])->first(); - $online_guests = $online_guests->{'count(*)'}; + $online_guests = DB::getInstance()->query('SELECT COUNT(*) as c FROM nl2_online_guests WHERE last_seen > ?', [strtotime('-5 minutes')])->first()->c; $this->_cache->store('online_guests', $online_guests, 60); } catch (Exception $e) { // Upgrade script hasn't been run @@ -90,22 +84,17 @@ public function initialise(): void { $online_guests = $this->_cache->retrieve('online_guests'); } - $forum_module = DB::getInstance()->get('modules', ['name', 'Forum'])->results(); - $forum_module = $forum_module[0]; - - if ($forum_module->enabled) { + if (Util::isModuleEnabled('Forum')) { $this->_cache->setCache('forum_stats'); if (!$this->_cache->isCached('total_topics')) { - $total_topics = DB::getInstance()->query('SELECT count(*) FROM nl2_topics WHERE deleted = 0')->first(); - $total_topics = $total_topics->{'count(*)'}; + $total_topics = DB::getInstance()->query('SELECT COUNT(*) as c FROM nl2_topics WHERE deleted = 0')->first()->c; $this->_cache->store('total_topics', $total_topics, 60); } else { $total_topics = $this->_cache->retrieve('total_topics'); } if (!$this->_cache->isCached('total_posts')) { - $total_posts = DB::getInstance()->query('SELECT count(*) FROM nl2_posts WHERE deleted = 0')->first(); - $total_posts = $total_posts->{'count(*)'}; + $total_posts = DB::getInstance()->query('SELECT COUNT(*) as c FROM nl2_posts WHERE deleted = 0')->first()->c; $this->_cache->store('total_posts', $total_posts, 60); } else { $total_posts = $this->_cache->retrieve('total_posts'); diff --git a/modules/Forum/classes/Forum.php b/modules/Forum/classes/Forum.php index d0192ecbbc..0b36f75d5c 100644 --- a/modules/Forum/classes/Forum.php +++ b/modules/Forum/classes/Forum.php @@ -40,89 +40,159 @@ public function listAllForums(array $groups = [0], int $user_id = 0): array { $user_id = 0; } + $groups_in = implode(',', $groups); + // Get a list of parent forums - $parent_forums = $this->_db->orderWhere('forums', 'parent = 0', 'forum_order', 'ASC')->results(); + $parent_forums = $this->_db->query( + <<forumExist($forum->id, $groups)) { - $return[$forum->id]['description'] = Output::getClean($forum->forum_description); - $return[$forum->id]['title'] = Output::getClean($forum->forum_title); - $return[$forum->id]['icon'] = Output::getPurified($forum->icon); - - // Get subforums - $forums = $this->_db->orderWhere('forums', 'parent = ' . $forum->id, 'forum_order', 'ASC')->results(); - if (count($forums)) { - foreach ($forums as $item) { - if ($this->forumExist($item->id, $groups)) { - $return[$forum->id]['subforums'][$item->id] = $item; - $return[$forum->id]['subforums'][$item->id]->forum_title = Output::getClean($item->forum_title); - $return[$forum->id]['subforums'][$item->id]->forum_description = Output::getClean($item->forum_description); - $return[$forum->id]['subforums'][$item->id]->icon = Output::getPurified($item->icon); - $return[$forum->id]['subforums'][$item->id]->link = URL::build('/forum/view/' . urlencode($item->id) . '-' . $this->titleToURL($item->forum_title)); - $return[$forum->id]['subforums'][$item->id]->redirect_to = Output::getClean($item->redirect_url); - - // Get topic/post count - $topics = $this->_db->orderWhere('topics', 'forum_id = ' . $item->id . ' AND deleted = 0', 'id', 'ASC')->results(); - $topics = count($topics); - $return[$forum->id]['subforums'][$item->id]->topics = $topics; - - $posts = $this->_db->orderWhere('posts', 'forum_id = ' . $item->id . ' AND deleted = 0', 'id', 'ASC')->results(); - $posts = count($posts); - $return[$forum->id]['subforums'][$item->id]->posts = $posts; - - // Can the user view other topics - if ($item->last_user_posted == $user_id || $this->canViewOtherTopics($item->id, $groups)) { - if ($item->last_topic_posted) { - // Last reply - $last_reply = $this->_db->orderWhere('posts', 'topic_id = ' . $item->last_topic_posted, 'created', 'DESC')->results(); - } else { - $last_reply = null; - } - } else { - $last_topic = $this->_db->orderWhere('topics', 'forum_id = ' . $item->id . ' AND deleted = 0 AND topic_creator = ' . $user_id, 'topic_reply_date', 'DESC')->results(); - if (count($last_topic)) { - $last_reply = $this->_db->orderWhere('posts', 'topic_id = ' . $last_topic[0]->id, 'created', 'DESC')->results(); - } else { - $last_reply = null; - } + if ($parent_forums->count()) { + foreach ($parent_forums->results() as $forum) { + $return[$forum->id]['description'] = Output::getClean($forum->forum_description); + $return[$forum->id]['title'] = Output::getClean($forum->forum_title); + $return[$forum->id]['icon'] = Output::getPurified($forum->icon); + + // Get discussion forums + $forums = $this->_db->query( + <<id] + ); + + if ($forums->count()) { + foreach ($forums->results() as $item) { + $return[$forum->id]['subforums'][$item->id] = $item; + $return[$forum->id]['subforums'][$item->id]->forum_title = Output::getClean($item->forum_title); + $return[$forum->id]['subforums'][$item->id]->forum_description = Output::getClean($item->forum_description); + $return[$forum->id]['subforums'][$item->id]->icon = Output::getPurified($item->icon); + $return[$forum->id]['subforums'][$item->id]->link = URL::build('/forum/view/' . urlencode($item->id) . '-' . $this->titleToURL($item->forum_title)); + $return[$forum->id]['subforums'][$item->id]->redirect_to = Output::getClean($item->redirect_url); + + // Get latest post from any sub-subforums + $subforums = $this->getAnySubforums($item->id, $groups, 0, true, $user_id); + + $latest_post = [$item->last_post_date, $item->last_user_posted, $item->last_topic_posted]; + + if (count($subforums)) { + $return[$forum->id]['subforums'][$item->id]->subforums = []; + + foreach ($subforums as $subforum) { + if (isset($subforum->last_post_date) && $subforum->last_post_date > $latest_post[0]) { + $latest_post = [$subforum->last_post_date, $subforum->last_user_posted, $subforum->last_topic_posted]; } - if (isset($last_reply) && count($last_reply)) { - $n = 0; - while (isset($last_reply[$n]) && $last_reply[$n]->deleted == 1) { - $n++; - } - - if (!isset($last_reply[$n])) { - continue; - } + $return[$forum->id]['subforums'][$item->id]->subforums[$subforum->id] = new stdClass(); + $return[$forum->id]['subforums'][$item->id]->subforums[$subforum->id]->title = $subforum->forum_title; + $return[$forum->id]['subforums'][$item->id]->subforums[$subforum->id]->link = URL::build('/forum/view/' . urlencode($subforum->id) . '-' . $this->titleToURL($subforum->forum_title)); + $return[$forum->id]['subforums'][$item->id]->subforums[$subforum->id]->icon = $subforum->icon; + } + } - // Title - $last_topic = $this->_db->get('topics', ['id', $last_reply[$n]->topic_id])->results(); + // Can the user view other topics? + if ($this->canViewOtherTopics($item->id, $groups)) { + $topics = $this->_db->query( + <<id] + )->first()->count; + + $posts = $this->_db->query( + <<id] + )->first()->count; - $return[$forum->id]['subforums'][$item->id]->last_post = $last_reply[$n]; - $return[$forum->id]['subforums'][$item->id]->last_post->title = Output::getClean($last_topic[0]->topic_title); - $return[$forum->id]['subforums'][$item->id]->last_post->link = URL::build('/forum/topic/' . urlencode($last_reply[$n]->topic_id) . '-' . $this->titleToURL($last_topic[0]->topic_title), 'pid=' . $last_reply[0]->id); - } + } else { + $topics = $this->_db->query( + <<id], + $user_id + )->first()->count; + + $posts = $this->_db->query( + <<id, $user_id] + )->first()->count; + } - // Get list of subforums (names + links) - $subforums = $this->_db->orderWhere('forums', 'parent = ' . $item->id, 'forum_order', 'ASC')->results(); - if (count($subforums)) { - foreach ($subforums as $subforum) { - if ($this->forumExist($subforum->id, $groups)) { - if (!isset($return[$forum->id]['subforums'][$item->id]->subforums)) { - $return[$forum->id]['subforums'][$item->id]->subforums = []; - } - $return[$forum->id]['subforums'][$item->id]->subforums[$subforum->id] = new stdClass(); - $return[$forum->id]['subforums'][$item->id]->subforums[$subforum->id]->title = Output::getClean($subforum->forum_title); - $return[$forum->id]['subforums'][$item->id]->subforums[$subforum->id]->link = URL::build('/forum/view/' . urlencode($subforum->id) . '-' . $this->titleToURL($subforum->forum_title)); - $return[$forum->id]['subforums'][$item->id]->subforums[$subforum->id]->icon = Output::getPurified($subforum->icon); - } - } - } + $return[$forum->id]['subforums'][$item->id]->topics = $topics; + $return[$forum->id]['subforums'][$item->id]->posts = $posts; + + // Get latest topic info + if ($latest_post[0]) { + $latest_topic = $this->_db->query( + <<count() && $latest_topic = $latest_topic->first()) { + $return[$forum->id]['subforums'][$item->id]->last_post = $latest_topic; + $return[$forum->id]['subforums'][$item->id]->last_post->title = Output::getClean($latest_topic->topic_title); + $return[$forum->id]['subforums'][$item->id]->last_post->link = URL::build('/forum/topic/' . urlencode($latest_post[2]) . '-' . $this->titleToURL($latest_topic->topic_title), 'pid=' . $latest_topic->pid); } } } @@ -210,13 +280,14 @@ public function canViewOtherTopics(int $forum_id, array $groups = [0]): bool { } /** - * Get the newest 50 topics this user/group can view + * Get the newest x topics this user/group can view * * @param array $groups Array of groups the user is in * @param int $user_id User ID - * @return array 50 latest topics + * @param int $limit Limit of topics to return, default 50 + * @return array Latest topics */ - public function getLatestDiscussions(array $groups = [0], int $user_id = 0): array { + public function getLatestDiscussions(array $groups = [0], int $user_id = 0, int $limit = 50): array { if (!$user_id) { $user_id = 0; } @@ -232,32 +303,34 @@ public function getLatestDiscussions(array $groups = [0], int $user_id = 0): arr return []; } + $all_topics_forums_string = ''; foreach ($all_topics_forums as $forum) { $all_topics_forums_string .= $forum->forum_id . ','; } $all_topics_forums_string = rtrim($all_topics_forums_string, ','); if (count($own_topics_forums)) { + $own_topics_forums_string = ''; foreach ($own_topics_forums as $forum) { $own_topics_forums_string .= $forum->forum_id . ','; } $own_topics_forums_string = rtrim($own_topics_forums_string, ','); return DB::getInstance()->query( - '(SELECT topics.id as id, topics.forum_id as forum_id, topics.topic_title as topic_title, topics.topic_creator as topic_creator, topics.topic_last_user as topic_last_user, topics.topic_date as topic_date, topics.topic_reply_date as topic_reply_date, topics.topic_views as topic_views, topics.locked as locked, topics.sticky as sticky, topics.label as label, topics.deleted as deleted, posts.id as last_post_id FROM nl2_topics topics LEFT JOIN nl2_posts posts ON topics.id = posts.topic_id AND posts.id = (SELECT MAX(id) FROM nl2_posts p WHERE p.topic_id = topics.id AND p.deleted = 0) WHERE topics.deleted = 0 AND topics.forum_id IN (' . $all_topics_forums_string . ') ORDER BY topics.topic_reply_date DESC LIMIT 50) + "(SELECT topics.id as id, topics.forum_id as forum_id, topics.topic_title as topic_title, topics.topic_creator as topic_creator, topics.topic_last_user as topic_last_user, topics.topic_date as topic_date, topics.topic_reply_date as topic_reply_date, topics.topic_views as topic_views, topics.locked as locked, topics.sticky as sticky, topics.label as label, topics.deleted as deleted, posts.id as last_post_id FROM nl2_topics topics LEFT JOIN nl2_posts posts ON topics.id = posts.topic_id AND posts.id = (SELECT MAX(id) FROM nl2_posts p WHERE p.topic_id = topics.id AND p.deleted = 0) WHERE topics.deleted = 0 AND topics.forum_id IN (' . $all_topics_forums_string . ') ORDER BY topics.topic_reply_date DESC LIMIT $limit) UNION - (SELECT topics.id as id, topics.forum_id as forum_id, topics.topic_title as topic_title, topics.topic_creator as topic_creator, topics.topic_last_user as topic_last_user, topics.topic_date as topic_date, topics.topic_reply_date as topic_reply_date, topics.topic_views as topic_views, topics.locked as locked, topics.sticky as sticky, topics.label as label, topics.deleted as deleted, posts.id as last_post_id FROM nl2_topics topics LEFT JOIN nl2_posts posts ON topics.id = posts.topic_id AND posts.id = (SELECT MAX(id) FROM nl2_posts p WHERE p.topic_id = topics.id AND p.deleted = 0) WHERE topics.deleted = 0 AND ((topics.forum_id IN (' . $own_topics_forums_string . ') AND topics.topic_creator = ?) OR topics.sticky = 1) ORDER BY topics.topic_reply_date DESC LIMIT 50) - ORDER BY topic_reply_date DESC LIMIT 50', + (SELECT topics.id as id, topics.forum_id as forum_id, topics.topic_title as topic_title, topics.topic_creator as topic_creator, topics.topic_last_user as topic_last_user, topics.topic_date as topic_date, topics.topic_reply_date as topic_reply_date, topics.topic_views as topic_views, topics.locked as locked, topics.sticky as sticky, topics.label as label, topics.deleted as deleted, posts.id as last_post_id FROM nl2_topics topics LEFT JOIN nl2_posts posts ON topics.id = posts.topic_id AND posts.id = (SELECT MAX(id) FROM nl2_posts p WHERE p.topic_id = topics.id AND p.deleted = 0) WHERE topics.deleted = 0 AND ((topics.forum_id IN (' . $own_topics_forums_string . ') AND topics.topic_creator = ?) OR topics.sticky = 1) ORDER BY topics.topic_reply_date DESC LIMIT $limit) + ORDER BY topic_reply_date DESC LIMIT $limit", [$user_id], true )->results(); } return DB::getInstance()->query( - 'SELECT topics.id as id, topics.forum_id as forum_id, topics.topic_title as topic_title, topics.topic_creator as topic_creator, topics.topic_last_user as topic_last_user, topics.topic_date as topic_date, topics.topic_reply_date as topic_reply_date, topics.topic_views as topic_views, topics.locked as locked, topics.sticky as sticky, topics.label as label, topics.deleted as deleted, posts.id as last_post_id + "SELECT topics.id as id, topics.forum_id as forum_id, topics.topic_title as topic_title, topics.topic_creator as topic_creator, topics.topic_last_user as topic_last_user, topics.topic_date as topic_date, topics.topic_reply_date as topic_reply_date, topics.topic_views as topic_views, topics.locked as locked, topics.sticky as sticky, topics.label as label, topics.deleted as deleted, posts.id as last_post_id FROM nl2_topics topics LEFT JOIN nl2_posts posts ON topics.id = posts.topic_id AND posts.id = (SELECT MAX(id) FROM nl2_posts p WHERE p.topic_id = topics.id AND p.deleted = 0) - WHERE topics.deleted = 0 AND topics.forum_id IN (' . $all_topics_forums_string . ') ORDER BY topics.topic_reply_date DESC LIMIT 50', + WHERE topics.deleted = 0 AND topics.forum_id IN (' . $all_topics_forums_string . ') ORDER BY topics.topic_reply_date DESC LIMIT $limit", )->results(); } @@ -319,105 +392,70 @@ public function canEditTopic(int $forum_id, array $groups = [0]): bool { /** * Update the database with the new latest forum posts. + * + * @param int $forum_id The forum ID to update */ - public function updateForumLatestPosts(): void { - $forums = $this->_db->get('forums', ['id', '<>', 0])->results(); - $latest_posts = []; - $n = 0; - - foreach ($forums as $item) { - if ($item->parent != 0) { - $latest_post_query = $this->_db->orderWhere('posts', 'forum_id = ' . $item->id, 'post_date', 'DESC')->results(); - - if (!empty($latest_post_query)) { - foreach ($latest_post_query as $latest_post) { - if ($latest_post->deleted != 1) { - // Ensure topic isn't deleted - $topic_query = $this->_db->get('topics', ['id', $latest_post->topic_id])->results(); - - if (empty($topic_query)) { - continue; - } - - $latest_posts[$n]['forum_id'] = $item->id; - if ($latest_post->created) { - $latest_posts[$n]['date'] = $latest_post->created; - } else { - $latest_posts[$n]['date'] = strtotime($latest_post->post_date); - } - $latest_posts[$n]['author'] = $latest_post->post_creator; - $latest_posts[$n]['topic_id'] = $latest_post->topic_id; - - break; - } - } - } - - if (!isset($latest_posts[$n])) { - $latest_posts[$n]['forum_id'] = $item->id; - $latest_posts[$n]['date'] = null; - $latest_posts[$n]['author'] = null; - $latest_posts[$n]['topic_id'] = null; - } - - $n++; - } - } - - $forums = null; - - if (count($latest_posts)) { - foreach ($latest_posts as $latest_post) { - $this->_db->update('forums', $latest_post['forum_id'], [ - 'last_post_date' => $latest_post['date'], - 'last_user_posted' => $latest_post['author'], - 'last_topic_posted' => $latest_post['topic_id'] - ]); - } + public function updateForumLatestPosts(int $forum_id): void { + echo "Checking latest posts for $forum_id
"; + $latest_post = $this->_db->query( + <<count() && $latest_post = $latest_post->first()) { + $this->_db->update('forums', $forum_id, [ + 'last_post_date' => $latest_post->created ?? strtotime($latest_post->post_date), + 'last_user_posted' => $latest_post->post_creator, + 'last_topic_posted' => $latest_post->topic_id, + ]); + } else { + $this->_db->update('forums', $forum_id, [ + 'last_post_date' => null, + 'last_user_posted' => null, + 'last_topic_posted' => null, + ]); } - - $latest_posts = null; } /** * Update the database with the new latest forum topic posts. + * + * @param int $topic_id The topic ID to update */ - public function updateTopicLatestPosts(): void { - $topics = $this->_db->get('topics', ['id', '<>', 0])->results(); - $latest_posts = []; - $n = 0; - - foreach ($topics as $topic) { - $latest_post_query = $this->_db->orderWhere('posts', 'topic_id = ' . $topic->id, 'post_date', 'DESC')->results(); - - if (count($latest_post_query)) { - foreach ($latest_post_query as $latest_post) { - if ($latest_post->deleted != 1) { - $latest_posts[$n]['topic_id'] = $topic->id; - - if ($latest_post->created != null) { - $latest_posts[$n]['date'] = $latest_post->created; - } else { - $latest_posts[$n]['date'] = strtotime($latest_post->post_date); - } - - $latest_posts[$n]['author'] = $latest_post->post_creator; - - break; - } - } - } - - $n++; - } - - foreach ($latest_posts as $latest_post) { - if (!empty($latest_post['date'])) { - $this->_db->update('topics', $latest_post['topic_id'], [ - 'topic_reply_date' => $latest_post['date'], - 'topic_last_user' => $latest_post['author'] - ]); - } + public function updateTopicLatestPosts(int $topic_id): void { + $latest_post = $this->_db->query( + <<count() && $latest_post = $latest_post->first()) { + $this->_db->update('topics', $topic_id, [ + 'topic_reply_date' => $latest_post->created ?? strtotime($latest_post->post_date), + 'topic_last_user' => $latest_post->post_creator, + ]); + } else { + $this->_db->update('forums', $forum_id, [ + 'last_post_date' => null, + 'last_user_posted' => null, + 'last_topic_posted' => null, + ]); } } @@ -633,35 +671,101 @@ public function getPosts(int $tid = null) { * @param int $forum_id The forum ID * @param array $groups The user groups * @param int $depth The depth of the subforums to get + * @param ?bool $onlyOwnTopics Whether to only get forums in which the user can only view their own topics (default false) + * @param ?int $user_id Current user ID (default 0) - only used if $onlyOwnTopics is true * @return array Subforums at any level for a forum */ - public function getAnySubforums(int $forum_id, array $groups = [0], int $depth = 0): array { + public function getAnySubforums( + int $forum_id, + array $groups = [0], + int $depth = 0, + ?bool $onlyOwnTopics = false, + ?int $user_id = 0 + ): array { if ($depth == 10) { return []; } $ret = []; - - $subforums_query = $this->_db->query('SELECT * FROM nl2_forums WHERE parent = ? ORDER BY forum_order ASC', [$forum_id]); + $groups_in = implode(',', $groups); + + $subforums_query = $this->_db->query( + <<count()) { return $ret; } foreach ($subforums_query->results() as $result) { - if ($this->forumExist($result->id, $groups)) { - $to_add = new stdClass(); - $to_add->id = Output::getClean($result->id); - $to_add->forum_title = Output::getClean($result->forum_title); - $to_add->category = false; - $ret[] = $to_add; - - $subforums = $this->getAnySubforums($result->id, $groups, ++$depth); - - if (count($subforums)) { - foreach ($subforums as $subforum) { - $ret[] = $subforum; - } + $to_add = new stdClass(); + $to_add->id = Output::getClean($result->id); + $to_add->forum_title = Output::getClean($result->forum_title); + $to_add->icon = Output::getPurified($result->icon); + $to_add->category = false; + + // Latest post + if ($onlyOwnTopics && $result->view_other_topics != '1') { + // Get the latest topic that the user can view + $latest_post = $this->_db->query( + <<id, $user_id] + ); + + if ($latest_post->count() && $latest_post = $latest_post->first()) { + $to_add->last_post_date = $latest_post->created ?? strtotime($latest_post->post_date); + $to_add->last_user_posted = $latest_post->post_creator; + $to_add->last_topic_posted = $latest_post->topic_id; + } + } else { + $to_add->last_post_date = $result->last_post_date; + $to_add->last_user_posted = $result->last_user_posted; + $to_add->last_topic_posted = $result->last_topic_posted; + } + + $ret[] = $to_add; + + $subforums = $this->getAnySubforums($result->id, $groups, ++$depth); + + if (count($subforums)) { + foreach ($subforums as $subforum) { + $ret[] = $subforum; } } } diff --git a/modules/Forum/pages/forum/delete.php b/modules/Forum/pages/forum/delete.php index 8a83387b53..5a1c9cf14e 100644 --- a/modules/Forum/pages/forum/delete.php +++ b/modules/Forum/pages/forum/delete.php @@ -58,7 +58,7 @@ } // Update latest posts in forums - $forum->updateForumLatestPosts(); + $forum->updateForumLatestPosts($topic->forum_id); } Redirect::to(URL::build('/forum')); diff --git a/modules/Forum/pages/forum/delete_post.php b/modules/Forum/pages/forum/delete_post.php index d566764d3a..08faf7a69a 100644 --- a/modules/Forum/pages/forum/delete_post.php +++ b/modules/Forum/pages/forum/delete_post.php @@ -72,8 +72,10 @@ } // Update latest posts in categories - $forum->updateForumLatestPosts(); - $forum->updateTopicLatestPosts(); + $forum->updateForumLatestPosts($forum_id); + if (Input::get('tid')) { + $forum->updateTopicLatestPosts(intval(Input::get('tid'))); + } Redirect::to($redirect); diff --git a/modules/Forum/pages/forum/merge.php b/modules/Forum/pages/forum/merge.php index b7f8a36a42..3021af7495 100644 --- a/modules/Forum/pages/forum/merge.php +++ b/modules/Forum/pages/forum/merge.php @@ -39,17 +39,22 @@ $posts_to_move = DB::getInstance()->get('posts', ['topic_id', $topic_id])->results(); if ($validation->passed()) { + $posts = implode(',', array_column($posts_to_move, 'id')); + DB::getInstance()->query( + "UPDATE nl2_posts SET `topic_id` = ? WHERE `id` IN ($posts)", + [Input::get('merge')] + ); + + $newTopic = DB::getInstance()->get('topics', ['id', Input::get('merge')])->first(); - foreach ($posts_to_move as $post_to_move) { - DB::getInstance()->update('posts', $post_to_move->id, [ - 'topic_id' => Input::get('merge') - ]); - } DB::getInstance()->delete('topics', ['id', $topic_id]); Log::getInstance()->log(Log::Action('forums/merge')); // Update latest posts in categories - $forum->updateForumLatestPosts(); - $forum->updateTopicLatestPosts(); + $forum->updateForumLatestPosts($forum_id); + if ($newTopic->forum_id != $forum_id) { + $forum->updateForumLatestPosts($newTopic->forum_id); + } + $forum->updateTopicLatestPosts(intval(Input::get('merge'))); Redirect::to(URL::build('/forum/topic/' . urlencode(Input::get('merge')))); diff --git a/modules/Forum/pages/forum/move.php b/modules/Forum/pages/forum/move.php index 95496eea14..6ddce20ef7 100644 --- a/modules/Forum/pages/forum/move.php +++ b/modules/Forum/pages/forum/move.php @@ -44,22 +44,25 @@ $posts_to_move = DB::getInstance()->get('posts', ['topic_id', $topic_id])->results(); if ($validation->passed()) { - DB::getInstance()->update('topics', $topic->id, [ - 'forum_id' => Input::get('forum') + 'forum_id' => intval(Input::get('forum')) ]); - foreach ($posts_to_move as $post_to_move) { - DB::getInstance()->update('posts', $post_to_move->id, [ - 'forum_id' => Input::get('forum') - ]); - } + $posts = implode(',', array_column($posts_to_move, 'id')); + echo '
', print_r($posts), '
'; + DB::getInstance()->query( + "UPDATE nl2_posts SET `forum_id` = ? WHERE `id` IN ($posts)", + [intval(Input::get('forum'))] + ); //TODO: Topic name & and Forums name Log::getInstance()->log(Log::Action('forums/move'), Output::getClean($topic_id) . ' => ' . Output::getClean(Input::get('forum'))); // Update latest posts in categories - $forum->updateForumLatestPosts(); - $forum->updateTopicLatestPosts(); + $forum->updateForumLatestPosts(intval(Input::get('forum'))); + if (Input::get('forum') != $forum_id) { + $forum->updateForumLatestPosts($forum_id); + } + $forum->updateTopicLatestPosts($topic->id); Redirect::to(URL::build('/forum/topic/' . $topic_id)); diff --git a/modules/Forum/widgets/LatestPostsWidget.php b/modules/Forum/widgets/LatestPostsWidget.php index dc9e8b9b74..da341eb965 100644 --- a/modules/Forum/widgets/LatestPostsWidget.php +++ b/modules/Forum/widgets/LatestPostsWidget.php @@ -55,7 +55,7 @@ public function initialise(): void { } else { // Generate latest posts - $discussions = $forum->getLatestDiscussions($user_groups, ($this->_user->isLoggedIn() ? $this->_user->data()->id : 0)); + $discussions = $forum->getLatestDiscussions($user_groups, ($this->_user->isLoggedIn() ? $this->_user->data()->id : 0), 5); $n = 0; // Calculate the number of discussions to display @@ -74,7 +74,7 @@ public function initialise(): void { $forum_name = Output::getPurified($forum_name[0]->forum_title); // Get the number of replies - $posts = $db->get('posts', ['topic_id', $discussion->id])->count(); + $posts = $db->query('SELECT COUNT(*) as c FROM nl2_posts WHERE `topic_id` = ? AND `deleted` = 0', [$discussion->id])->first()->c; // Is there a label? if ($discussion->label != 0) { From 89367bdb6891f5cfd52527c38b60c159705152ba Mon Sep 17 00:00:00 2001 From: samerton Date: Sun, 6 Nov 2022 19:04:54 +0000 Subject: [PATCH 2/4] Remove debug --- modules/Forum/pages/forum/move.php | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/Forum/pages/forum/move.php b/modules/Forum/pages/forum/move.php index 6ddce20ef7..3b1ba48e96 100644 --- a/modules/Forum/pages/forum/move.php +++ b/modules/Forum/pages/forum/move.php @@ -48,7 +48,6 @@ 'forum_id' => intval(Input::get('forum')) ]); $posts = implode(',', array_column($posts_to_move, 'id')); - echo '
', print_r($posts), '
'; DB::getInstance()->query( "UPDATE nl2_posts SET `forum_id` = ? WHERE `id` IN ($posts)", [intval(Input::get('forum'))] From b4b2dad50d6a41aec1803f8fd5bca772cfca5a4f Mon Sep 17 00:00:00 2001 From: samerton Date: Sun, 6 Nov 2022 19:05:40 +0000 Subject: [PATCH 3/4] Remove more debug --- modules/Forum/classes/Forum.php | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/Forum/classes/Forum.php b/modules/Forum/classes/Forum.php index 0b36f75d5c..5879f70b63 100644 --- a/modules/Forum/classes/Forum.php +++ b/modules/Forum/classes/Forum.php @@ -396,7 +396,6 @@ public function canEditTopic(int $forum_id, array $groups = [0]): bool { * @param int $forum_id The forum ID to update */ public function updateForumLatestPosts(int $forum_id): void { - echo "Checking latest posts for $forum_id
"; $latest_post = $this->_db->query( << Date: Tue, 8 Nov 2022 18:39:33 +0000 Subject: [PATCH 4/4] Improve StaffCP total users widget --- modules/Core/collections/panel/TotalUsers.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/Core/collections/panel/TotalUsers.php b/modules/Core/collections/panel/TotalUsers.php index ba5e5d29a8..bde27bbcb4 100644 --- a/modules/Core/collections/panel/TotalUsers.php +++ b/modules/Core/collections/panel/TotalUsers.php @@ -34,11 +34,11 @@ public function __construct(Smarty $smarty, Language $language, Cache $cache) { public function getContent(): string { // Get the number of total users - $users_query = DB::getInstance()->get('users', ['id', '<>', 0])->results(); + $users_query = DB::getInstance()->query('SELECT COUNT(*) AS c FROM nl2_users')->first()->c; $this->_smarty->assign([ 'TITLE' => $this->_language->get('admin', 'total_users'), - 'VALUE' => count($users_query) + 'VALUE' => $users_query ]); return $this->_smarty->fetch('collections/dashboard_stats/total_users.tpl');