2018-05-30 00:36:52 +01:00
< ? php
2025-02-24 18:44:29 +00:00
/**
* NamelessMC Forum Module
2016-11-29 22:27:19 +00:00
*
2025-02-24 18:44:29 +00:00
* @ author Samerton
2025-05-02 19:19:52 +02:00
* @ version 2.3 . 0
2025-02-24 18:44:29 +00:00
* @ license MIT
2016-11-29 22:27:19 +00:00
*/
2018-09-10 01:14:58 +01:00
class Forum_Module extends Module {
2021-10-12 12:54:07 -07:00
private Language $_language ;
private Language $_forum_language ;
2020-12-14 20:40:55 -08:00
2021-12-07 22:14:12 -08:00
public function __construct ( Language $language , Language $forum_language , Pages $pages ) {
$this -> _language = $language ;
$this -> _forum_language = $forum_language ;
2018-09-10 01:14:58 +01:00
2021-12-07 22:14:12 -08:00
$name = 'Forum' ;
2025-02-24 18:44:29 +00:00
$author = '<a href="https://samerton.dev" target="_blank" rel="nofollow noopener">Samerton</a>' ;
2026-04-19 09:44:29 +01:00
$module_version = '2.2.5' ;
$nameless_version = '2.2.5' ;
2018-09-10 01:14:58 +01:00
2021-12-07 22:14:12 -08:00
parent :: __construct ( $this , $name , $author , $module_version , $nameless_version );
2018-09-10 01:14:58 +01:00
2021-12-07 22:14:12 -08:00
// Define URLs which belong to this module
$pages -> add ( 'Forum' , '/panel/forums' , 'pages/panel/forums.php' );
$pages -> add ( 'Forum' , '/panel/forums/labels' , 'pages/panel/labels.php' );
2021-08-26 19:52:02 +02:00
$pages -> add ( 'Forum' , '/panel/forums/settings' , 'pages/panel/settings.php' );
2018-09-22 17:06:13 +01:00
2021-12-07 22:14:12 -08:00
$pages -> add ( 'Forum' , '/forum' , 'pages/forum/index.php' , 'forum' , true );
$pages -> add ( 'Forum' , '/forum/error' , 'pages/forum/error.php' );
$pages -> add ( 'Forum' , '/forum/view' , 'pages/forum/view_forum.php' );
$pages -> add ( 'Forum' , '/forum/topic' , 'pages/forum/view_topic.php' );
$pages -> add ( 'Forum' , '/forum/new' , 'pages/forum/new_topic.php' );
$pages -> add ( 'Forum' , '/forum/spam' , 'pages/forum/spam.php' );
$pages -> add ( 'Forum' , '/forum/report' , 'pages/forum/report.php' );
$pages -> add ( 'Forum' , '/forum/get_quotes' , 'pages/forum/get_quotes.php' );
$pages -> add ( 'Forum' , '/forum/delete_post' , 'pages/forum/delete_post.php' );
$pages -> add ( 'Forum' , '/forum/delete' , 'pages/forum/delete.php' );
$pages -> add ( 'Forum' , '/forum/move' , 'pages/forum/move.php' );
$pages -> add ( 'Forum' , '/forum/merge' , 'pages/forum/merge.php' );
$pages -> add ( 'Forum' , '/forum/edit' , 'pages/forum/edit.php' );
$pages -> add ( 'Forum' , '/forum/lock' , 'pages/forum/lock.php' );
$pages -> add ( 'Forum' , '/forum/stick' , 'pages/forum/stick.php' );
$pages -> add ( 'Forum' , '/forum/search' , 'pages/forum/search.php' );
// UserCP
$pages -> add ( 'Forum' , '/user/following_topics' , 'pages/user/following_topics.php' );
// Redirects
$pages -> add ( 'Forum' , '/forum/view_topic' , 'pages/forum/redirect.php' );
$pages -> add ( 'Forum' , '/forum/view_forum' , 'pages/forum/redirect.php' );
2023-03-01 11:35:10 -08:00
EventHandler :: registerListener ( UserDeletedEvent :: class , DeleteUserForumHook :: class );
EventHandler :: registerListener ( GroupClonedEvent :: class , CloneGroupForumHook :: class );
// -- Events
EventHandler :: registerEvent ( TopicCreatedEvent :: class );
EventHandler :: registerEvent ( TopicReplyCreatedEvent :: class );
// -- Pipelines
2025-05-02 19:19:52 +02:00
EventHandler :: registerEvent ( PrePostCreateEvent :: class );
EventHandler :: registerEvent ( PrePostEditEvent :: class );
EventHandler :: registerEvent ( PreTopicCreateEvent :: class );
EventHandler :: registerEvent ( PreTopicEditEvent :: class );
2022-03-31 19:47:08 +01:00
2025-05-02 19:19:52 +02:00
EventHandler :: registerListener ( PrePostCreateEvent :: class , [ MentionsHook :: class , 'preCreate' ]);
EventHandler :: registerListener ( PrePostEditEvent :: class , [ MentionsHook :: class , 'preEdit' ]);
2022-03-31 19:47:08 +01:00
2025-05-02 19:19:52 +02:00
EventHandler :: registerListener ( PreTopicCreateEvent :: class , [ MentionsHook :: class , 'preCreate' ]);
EventHandler :: registerListener ( PreTopicEditEvent :: class , [ MentionsHook :: class , 'preEdit' ]);
2023-03-07 08:26:53 -08:00
2024-07-29 18:14:39 +02:00
if ( Util :: isModuleEnabled ( 'Members' )) {
MemberListManager :: getInstance () -> registerListProvider ( new MostPostsMemberListProvider ( $forum_language ));
MemberListManager :: getInstance () -> registerListProvider ( new HighestForumReactionScoresMemberListProvider ( $forum_language ));
MemberListManager :: getInstance () -> registerMemberMetadataProvider ( function ( User $member ) use ( $forum_language ) {
return [
$forum_language -> get ( 'forum' , 'posts_title' ) =>
DB :: getInstance () -> query (
2025-05-26 11:06:51 -07:00
'SELECT COUNT(post_content) AS `count` FROM nl2_posts WHERE post_creator = ? AND deleted = 0' ,
2024-07-29 18:14:39 +02:00
[ $member -> data () -> id ]
) -> first () -> count ,
];
});
MemberListManager :: getInstance () -> registerMemberMetadataProvider ( function ( User $member ) use ( $forum_language ) {
return [
$forum_language -> get ( 'forum' , 'reaction_score' ) =>
DB :: getInstance () -> query (
'SELECT COUNT(fr.user_received) AS `count` FROM nl2_forums_reactions fr JOIN nl2_reactions r ON r.id = fr.reaction_id WHERE r.type = 2 AND fr.user_received = ?' ,
[ $member -> data () -> id ]
) -> first () -> count ,
];
});
}
2025-03-31 19:25:00 +01:00
ReactionContextsManager :: getInstance () -> provideContext ( new ForumPostReactionContext ( $forum_language ));
2025-04-29 07:43:09 -07:00
Notification :: addType (
'forum_topic_reply' ,
$forum_language -> get ( 'forum' , 'forum_topic_replies' ),
2025-04-29 12:51:01 -07:00
[ 'alert' => true , 'email' => true ],
);
Notification :: addType (
'forum_topic_mention' ,
$forum_language -> get ( 'forum' , 'forum_topic_mentions' ),
2025-04-29 07:43:09 -07:00
[ 'alert' => true , 'email' => true ],
);
2021-12-07 22:14:12 -08:00
}
2018-09-10 01:14:58 +01:00
2021-12-07 22:14:12 -08:00
public function onInstall () {
// Not necessary for Forum
}
2018-09-10 01:14:58 +01:00
2021-12-07 22:14:12 -08:00
public function onUninstall () {
2018-09-10 01:14:58 +01:00
2021-12-07 22:14:12 -08:00
}
2018-09-10 01:14:58 +01:00
2021-12-07 22:14:12 -08:00
public function onEnable () {
// No actions necessary
}
2018-09-10 01:14:58 +01:00
2021-12-07 22:14:12 -08:00
public function onDisable () {
// No actions necessary
}
2018-09-10 01:14:58 +01:00
2025-02-24 18:44:29 +00:00
public function onPageLoad (
User $user ,
Pages $pages ,
Cache $cache ,
$smarty ,
iterable $navs ,
Widgets $widgets ,
TemplateBase $template
) {
2021-12-07 22:14:12 -08:00
// AdminCP
PermissionHandler :: registerPermissions ( 'Forum' , [
'admincp.forums' => $this -> _language -> get ( 'moderator' , 'staff_cp' ) . ' » ' . $this -> _forum_language -> get ( 'forum' , 'forum' )
2021-12-07 20:17:45 -08:00
]);
2018-09-10 01:14:58 +01:00
2021-12-07 22:14:12 -08:00
// Sitemap
2022-03-29 15:09:21 -07:00
$pages -> registerSitemapMethod ([ Forum_Sitemap :: class , 'generateSitemap' ]);
2018-09-10 01:14:58 +01:00
2021-12-07 22:14:12 -08:00
// Add link to navbar
2021-08-26 19:52:02 +02:00
$cache -> setCache ( 'nav_location' );
2025-05-20 18:37:24 -07:00
$link_location = $cache -> fetch ( 'forum_location' , 1 );
2021-12-07 22:14:12 -08:00
$cache -> setCache ( 'navbar_order' );
2025-05-20 18:37:24 -07:00
$forum_order = $cache -> fetch ( 'forum_order' , 2 );
2021-12-07 22:14:12 -08:00
$cache -> setCache ( 'navbar_icons' );
2025-05-20 18:37:24 -07:00
$icon = $cache -> fetch ( 'forum_icon' , '' );
2021-12-07 22:14:12 -08:00
switch ( $link_location ) {
2021-08-26 19:52:02 +02:00
case 1 :
// Navbar
$navs [ 0 ] -> add ( 'forum' , $this -> _forum_language -> get ( 'forum' , 'forum' ), URL :: build ( '/forum' ), 'top' , null , $forum_order , $icon );
2021-12-07 22:14:12 -08:00
break ;
2021-08-26 19:52:02 +02:00
case 2 :
// "More" dropdown
$navs [ 0 ] -> addItemToDropdown ( 'more_dropdown' , 'forum' , $this -> _forum_language -> get ( 'forum' , 'forum' ), URL :: build ( '/forum' ), 'top' , null , $icon , $forum_order );
2021-12-07 22:14:12 -08:00
break ;
2021-08-26 19:52:02 +02:00
case 3 :
// Footer
$navs [ 0 ] -> add ( 'forum' , $this -> _forum_language -> get ( 'forum' , 'forum' ), URL :: build ( '/forum' ), 'footer' , null , $forum_order , $icon );
2021-12-07 22:14:12 -08:00
break ;
2021-08-26 19:52:02 +02:00
}
2018-09-10 01:14:58 +01:00
2021-12-07 22:14:12 -08:00
// Widgets
2023-03-23 20:01:23 -07:00
if ( $pages -> getActivePage ()[ 'widgets' ] || ( defined ( 'PANEL_PAGE' ) && str_contains ( PANEL_PAGE , 'widget' ))) {
2022-04-23 12:02:00 -07:00
// Latest posts
2025-02-24 18:44:29 +00:00
$widgets -> add ( new LatestPostsWidget ( $this -> _forum_language , $template -> getEngine (), $cache , $user , $this -> _language ));
2022-04-23 12:02:00 -07:00
}
2021-12-07 22:14:12 -08:00
// Front end or back end?
if ( defined ( 'FRONT_END' )) {
if ( defined ( 'PAGE' ) && PAGE == 'user_query' ) {
2025-02-24 18:44:29 +00:00
$user_id = $template -> getEngine () -> getVariable ( 'USER_ID' );
2021-12-07 22:14:12 -08:00
if ( $user_id ) {
2022-04-02 14:13:02 +01:00
$forum = new Forum ();
2025-02-24 18:44:29 +00:00
$template -> getEngine () -> addVariables ([
'TOPICS' => $this -> _forum_language -> get ( 'forum' , 'x_topics' , [ 'count' => $forum -> getTopicCount ( $user_id )]),
'POSTS' => $this -> _forum_language -> get ( 'forum' , 'x_posts' , [ 'count' => $forum -> getPostCount ( $user_id )])
]);
2021-12-07 22:14:12 -08:00
}
}
} else {
if ( defined ( 'BACK_END' )) {
if ( $user -> hasPermission ( 'admincp.forums' )) {
2025-06-14 09:51:11 -07:00
$navs [ 2 ] -> add ( 'forum_divider' , mb_strtoupper ( $this -> _forum_language -> get ( 'forum' , 'forum' ), 'UTF-8' ), 'divider' , 'top' , null , 12 , '' );
$navs [ 2 ] -> add ( 'forum_settings' , $this -> _language -> get ( 'admin' , 'settings' ), URL :: build ( '/panel/forums/settings' ), 'top' , null , 12.1 , '<i class="nav-icon fas fa-cogs"></i>' );
$navs [ 2 ] -> add ( 'forums' , $this -> _forum_language -> get ( 'forum' , 'forums' ), URL :: build ( '/panel/forums' ), 'top' , null , 12.2 , '<i class="nav-icon fas fa-comments"></i>' );
$navs [ 2 ] -> add ( 'forum_labels' , $this -> _forum_language -> get ( 'forum' , 'labels' ), URL :: build ( '/panel/forums/labels' ), 'top' , null , 12.3 , '<i class="nav-icon fas fa-tags"></i>' );
2021-12-07 22:14:12 -08:00
}
if ( defined ( 'PANEL_PAGE' ) && PANEL_PAGE == 'dashboard' ) {
// Dashboard graph
// Get data for topics and posts
2022-12-12 20:49:53 +00:00
$start_time = strtotime ( '7 days ago' );
$latest_topics = DB :: getInstance () -> query (
<<< SQL
SELECT DATE_FORMAT ( FROM_UNIXTIME ( `topic_date` ), '%Y-%m-%d' ) d , COUNT ( * ) c
FROM nl2_topics
2023-01-18 10:45:30 -08:00
WHERE `topic_date` > ? AND `topic_date` < UNIX_TIMESTAMP ()
2022-12-12 20:49:53 +00:00
AND `deleted` = 0
GROUP BY DATE_FORMAT ( FROM_UNIXTIME ( `topic_date` ), '%Y-%m-%d' )
SQL ,
[ $start_time ],
);
$latest_topics_count = $latest_topics -> count ();
$latest_topics = $latest_topics -> results ();
$latest_posts = DB :: getInstance () -> query (
<<< SQL
SELECT DATE_FORMAT ( FROM_UNIXTIME ( `created` ), '%Y-%m-%d' ) d , COUNT ( * ) c
FROM nl2_posts
2023-01-18 10:45:30 -08:00
WHERE `created` > ? AND `created` < UNIX_TIMESTAMP ()
2022-12-12 20:49:53 +00:00
AND `deleted` = 0
GROUP BY DATE_FORMAT ( FROM_UNIXTIME ( `created` ), '%Y-%m-%d' )
SQL ,
[ $start_time ],
);
$latest_posts_count = $latest_posts -> count ();
$latest_posts = $latest_posts -> results ();
2021-12-07 22:14:12 -08:00
$cache -> setCache ( 'dashboard_graph' );
2025-05-20 18:37:24 -07:00
$data = $cache -> fetch ( 'forum_data' , function () use ( $latest_topics , $latest_posts ) {
2022-12-12 20:49:53 +00:00
$data = [];
2021-12-07 22:14:12 -08:00
2022-12-12 20:49:53 +00:00
$data [ 'datasets' ][ 'topics' ][ 'label' ] = 'forum_language/forum/topics_title' ; // for $forum_language->get('forum', 'topics_title');
$data [ 'datasets' ][ 'topics' ][ 'colour' ] = '#00931D' ;
$data [ 'datasets' ][ 'posts' ][ 'label' ] = 'forum_language/forum/posts_title' ; // for $forum_language->get('forum', 'posts_title');
$data [ 'datasets' ][ 'posts' ][ 'colour' ] = '#ffde0a' ;
2021-12-07 22:14:12 -08:00
2022-12-12 20:49:53 +00:00
if ( count ( $latest_topics )) {
foreach ( $latest_topics as $day ) {
$data [ '_' . $day -> d ] = [ 'topics' => $day -> c ];
2021-12-07 22:14:12 -08:00
}
}
2022-12-12 20:49:53 +00:00
if ( count ( $latest_posts )) {
foreach ( $latest_posts as $day ) {
if ( isset ( $data [ '_' . $day -> d ])) {
$data [ '_' . $day -> d ][ 'posts' ] = $day -> c ;
} else {
$data [ '_' . $day -> d ] = [ 'posts' => $day -> c ];
}
2021-12-07 22:14:12 -08:00
}
}
2022-12-12 20:49:53 +00:00
$data = Core_Module :: fillMissingGraphDays ( $data , 'topics' );
$data = Core_Module :: fillMissingGraphDays ( $data , 'posts' );
2021-12-07 22:14:12 -08:00
// Sort by date
2022-12-12 20:49:53 +00:00
ksort ( $data );
2021-12-07 22:14:12 -08:00
2025-05-20 18:37:24 -07:00
return $data ;
}, 120 );
2021-12-07 22:14:12 -08:00
2022-12-12 20:49:53 +00:00
Core_Module :: addDataToDashboardGraph ( $this -> _language -> get ( 'admin' , 'overview' ), $data );
2021-12-07 22:14:12 -08:00
// Dashboard stats
2025-02-24 18:44:29 +00:00
require_once ROOT_PATH . '/modules/Forum/collections/panel/RecentTopics.php' ;
2025-05-20 18:37:24 -07:00
CollectionManager :: addItemToCollection ( 'dashboard_stats' , new RecentTopicsItem ( $template -> getEngine (), $this -> _forum_language , $latest_topics_count ));
2021-12-07 22:14:12 -08:00
2025-02-24 18:44:29 +00:00
require_once ROOT_PATH . '/modules/Forum/collections/panel/RecentPosts.php' ;
2025-05-20 18:37:24 -07:00
CollectionManager :: addItemToCollection ( 'dashboard_stats' , new RecentPostsItem ( $template -> getEngine (), $this -> _forum_language , $latest_posts_count ));
2021-12-07 22:14:12 -08:00
}
}
}
}
2021-10-13 21:46:34 -07:00
public function getDebugInfo () : array {
return [];
}
2022-01-15 15:18:05 -08:00
}