2023-08-04 20:51:02 +00:00
< ? php
namespace Misuzu\Home ;
2023-08-31 00:38:20 +00:00
use RuntimeException ;
2023-08-04 20:51:02 +00:00
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 {
2023-08-05 13:50:15 +00:00
$postInfos = $this -> news -> getPosts (
2023-08-04 20:51:02 +00:00
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
2023-08-05 13:50:15 +00:00
$this -> newsCategoryInfos [ $categoryId ] = $categoryInfo = $this -> news -> getCategory ( postInfo : $postInfo );
2023-08-04 20:51:02 +00:00
$commentsCount = $postInfo -> hasCommentsCategoryId ()
2023-08-05 13:50:15 +00:00
? $this -> comments -> countPosts ( categoryInfo : $postInfo -> getCommentsCategoryId (), deleted : false ) : 0 ;
2023-08-04 20:51:02 +00:00
$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 );
2023-08-05 13:50:15 +00:00
$changelog = $this -> changelog -> getChanges ( pagination : new Pagination ( 10 ));
2023-08-04 20:51:02 +00:00
$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 = [];
2023-08-31 00:40:07 +00:00
$this -> config -> removeValues ( 'users.newest' );
2023-08-04 20:51:02 +00:00
}
}
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 ,
]);
}
}