config = $config; $this->dbConn = $dbConn; $this->authInfo = $authInfo; $this->changelog = $changelog; $this->comments = $comments; $this->counters = $counters; $this->news = $news; $this->users = $users; $router->get('/', [$this, 'getIndex']); if(MSZ_DEBUG) $router->get('/dev-landing', [$this, 'getLanding']); $router->get('/index.php', function($response) { $response->redirect(url('index'), true); }); } private function getStats(): array { return $this->counters->get([ 'users:active', 'users:online:recent', 'users:online:today', 'comments:posts:visible', 'forum:topics:visible', 'forum:posts:visible', ]); } private function getOnlineUsers(): array { return $this->users->getUsers( lastActiveInMinutes: 5, deleted: false, orderBy: 'random', ); } private array $userInfos = []; private array $userColours = []; private array $newsCategoryInfos = []; private function getFeaturedNewsPosts(int $amount, bool $decorate): array { $postInfos = $this->news->getPosts( onlyFeatured: true, pagination: new Pagination($amount) ); if(!$decorate) return $postInfos; $posts = []; foreach($postInfos as $postInfo) { $userId = $postInfo->getUserId(); $categoryId = $postInfo->getCategoryId(); if(array_key_exists($userId, $this->userInfos)) { $userInfo = $this->userInfos[$userId]; $userColour = $this->userColours[$userId]; } else { try { $userInfo = $this->users->getUser($userId, 'id'); $userColour = $this->users->getUserColour($userInfo); } catch(RuntimeException $ex) { $userInfo = null; $userColour = null; } $this->userInfos[$userId] = $userInfo; $this->userColours[$userId] = $userColour; } if(array_key_exists($categoryId, $this->newsCategoryInfos)) $categoryInfo = $this->newsCategoryInfos[$categoryId]; else $this->newsCategoryInfos[$categoryId] = $categoryInfo = $this->news->getCategory(postInfo: $postInfo); $commentsCount = $postInfo->hasCommentsCategoryId() ? $this->comments->countPosts(categoryInfo: $postInfo->getCommentsCategoryId(), deleted: false) : 0; $posts[] = [ 'post' => $postInfo, 'category' => $categoryInfo, 'user' => $userInfo, 'user_colour' => $userColour, 'comments_count' => $commentsCount, ]; } return $posts; } public function getPopularForumTopics(array $categoryIds): array { $args = 0; $stmt = $this->dbConn->prepare( 'SELECT t.topic_id, c.forum_id, t.topic_title, c.forum_icon, t.topic_count_views' . ', (SELECT COUNT(*) FROM msz_forum_posts AS p WHERE p.topic_id = t.topic_id AND post_deleted IS NULL)' . ' FROM msz_forum_topics AS t' . ' LEFT JOIN msz_forum_categories AS c ON c.forum_id = t.forum_id' . ' WHERE c.forum_id IN (' . DbTools::prepareListString($categoryIds) . ') AND topic_deleted IS NULL AND topic_locked IS NULL' . ' ORDER BY (SELECT COUNT(*) FROM msz_forum_posts AS p WHERE p.topic_id = t.topic_id AND post_deleted IS NULL AND post_created > NOW() - INTERVAL 3 MONTH) DESC' . ' LIMIT 10' ); foreach($categoryIds as $categoryId) $stmt->addParameter(++$args, (string)$categoryId); $stmt->execute(); $topics = []; $result = $stmt->getResult(); while($result->next()) $topics[] = [ 'topic_id' => $result->getInteger(0), 'forum_id' => $result->getInteger(1), 'topic_title' => $result->getString(2), 'forum_icon' => $result->getString(3), 'topic_count_views' => $result->getInteger(4), 'topic_count_posts' => $result->getInteger(5), ]; return $topics; } public function getActiveForumTopics(array $categoryIds): array { $args = 0; $stmt = $this->dbConn->prepare( 'SELECT t.topic_id, c.forum_id, t.topic_title, c.forum_icon, t.topic_count_views' . ', (SELECT COUNT(*) FROM msz_forum_posts AS p WHERE p.topic_id = t.topic_id AND post_deleted IS NULL)' . ', (SELECT MAX(post_id) FROM msz_forum_posts AS p WHERE p.topic_id = t.topic_id AND post_deleted IS NULL)' . ' FROM msz_forum_topics AS t' . ' LEFT JOIN msz_forum_categories AS c ON c.forum_id = t.forum_id' . ' WHERE c.forum_id IN (' . DbTools::prepareListString($categoryIds) . ') AND topic_deleted IS NULL AND topic_locked IS NULL' . ' ORDER BY topic_bumped DESC' . ' LIMIT 10' ); foreach($categoryIds as $categoryId) $stmt->addParameter(++$args, (string)$categoryId); $stmt->execute(); $topics = []; $result = $stmt->getResult(); while($result->next()) $topics[] = [ 'topic_id' => $result->getInteger(0), 'forum_id' => $result->getInteger(1), 'topic_title' => $result->getString(2), 'forum_icon' => $result->getString(3), 'topic_count_views' => $result->getInteger(4), 'topic_count_posts' => $result->getInteger(5), 'latest_post_id' => $result->getInteger(6), ]; return $topics; } public function getIndex(...$args) { return $this->authInfo->isLoggedIn() ? $this->getHome(...$args) : $this->getLanding(...$args); } public function getHome() { $stats = $this->getStats(); $onlineUserInfos = $this->getOnlineUsers(); $featuredNews = $this->getFeaturedNewsPosts(5, true); $changelog = $this->changelog->getChanges(pagination: new Pagination(10)); $stats['users:online:recent'] = count($onlineUserInfos); $birthdays = []; $birthdayInfos = $this->users->getUsers(deleted: false, birthdate: DateTime::now(), orderBy: 'random'); foreach($birthdayInfos as $birthdayInfo) $birthdays[] = [ 'info' => $birthdayInfo, 'colour' => $this->users->getUserColour($birthdayInfo), ]; $newestMember = []; if(empty($birthdays)) { $newestMemberId = $this->config->getString('users.newest'); if(!empty($newestMemberId)) try { $newestMemberInfo = $this->users->getUser($newestMemberId, 'id'); $newestMemberColour = $this->users->getUserColour($newestMemberInfo); $newestMember['info'] = $newestMemberInfo; $newestMember['colour'] = $newestMemberColour; } catch(RuntimeException $ex) { $newestMember = []; $this->config->removeValues('users.newest'); } } return Template::renderRaw('home.home', [ 'statistics' => $stats, 'newest_member' => $newestMember, 'online_users' => $onlineUserInfos, 'birthdays' => $birthdays, 'featured_changelog' => $changelog, 'featured_news' => $featuredNews, ]); } public function getLanding() { $config = $this->config->getValues([ ['social.embed_linked:b'], ['landing.forum_categories:a'], ['site.name:s', 'Misuzu'], 'site.url:s', 'site.ext_logo:s', 'social.linked:a' ]); if($config['social.embed_linked']) { $linkedData = [ '@context' => 'http://schema.org', '@type' => 'Organization', 'name' => $config['site.name'], 'url' => $config['site.url'], 'logo' => $config['site.ext_logo'], 'same_as' => $config['social.linked'], ]; } else $linkedData = null; $stats = $this->getStats(); $onlineUserInfos = $this->getOnlineUsers(); $featuredNews = $this->getFeaturedNewsPosts(3, false); $popularTopics = $this->getPopularForumTopics($config['landing.forum_categories']); $activeTopics = $this->getActiveForumTopics($config['landing.forum_categories']); $stats['users:online:recent'] = count($onlineUserInfos); return Template::renderRaw('home.landing', [ 'statistics' => $stats, 'online_users' => $onlineUserInfos, 'featured_news' => $featuredNews, 'linked_data' => $linkedData, 'forum_popular' => $popularTopics, 'forum_active' => $activeTopics, ]); } }