283 lines
9.9 KiB
PHP
283 lines
9.9 KiB
PHP
<?php
|
|
namespace Misuzu\Home;
|
|
|
|
use Index\DateTime;
|
|
use Index\Data\DbTools;
|
|
use Index\Data\IDbConnection;
|
|
use Index\Routing\IRouter;
|
|
use Misuzu\Pagination;
|
|
use Misuzu\Template;
|
|
use Misuzu\Auth\AuthInfo;
|
|
use Misuzu\Changelog\Changelog;
|
|
use Misuzu\Comments\Comments;
|
|
use Misuzu\Config\IConfig;
|
|
use Misuzu\Counters\Counters;
|
|
use Misuzu\News\News;
|
|
use Misuzu\Users\Users;
|
|
|
|
class HomeRoutes {
|
|
private IConfig $config;
|
|
private IDbConnection $dbConn;
|
|
private AuthInfo $authInfo;
|
|
private Changelog $changelog;
|
|
private Comments $comments;
|
|
private Counters $counters;
|
|
private News $news;
|
|
private Users $users;
|
|
|
|
public function __construct(
|
|
IRouter $router,
|
|
IConfig $config,
|
|
IDbConnection $dbConn,
|
|
AuthInfo $authInfo,
|
|
Changelog $changelog,
|
|
Comments $comments,
|
|
Counters $counters,
|
|
News $news,
|
|
Users $users
|
|
) {
|
|
$this->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->getAllPosts(
|
|
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->getCategoryByPost($postInfo);
|
|
|
|
$commentsCount = $postInfo->hasCommentsCategoryId()
|
|
? $this->comments->countPosts($postInfo->getCommentsCategoryId(), includeReplies: true) : 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->getAllChanges(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 = [];
|
|
$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,
|
|
]);
|
|
}
|
|
}
|