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->usersCtx->getUsers()->getUsers( lastActiveInMinutes: 5, deleted: false, orderBy: 'random', ); } 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) { $categoryId = $postInfo->getCategoryId(); $userInfo = $postInfo->hasUserId() ? $this->usersCtx->getUserInfo($postInfo->getUserId()) : null; 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' => $this->usersCtx->getUserColour($userInfo), '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; } #[Route('GET', '/')] #[URLInfo('index', '/')] 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->usersCtx->getUsers()->getUsers(deleted: false, birthdate: DateTime::now(), orderBy: 'random'); foreach($birthdayInfos as $birthdayInfo) $birthdays[] = [ 'info' => $birthdayInfo, 'colour' => $this->usersCtx->getUserColour($birthdayInfo), ]; $newestMember = []; if(empty($birthdays)) { $newestMemberId = $this->config->getString('users.newest'); if(!empty($newestMemberId)) try { $newestMember['info'] = $this->usersCtx->getUserInfo($newestMemberId); $newestMember['colour'] = $this->usersCtx->getUserColour($newestMemberId); } 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, ]); } #[Route('GET', '/_landing')] public function getLanding($response, $request) { $config = $this->config->getValues([ ['social.embed_linked:b'], ['landing.forum_categories:a'], 'social.linked:a' ]); if($config['social.embed_linked']) { $linkedData = [ '@context' => 'http://schema.org', '@type' => 'Organization', 'name' => $this->siteInfo->getName(), 'url' => $this->siteInfo->getURL(), 'logo' => $this->siteInfo->getExternalLogo(), '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, ]); } }