_language = $language; $name = 'Core'; $author = 'Samerton'; $module_version = '2.2.5'; $nameless_version = '2.2.5'; parent::__construct($this, $name, $author, $module_version, $nameless_version); // Define URLs which belong to this module $pages->add('Core', '/', 'pages/index.php', '', true); $pages->add('Core', '/api/v2', 'pages/api/v2/index.php'); $pages->add('Core', '/home', 'pages/home.php', 'index', true); $pages->add('Core', '/login', 'pages/login.php'); $pages->add('Core', '/logout', 'pages/logout.php'); $pages->add('Core', '/profile', 'pages/profile.php', 'profile', true); $pages->add('Core', '/register', 'pages/register.php'); $pages->add('Core', '/register/oauth', 'pages/register.php'); $pages->add('Core', '/validate', 'pages/validate.php'); $pages->add('Core', '/queries/admin_users', 'queries/admin_users.php'); $pages->add('Core', '/queries/authme_test_connection', 'queries/authme_test_connection.php'); $pages->add('Core', '/queries/mention_users', 'queries/mention_users.php'); $pages->add('Core', '/queries/alerts', 'queries/alerts.php'); $pages->add('Core', '/queries/dark_light_mode', 'queries/dark_light_mode.php'); $pages->add('Core', '/queries/queue', 'queries/queue.php'); $pages->add('Core', '/queries/queue_status', 'queries/queue_status.php'); $pages->add('Core', '/queries/pms', 'queries/pms.php'); $pages->add('Core', '/queries/servers', 'queries/servers.php'); $pages->add('Core', '/queries/server', 'queries/server.php'); $pages->add('Core', '/queries/user', 'queries/user.php'); $pages->add('Core', '/queries/users', 'queries/users.php'); $pages->add('Core', '/queries/debug_link', 'queries/debug_link.php'); $pages->add('Core', '/queries/tinymce_image_upload', 'queries/tinymce_image_upload.php'); $pages->add('Core', '/queries/reactions', 'queries/reactions.php'); $pages->add('Core', '/banner', 'pages/minecraft/banner.php'); $pages->add('Core', '/terms', 'pages/terms.php'); $pages->add('Core', '/privacy', 'pages/privacy.php'); $pages->add('Core', '/forgot_password', 'pages/forgot_password.php'); $pages->add('Core', '/complete_signup', 'pages/complete_signup.php'); $pages->add('Core', '/status', 'pages/status.php', 'status'); if (Settings::get('mc_integration')) { $pages->add('Core', '/leaderboards', 'pages/leaderboards.php', 'leaderboards'); } $pages->add('Core', '/oauth', 'pages/oauth.php'); $pages->add('Core', '/user', 'pages/user/index.php', 'cc_overview'); $pages->add('Core', '/user/settings', 'pages/user/settings.php', 'cc_settings'); $pages->add('Core', '/user/messaging', 'pages/user/messaging.php', 'cc_messaging'); $pages->add('Core', '/user/alerts', 'pages/user/alerts.php', 'cc_alerts'); $pages->add('Core', '/user/sessions', 'pages/user/sessions.php', 'cc_sessions'); $pages->add('Core', '/user/notification_settings', 'pages/user/notification_settings.php', 'cc_notification_settings'); $pages->add('Core', '/user/placeholders', 'pages/user/placeholders.php', 'cc_placeholders'); $pages->add('Core', '/user/acknowledge', 'pages/user/acknowledge.php'); $pages->add('Core', '/user/connections', 'pages/user/connections.php', 'cc_connections'); // Panel $pages->add('Core', '/panel', 'pages/panel/index.php'); $pages->add('Core', '/panel/auth', 'pages/panel/auth.php'); $pages->add('Core', '/panel/core/general_settings', 'pages/panel/general_settings.php'); $pages->add('Core', '/panel/core/api', 'pages/panel/api.php'); $pages->add('Core', '/panel/core/seo', 'pages/panel/seo.php'); $pages->add('Core', '/panel/core/avatars', 'pages/panel/avatars.php'); $pages->add('Core', '/panel/core/profile_fields', 'pages/panel/profile_fields.php'); $pages->add('Core', '/panel/core/debugging_and_maintenance', 'pages/panel/debugging_and_maintenance.php'); $pages->add('Core', '/panel/core/errors', 'pages/panel/errors.php'); $pages->add('Core', '/panel/core/emails', 'pages/panel/emails.php'); $pages->add('Core', '/panel/core/emails/errors', 'pages/panel/emails_errors.php'); $pages->add('Core', '/panel/core/mass_message', 'pages/panel/mass_message.php'); $pages->add('Core', '/panel/core/navigation', 'pages/panel/navigation.php'); $pages->add('Core', '/panel/core/privacy_and_terms', 'pages/panel/privacy_and_terms.php'); $pages->add('Core', '/panel/core/reactions', 'pages/panel/reactions.php'); $pages->add('Core', '/panel/core/registration', 'pages/panel/registration.php'); $pages->add('Core', '/panel/core/social_media', 'pages/panel/social_media.php'); $pages->add('Core', '/panel/core/groups', 'pages/panel/groups.php'); $pages->add('Core', '/panel/core/images', 'pages/panel/images.php'); $pages->add('Core', '/panel/core/panel_templates', 'pages/panel/panel_templates.php'); $pages->add('Core', '/panel/core/templates', 'pages/panel/templates.php'); $pages->add('Core', '/panel/core/announcements', 'pages/panel/announcements.php'); $pages->add('Core', '/panel/core/widgets', 'pages/panel/widgets.php'); $pages->add('Core', '/panel/core/modules', 'pages/panel/modules.php'); $pages->add('Core', '/panel/core/pages', 'pages/panel/pages.php'); $pages->add('Core', '/panel/core/queue', 'pages/panel/queue.php'); $pages->add('Core', '/panel/core/hooks', 'pages/panel/hooks.php'); $pages->add('Core', '/panel/core/integrations', 'pages/panel/integrations.php'); $pages->add('Core', '/panel/minecraft/placeholders', 'pages/panel/placeholders.php'); $pages->add('Core', '/panel/minecraft', 'pages/panel/minecraft.php'); $pages->add('Core', '/panel/minecraft/authme', 'pages/panel/minecraft_authme.php'); $pages->add('Core', '/panel/minecraft/servers', 'pages/panel/minecraft_servers.php'); $pages->add('Core', '/panel/minecraft/query_errors', 'pages/panel/minecraft_query_errors.php'); $pages->add('Core', '/panel/minecraft/banners', 'pages/panel/minecraft_server_banners.php'); $pages->add('Core', '/panel/security', 'pages/panel/security.php'); $pages->add('Core', '/panel/update', 'pages/panel/update.php'); $pages->add('Core', '/panel/upgrade', 'pages/panel/upgrade.php'); $pages->add('Core', '/panel/users', 'pages/panel/users.php'); $pages->add('Core', '/panel/users/edit', 'pages/panel/users_edit.php'); $pages->add('Core', '/panel/users/integrations', 'pages/panel/users_integrations.php'); $pages->add('Core', '/panel/users/ip_lookup', 'pages/panel/users_ip_lookup.php'); $pages->add('Core', '/panel/users/punishments', 'pages/panel/users_punishments.php'); $pages->add('Core', '/panel/users/reports', 'pages/panel/users_reports.php'); $pages->add('Core', '/panel/users/sessions', 'pages/panel/users_sessions.php'); $pages->add('Core', '/panel/user', 'pages/panel/user.php'); // Ajax GET requests $pages->addAjaxScript(URL::build('/queries/servers')); if (Settings::get('queue_runner', 'ajax') == 'ajax') { $pages->addAjaxScript(URL::build('/queries/queue')); } // "More" dropdown $cache->setCache('navbar_icons'); $icon = $cache->fetch('more_dropdown_icon', ''); $cache->setCache('navbar_order'); $order = $cache->fetch('more_dropdown_order', 2500); $navigation->addDropdown('more_dropdown', $language->get('general', 'more'), 'top', $order, $icon); // Custom pages $custom_pages = DB::getInstance()->get('custom_pages', ['id', '<>', 0])->results(); if (count($custom_pages)) { $more = []; $cache->setCache('navbar_order'); if ($user->isLoggedIn()) { // Check all groups $user_groups = $user->getAllGroupIds(); foreach ($custom_pages as $custom_page) { $redirect = null; // Get redirect URL if enabled if ($custom_page->redirect == 1) { $redirect = $custom_page->link; } $pages->addCustom(Output::urlEncodeAllowSlashes($custom_page->url), Output::getClean($custom_page->title), !$custom_page->basic); foreach ($user_groups as $user_group) { $custom_page_permissions = DB::getInstance()->get('custom_pages_permissions', ['group_id', $user_group])->results(); if (count($custom_page_permissions)) { foreach ($custom_page_permissions as $permission) { if ($permission->page_id == $custom_page->id) { if ($permission->view == 1) { // Check cache for order $page_order = $cache->fetch($custom_page->id . '_order', 200); switch ($custom_page->link_location) { case 1: // Navbar $navigation->add( $custom_page->id, Output::getClean($custom_page->title), (is_null($redirect)) ? URL::build(Output::urlEncodeAllowSlashes($custom_page->url)) : $redirect, 'top', $custom_page->target ? '_blank' : null, $page_order, $custom_page->icon ); break; case 2: // "More" dropdown $more[] = [ 'id' => $custom_page->id, 'title' => Output::getClean($custom_page->title), 'url' => is_null($redirect) ? URL::build(Output::urlEncodeAllowSlashes($custom_page->url)) : $redirect, 'redirect' => $redirect, 'target' => $custom_page->target, 'icon' => $custom_page->icon, 'order' => $page_order ]; break; case 3: // Footer $navigation->add( $custom_page->id, Output::getClean($custom_page->title), (is_null($redirect)) ? URL::build(Output::urlEncodeAllowSlashes($custom_page->url)) : $redirect, 'footer', $custom_page->target ? '_blank' : null, 2000, $custom_page->icon ); break; } break 2; } break; } } } } } } else { $custom_page_permissions = DB::getInstance()->get('custom_pages_permissions', ['group_id', 0])->results(); if (count($custom_page_permissions)) { foreach ($custom_pages as $custom_page) { $redirect = null; if ($custom_page->redirect == 1) { $redirect = Output::getClean($custom_page->link); } $pages->addCustom(Output::urlEncodeAllowSlashes($custom_page->url), Output::getClean($custom_page->title), !$custom_page->basic); foreach ($custom_page_permissions as $permission) { if ($permission->page_id == $custom_page->id) { if ($permission->view == 1) { // Check cache for order $page_order = $cache->fetch($custom_page->id . '_order', 200); switch ($custom_page->link_location) { case 1: // Navbar $navigation->add( $custom_page->id, Output::getClean($custom_page->title), is_null($redirect) ? URL::build(Output::urlEncodeAllowSlashes($custom_page->url)) : $redirect, 'top', $custom_page->target ? '_blank' : null, $page_order, $custom_page->icon ); break; case 2: // "More" dropdown $more[] = [ 'id' => $custom_page->id, 'title' => Output::getClean($custom_page->title), 'url' => is_null($redirect) ? URL::build(Output::urlEncodeAllowSlashes($custom_page->url)) : $redirect, 'redirect' => $redirect, 'target' => $custom_page->target, 'icon' => $custom_page->icon, 'order' => $page_order ]; break; case 3: // Footer $navigation->add( $custom_page->id, Output::getClean($custom_page->title), is_null($redirect) ? URL::build(Output::urlEncodeAllowSlashes($custom_page->url)) : $redirect, 'footer', $custom_page->target ? '_blank' : null, 2000, $custom_page->icon ); break; } } break; } } } } } $custom_page_permissions = null; if (count($more)) { foreach ($more as $item) { $navigation->addItemToDropdown('more_dropdown', $item['id'], $item['title'], $item['url'], 'top', ($item['target']) ? '_blank' : null, $item['icon'] ?? '', $item['order']); } } } $custom_pages = null; // -- Events EventHandler::registerEvent(AnnouncementCreatedEvent::class); EventHandler::registerEvent(GenerateNotificationContentEvent::class); EventHandler::registerEvent(GroupClonedEvent::class); EventHandler::registerEvent(ReportCreatedEvent::class); EventHandler::registerEvent(UserBannedEvent::class); EventHandler::registerEvent(UserDeletedEvent::class); EventHandler::registerEvent(UserGroupAddedEvent::class); EventHandler::registerEvent(UserGroupRemovedEvent::class); EventHandler::registerEvent(UserIntegrationLinkedEvent::class); EventHandler::registerEvent(UserIntegrationUnlinkedEvent::class); EventHandler::registerEvent(UserIntegrationVerifiedEvent::class); EventHandler::registerEvent(UserProfilePostCreatedEvent::class); EventHandler::registerEvent(UserProfilePostReplyCreatedEvent::class); EventHandler::registerEvent(UserRegisteredEvent::class); EventHandler::registerEvent(UserValidatedEvent::class); EventHandler::registerEvent(UserWarnedEvent::class); // -- Pipelines EventHandler::registerEvent(PreCustomPageCreateEvent::class); EventHandler::registerEvent(PreCustomPageEditEvent::class); EventHandler::registerEvent(RenderContentEvent::class); EventHandler::registerEvent(RenderContentEditEvent::class); NamelessOAuth::getInstance()->registerProvider('discord', 'Core', [ 'class' => \Wohali\OAuth2\Client\Provider\Discord::class, 'user_id_name' => 'id', 'scope_id_name' => 'identify', 'icon' => 'fab fa-discord', 'button_css' => [ 'background-color' => '#5865F2', 'color' => '#FFFFFF', ], 'verify_email' => static fn () => true, ]); NamelessOAuth::getInstance()->registerProvider('google', 'Core', [ 'class' => \League\OAuth2\Client\Provider\Google::class, 'user_id_name' => 'sub', 'scope_id_name' => 'openid', 'logo_url' => rtrim(URL::getSelfURL(), '/') . '/core/assets/img/google_logo.png', // Google has strict restrictions (https://developers.google.com/identity/branding-guidelines) on how // their logo should be formatted for login buttons, and should not be altered by any template 'logo_css' => [ 'width' => '18px', 'height' => '18px', 'vertical-align' => 'middle', 'margin-bottom' => '-2px', 'margin-top' => '-2px', ], 'button_css' => [ 'background-color' => '#FFFFFF', 'color' => '#757575', 'line-height' => '.05em', 'box-shadow' => 'inset 0px 0px 0px 1px #DFDFDF;' ], 'text_css' => [ 'vertical-align' => 'middle', ], 'verify_email' => static fn () => true, ]); // Captcha $captchaPublicKey = Settings::get('recaptcha_key', ''); $captchaPrivateKey = Settings::get('recaptcha_secret', ''); $activeCaptcha = Settings::get('recaptcha_type', 'Recaptcha3'); CaptchaBase::addProvider(new hCaptcha($captchaPrivateKey, $captchaPublicKey)); CaptchaBase::addProvider(new Recaptcha2($captchaPrivateKey, $captchaPublicKey)); CaptchaBase::addProvider(new Recaptcha3($captchaPrivateKey, $captchaPublicKey)); CaptchaBase::setActiveProvider($activeCaptcha); // Avatar Sources AvatarSource::registerSource(new CrafatarAvatarSource()); AvatarSource::registerSource(new CraftheadAvatarSource()); AvatarSource::registerSource(new CravatarAvatarSource()); AvatarSource::registerSource(new MCHeadsAvatarSource()); AvatarSource::registerSource(new MinotarAvatarSource()); AvatarSource::registerSource(new VisageAvatarSource()); // Autoload API Endpoints $endpoints->loadEndpoints(ROOT_PATH . '/modules/Core/includes/endpoints'); GroupSyncManager::getInstance()->registerInjector(new NamelessMCGroupSyncInjector); GroupSyncManager::getInstance()->registerInjector(new MinecraftGroupSyncInjector); Endpoints::registerTransformer('user', 'Core', static function (Nameless2API $api, string $value) { $lookup_data = explode(':', $value); if (count($lookup_data) === 1) { // assume it is a namelessmc user id $user = new User($lookup_data[0]); if ($user->exists()) { return $user; } } else if (count($lookup_data) === 2) { // probably handling native namelessmc user [$lookup_type, $lookup_value] = $lookup_data; if ($lookup_type === 'id') { $column = 'id'; } else if ($lookup_type === 'username') { $column = 'username'; } else { $api->throwError(Nameless2API::ERROR_CANNOT_FIND_USER, "invalid native lookup type: $value"); } $user = new User($lookup_value, $column); if ($user->exists()) { return $user; } } else if (count($lookup_data) === 3) { // Handling a user integration lookup [$integration_lookup_type, $integration_name, $lookup_value] = $lookup_data; $integration = Integrations::getInstance()->getIntegration($integration_name); if ($integration != null) { if ($integration_lookup_type === 'integration_id') { $integrationUser = new IntegrationUser($integration, $lookup_value, 'identifier'); if ($integrationUser->exists()) { return $integrationUser->getUser(); } $api->throwError(Nameless2API::ERROR_CANNOT_FIND_USER, "invalid integration lookup name: $value"); } else if ($integration_lookup_type === 'integration_name') { $integrationUser = new IntegrationUser($integration, $lookup_value, 'username'); if ($integrationUser->exists()) { return $integrationUser->getUser(); } $api->throwError(Nameless2API::ERROR_CANNOT_FIND_USER, "invalid integration lookup name: $value"); } else { $api->throwError(Nameless2API::ERROR_CANNOT_FIND_USER, "invalid integration lookup name: $value"); } } else { $api->throwError(Nameless2API::ERROR_CANNOT_FIND_USER, "invalid integration lookup type: $value"); } } $api->throwError(Nameless2API::ERROR_CANNOT_FIND_USER, $value); }); // Minecraft Integration if (Settings::get('mc_integration')) { Integrations::getInstance()->registerIntegration(new MinecraftIntegration($language)); } Integrations::getInstance()->registerIntegration(new GoogleIntegration($language)); EventHandler::registerListener(GroupClonedEvent::class, CloneGroupHook::class); EventHandler::registerListener(GenerateNotificationContentEvent::class, 'ContentHook::purify'); EventHandler::registerListener(GenerateNotificationContentEvent::class, 'ContentHook::renderEmojis', 10); EventHandler::registerListener(GenerateNotificationContentEvent::class, 'MentionsHook::parsePost', 5); EventHandler::registerListener(RenderContentEvent::class, [ContentHook::class, 'purify']); EventHandler::registerListener(RenderContentEvent::class, [ContentHook::class, 'renderEmojis'], 10); EventHandler::registerListener(RenderContentEvent::class, [ContentHook::class, 'replaceAnchors'], 5); EventHandler::registerListener(RenderContentEvent::class, [MentionsHook::class, 'parsePost'], 5); EventHandler::registerListener(RenderContentEditEvent::class, [ContentHook::class, 'purify']); EventHandler::registerListener(RenderContentEditEvent::class, [ContentHook::class, 'replaceAnchors'], 15); EventHandler::registerListener(RenderContentEditEvent::class, [MentionsHook::class, 'stripPost'], 15); EventHandler::registerListener(ContentCreateEvent::class, [MentionsHook::class, 'preCreate']); EventHandler::registerListener(ContentEditEvent::class, [MentionsHook::class, 'preEdit']); EventHandler::registerListener(PreCustomPageCreateEvent::class, [MentionsHook::class, 'preCreate']); EventHandler::registerListener(PreCustomPageEditEvent::class, [MentionsHook::class, 'preEdit']); EventHandler::registerListener(UserRegisteredEvent::class, DefaultUserNotificationPreferencesHook::class); Email::addPlaceholder('[Sitename]', Output::getClean(SITE_NAME)); Email::addPlaceholder('[Greeting]', static fn(Language $viewing_language) => $viewing_language->get('emails', 'greeting')); Email::addPlaceholder('[Message]', static fn(Language $viewing_language, string $email) => $viewing_language->get('emails', $email . '_message')); Email::addPlaceholder('[Thanks]', static fn(Language $viewing_language) => $viewing_language->get('emails', 'thanks')); if (Util::isModuleEnabled('Members')) { MemberListManager::getInstance()->registerListProvider(new RegisteredMembersListProvider($language)); MemberListManager::getInstance()->registerListProvider(new StaffMembersListProvider($language)); MemberListManager::getInstance()->registerMemberMetadataProvider(function (User $member) use ($language) { return [ $language->get('general', 'joined') => date(DATE_FORMAT, $member->data()->joined), ]; }); } ReactionContextsManager::getInstance()->provideContext(new ProfilePostReactionContext()); // Notifications Notification::addType( 'mass_message', $language->get('notification', 'mass_messages'), ['alert' => true, 'email' => true], ); Notification::addType( 'report', $language->get('notification', 'reports'), ['alert' => true, 'email' => true], ); Notification::addType( 'punishment', $language->get('notification', 'punishments'), ['alert' => true, 'email' => true], ); } public static function getDashboardGraphs(): array { return self::$_dashboard_graph; } public static function getNotices(): array { return self::$_notices; } public static function getUserActions(): array { $return = self::$_user_actions; uasort($return, static function ($a, $b) { return $a['title'] > $b['title']; }); return $return; } public function onInstall() { // Not necessary for Core } public function onUninstall() { // Not necessary for Core } public function onEnable() { // Not necessary for Core } public function onDisable() { // Not necessary for Core } public function onPageLoad( User $user, Pages $pages, Cache $cache, $smarty, iterable $navs, Widgets $widgets, TemplateBase $template ) { $language = $this->_language; // Permissions PermissionHandler::registerPermissions($language->get('admin', 'administrator'), [ 'administrator' => $language->get('admin', 'administrator') . ' » ' . $language->get('admin', 'administrator_permission_info'), ]); // AdminCP PermissionHandler::registerPermissions($language->get('moderator', 'staff_cp'), [ 'admincp.core' => $language->get('admin', 'core'), 'admincp.core.api' => $language->get('admin', 'core') . ' » ' . $language->get('admin', 'api'), 'admincp.core.seo' => $language->get('admin', 'core') . ' » ' . $language->get('admin', 'seo'), 'admincp.core.general' => $language->get('admin', 'core') . ' » ' . $language->get('admin', 'general_settings'), 'admincp.core.avatars' => $language->get('admin', 'core') . ' » ' . $language->get('admin', 'avatars'), 'admincp.core.fields' => $language->get('admin', 'core') . ' » ' . $language->get('admin', 'custom_fields'), 'admincp.core.debugging' => $language->get('admin', 'core') . ' » ' . $language->get('admin', 'debugging_and_maintenance'), 'admincp.errors' => $language->get('admin', 'core') . ' » ' . $language->get('admin', 'debugging_and_maintenance') . ' » ' . $language->get('admin', 'error_logs'), 'admincp.core.emails' => $language->get('admin', 'core') . ' » ' . $language->get('admin', 'emails'), 'admincp.core.emails_mass_message' => $language->get('admin', 'core') . ' » ' . $language->get('admin', 'mass_message'), 'admincp.core.navigation' => $language->get('admin', 'core') . ' » ' . $language->get('admin', 'navigation'), 'admincp.core.queue' => $language->get('admin', 'core') . ' » ' . $language->get('admin', 'queue'), 'admincp.core.reactions' => $language->get('admin', 'core') . ' » ' . $language->get('user', 'reactions'), 'admincp.core.registration' => $language->get('admin', 'core') . ' » ' . $language->get('admin', 'registration'), 'admincp.core.social_media' => $language->get('admin', 'core') . ' » ' . $language->get('admin', 'social_media'), 'admincp.core.terms' => $language->get('admin', 'core') . ' » ' . $language->get('admin', 'privacy_and_terms'), 'admincp.core.hooks' => $language->get('admin', 'core') . ' » ' . $language->get('admin', 'hooks'), 'admincp.core.announcements' => $language->get('admin', 'core') . ' » ' . $language->get('admin', 'announcements'), 'admincp.core.placeholders' => $language->get('admin', 'core') . ' » ' . $language->get('admin', 'placeholders'), 'admincp.integrations' => $language->get('admin', 'integrations'), 'admincp.integrations.edit' => $language->get('admin', 'integrations') . ' » ' . $language->get('admin', 'general_settings'), 'admincp.minecraft' => $language->get('admin', 'integrations') . ' » ' . $language->get('admin', 'minecraft'), 'admincp.minecraft.authme' => $language->get('admin', 'integrations') . ' » ' . $language->get('admin', 'minecraft') . ' » ' . $language->get('admin', 'authme_integration'), 'admincp.minecraft.servers' => $language->get('admin', 'integrations') . ' » ' . $language->get('admin', 'minecraft') . ' » ' . $language->get('admin', 'minecraft_servers'), 'admincp.minecraft.query_errors' => $language->get('admin', 'integrations') . ' » ' . $language->get('admin', 'minecraft') . ' » ' . $language->get('admin', 'query_errors'), 'admincp.minecraft.banners' => $language->get('admin', 'integrations') . ' » ' . $language->get('admin', 'minecraft') . ' » ' . $language->get('admin', 'server_banners'), 'admincp.modules' => $language->get('admin', 'modules'), 'admincp.pages' => $language->get('admin', 'pages'), 'admincp.security' => $language->get('admin', 'security'), 'admincp.security.acp_logins' => $language->get('admin', 'security') . ' » ' . $language->get('admin', 'acp_logins'), 'admincp.security.template' => $language->get('admin', 'security') . ' » ' . $language->get('admin', 'template_changes'), 'admincp.security.emails' => $language->get('admin', 'security') . ' » ' . $language->get('admin', 'email_logs'), 'admincp.security.group_sync' => $language->get('admin', 'security') . ' » ' . $language->get('admin', 'group_sync_logs'), 'admincp.security.all' => $language->get('admin', 'security') . ' » ' . $language->get('admin', 'all_logs'), 'admincp.styles' => $language->get('admin', 'styles'), 'admincp.styles.panel_templates' => $language->get('admin', 'styles') . ' » ' . $language->get('admin', 'panel_templates'), 'admincp.styles.templates' => $language->get('admin', 'styles') . ' » ' . $language->get('admin', 'templates'), 'admincp.styles.templates.edit' => $language->get('admin', 'styles') . ' » ' . $language->get('admin', 'templates') . ' » ' . $language->get('general', 'edit'), 'admincp.styles.images' => $language->get('admin', 'styles') . ' » ' . $language->get('admin', 'images'), 'admincp.update' => $language->get('admin', 'update'), 'admincp.users' => $language->get('admin', 'user_management'), 'modcp.ip_lookup' => $language->get('admin', 'user_management') . ' » ' . $language->get('moderator', 'ip_lookup'), 'modcp.punishments' => $language->get('admin', 'user_management') . ' » ' . $language->get('moderator', 'punishments'), 'modcp.punishments.reset_avatar' => $language->get('admin', 'user_management') . ' » ' . $language->get('moderator', 'punishments') . ' » ' . $language->get('moderator', 'reset_avatar'), 'modcp.punishments.warn' => $language->get('admin', 'user_management') . ' » ' . $language->get('moderator', 'punishments') . ' » ' . $language->get('moderator', 'warn_user'), 'modcp.punishments.ban' => $language->get('admin', 'user_management') . ' » ' . $language->get('moderator', 'punishments') . ' » ' . $language->get('moderator', 'ban_user'), 'modcp.punishments.banip' => $language->get('admin', 'user_management') . ' » ' . $language->get('moderator', 'punishments') . ' » ' . $language->get('moderator', 'ban_ip'), 'modcp.punishments.revoke' => $language->get('admin', 'user_management') . ' » ' . $language->get('moderator', 'punishments') . ' » ' . $language->get('moderator', 'revoke'), 'modcp.reports' => $language->get('admin', 'user_management') . ' » ' . $language->get('moderator', 'reports'), 'modcp.profile_banner_reset' => $language->get('admin', 'user_management') . ' » ' . $language->get('moderator', 'reset_profile_banner'), 'admincp.users.edit' => $language->get('admin', 'user_management') . ' » ' . $language->get('admin', 'users') . ' » ' . $language->get('general', 'edit'), 'admincp.users.sessions' => $language->get('admin', 'user_management') . ' » ' . $language->get('admin', 'users') . ' » ' . $language->get('general', 'sessions'), 'admincp.groups' => $language->get('admin', 'groups'), 'admincp.groups.self' => $language->get('admin', 'groups') . ' » ' . $language->get('admin', 'can_edit_own_group'), 'admincp.widgets' => $language->get('admin', 'widgets'), ]); // UserCP PermissionHandler::registerPermissions('UserCP', [ 'usercp.messaging' => $language->get('user', 'messaging'), 'usercp.signature' => $language->get('user', 'profile_settings') . ' » ' . $language->get('user', 'signature'), 'usercp.private_profile' => $language->get('user', 'profile_settings') . ' » ' . $language->get('user', 'private_profile'), 'usercp.nickname' => $language->get('user', 'profile_settings') . ' » ' . $language->get('user', 'nickname'), 'usercp.title' => $language->get('user', 'profile_settings') . ' » ' . $language->get('user', 'user_title'), 'usercp.profile_banner' => $language->get('user', 'profile_settings') . ' » ' . $language->get('user', 'upload_profile_banner'), 'usercp.gif_avatar' => $language->get('user', 'profile_settings') . ' » ' . $language->get('user', 'gif_avatar') ]); // Profile Page PermissionHandler::registerPermissions('Profile', [ 'profile.private.bypass' => $language->get('general', 'bypass') . ' » ' . $language->get('user', 'private_profile'), 'profile.post' => $language->get('user', 'profile') . ' » ' . $language->get('user', 'profile_posts'), ]); // Sitemap $pages->registerSitemapMethod([Core_Sitemap::class, 'generateSitemap']); // Widgets - only load if on a widget staffcp page or the frontend if ($pages->getActivePage()['widgets'] || (defined('PANEL_PAGE') && str_contains(PANEL_PAGE, 'widget'))) { // Facebook $fb_url = Settings::get('fb_url'); if ($fb_url) { $widgets->add(new FacebookWidget($template->getEngine(), $fb_url)); } // Twitter $twitter = Settings::get('twitter_url'); if ($twitter) { $theme = Settings::get('twitter_style'); $widgets->add(new TwitterWidget($template->getEngine(), $twitter, $theme)); } // Profile Posts $widgets->add(new ProfilePostsWidget($template->getEngine(), $language, $cache, $user, new TimeAgo(TIMEZONE))); // Online staff $widgets->add(new OnlineStaffWidget($template->getEngine(), $language, $cache)); // Online users $widgets->add(new OnlineUsersWidget($cache, $template->getEngine(), $language)); // Online users $widgets->add(new ServerStatusWidget($template->getEngine(), $language, $cache)); // Statistics $widgets->add(new StatsWidget($template->getEngine(), $language, $cache)); // Reactions profile widget $widgets->add(new ReactionsProfileWidget($template->getEngine(), $language)); // Minecraft account profile widget if (Settings::get('mc_integration')) { $widgets->add(new MinecraftAccountProfileWidget($template->getEngine(), $cache, $language)); } } // Validate user hook $validate_action = Settings::get('validate_user_action'); $validate_action = json_decode($validate_action, true); if ($validate_action['action'] == 'promote') { EventHandler::registerListener(UserValidatedEvent::class, ValidateHook::class); define('VALIDATED_DEFAULT', $validate_action['group']); } // Check for updates if ($user->isLoggedIn()) { if (!(defined('PANEL_PAGE') && PANEL_PAGE === 'update') && $user->hasPermission('admincp.update')) { $cache->setCache('update_check'); $update_check = $cache->fetch('update_check', fn () => Util::updateCheck(), 3600); if (!is_string($update_check) && $update_check->updateAvailable()) { $template->getEngine()->addVariables([ 'NEW_UPDATE' => $update_check->isUrgent() ? $language->get('admin', 'new_urgent_update_available') : $language->get('admin', 'new_update_available'), 'NEW_UPDATE_URGENT' => $update_check->isUrgent(), 'CURRENT_VERSION' => $language->get('admin', 'current_version_x', [ 'version' => Output::getClean(NAMELESS_VERSION) ]), 'NEW_VERSION' => $language->get('admin', 'new_version_x', [ 'version' => Output::getClean($update_check->versionTag()) ]), 'NAMELESS_UPDATE' => $language->get('admin', 'update'), 'NAMELESS_UPDATE_LINK' => URL::build('/panel/update') ]); } } } if (Settings::get('mc_integration') && Settings::get('status_page')) { // Add status link to navbar $cache->setCache('navbar_order'); $status_order = $cache->fetch('status_order', 3); $cache->setCache('navbar_icons'); $icon = $cache->fetch('status_icon', ''); $navs[0]->add('status', $language->get('general', 'status'), URL::build('/status'), 'top', null, $status_order, $icon); } // Only add leaderboard link if there is at least one enabled placeholder and MC integration enabled if (Settings::get('mc_integration') && Settings::get('placeholders') === '1') { $leaderboard_placeholders = Placeholders::getInstance()->getLeaderboardPlaceholders(); if (count($leaderboard_placeholders)) { $cache->setCache('navbar_order'); $leaderboards_order = $cache->fetch('leaderboards_order', 4); $cache->setCache('navbar_icons'); $leaderboards_icon = $cache->fetch('leaderboards_icon', ''); $navs[0]->add('leaderboards', $language->get('general', 'leaderboards'), URL::build('/leaderboards'), 'top', null, $leaderboards_order, $leaderboards_icon); } } // Check page type (frontend or backend) if (defined('FRONT_END')) { // Minecraft integration? if (Settings::get('mc_integration')) { // Query main server $cache->setCache('mc_default_server'); // Already cached? if ($cache->isCached('default_query')) { $result = $cache->retrieve('default_query'); $default = $cache->retrieve('default'); } else { if ($cache->isCached('default')) { $default = $cache->retrieve('default'); $sub_servers = $cache->retrieve('default_sub'); } else { // Get default server from database $default = DB::getInstance()->get('mc_servers', ['is_default', true])->results(); if (count($default)) { // Get sub-servers of default server $sub_servers = DB::getInstance()->get('mc_servers', ['parent_server', $default[0]->id])->results(); if (count($sub_servers)) { $cache->store('default_sub', $sub_servers); } else { $cache->store('default_sub', []); } $default = $default[0]; $cache->store('default', $default, 60); } else { $cache->store('default', null, 60); } } if (!is_null($default) && isset($default->ip)) { $full_ip = ['ip' => $default->ip . (is_null($default->port) ? '' : ':' . $default->port), 'pre' => $default->pre, 'name' => $default->name, 'id' => $default->id]; // Get query type $query_type = Settings::get('query_type', 'internal'); if (isset($sub_servers) && count($sub_servers)) { $servers = [$full_ip]; foreach ($sub_servers as $server) { $servers[] = [ 'id' => $server->id, 'ip' => $server->ip . (is_null($server->port) ? '' : ':' . $server->port), 'pre' => $server->pre, 'name' => $server->name, 'bedrock' => $server->bedrock ]; } $result = $query_type === 'plugin' ? PluginQuery::multiQuery($servers, $language, true) : MCQuery::multiQuery($servers, $query_type, $language, true); if (isset($result['status_value']) && $result['status_value'] == 1) { $result['status'] = $language->get('general', 'online'); if ($result['player_count'] == 1) { $result['status_full'] = $language->get('general', 'currently_1_player_online'); $result['x_players_online'] = $language->get('general', 'currently_1_player_online'); } else { $result['status_full'] = $language->get('general', 'currently_x_players_online', ['count' => $result['player_count']]); $result['x_players_online'] = $language->get('general', 'currently_x_players_online', ['count' => $result['player_count']]); } } else { $result['status'] = $language->get('general', 'offline'); $result['status_full'] = $language->get('general', 'server_offline'); $result['server_offline'] = $language->get('general', 'server_offline'); } } else { $result = $query_type === 'plugin' ? PluginQuery::singleQuery($default->id, $language) : MCQuery::singleQuery($full_ip, $query_type, $default->bedrock, $language); if (isset($result['status_value']) && $result['status_value'] == 1) { $result['status'] = $language->get('general', 'online'); if ($result['player_count'] == 1) { $result['status_full'] = $language->get('general', 'currently_1_player_online'); $result['x_players_online'] = $language->get('general', 'currently_1_player_online'); } else { $result['status_full'] = $language->get('general', 'currently_x_players_online', ['count' => $result['player_count']]); $result['x_players_online'] = $language->get('general', 'currently_x_players_online', ['count' => $result['player_count']]); } } else { $result['status'] = $language->get('general', 'offline'); $result['status_full'] = $language->get('general', 'server_offline'); $result['server_offline'] = $language->get('general', 'server_offline'); } } // Cache for 1 minute $cache->store('default_query', $result, 60); } } $template->getEngine()->addVariable('MINECRAFT', true); if (isset($result)) { $template->getEngine()->addVariable('SERVER_QUERY', $result); } if (!is_null($default) && isset($default->ip)) { $template->getEngine()->addVariables([ 'CONNECT_WITH' => $language->get('general', 'connect_with_ip_x', [ 'address' => '' . Output::getClean($default->ip . ($default->port && $default->port != 25565 ? ':' . $default->port : '')) . '', ]), 'DEFAULT_IP' => Output::getClean($default->ip . ($default->port != 25565 ? ':' . $default->port : '')), 'CLICK_TO_COPY_TOOLTIP' => $language->get('general', 'click_to_copy_tooltip'), 'COPIED' => $language->get('general', 'copied'), ]); } else { $template->getEngine()->addVariables([ 'CONNECT_WITH' => '', 'DEFAULT_IP' => '', ]); } $template->getEngine()->addVariable('SERVER_OFFLINE', $language->get('general', 'server_offline')); } if (defined('PAGE') && PAGE == 'user_query') { // Collection $user_id = $template->getEngine()->getVariable('USER_ID'); $timeAgo = new TimeAgo(TIMEZONE); if ($user_id) { $user_query = DB::getInstance()->get('users', ['id', $user_id])->results(); if (count($user_query)) { $user_query = new UserData($user_query[0]); $template->getEngine()->addVariables([ 'REGISTERED' => $language->get('user', 'registered_x', [ 'registeredAt' => $timeAgo->inWords($user_query->joined, $language), ]), 'REGISTERED_DATE' => date(DATE_FORMAT, $user_query->joined), ]); if ($user->canBypassPrivateProfile() || (!Settings::get('private_profile') || !$user_query->private_profile)) { $template->getEngine()->addVariables([ 'LAST_SEEN' => $language->get('user', 'last_seen_x', [ 'lastSeenAt' => $timeAgo->inWords($user_query->last_online, $language), ]), 'LAST_SEEN_DATE' => date(DATE_FORMAT, $user_query->last_online) ]); } } } } } else { // Navigation $navs[2]->add('core_divider', mb_strtoupper($language->get('admin', 'core')), 'divider', 'top', null, 1, ''); $navs[2]->add('dashboard', $language->get('admin', 'dashboard'), URL::build('/panel'), 'top', null, 1, ''); if ($user->hasPermission('admincp.core')) { $navs[2]->addDropdown('core_configuration', $language->get('admin', 'configuration'), 'top', 2, ''); if ($user->hasPermission('admincp.core.general')) { $navs[2]->addItemToDropdown('core_configuration', 'general_settings', $language->get('admin', 'general_settings'), URL::build('/panel/core/general_settings'), 'top', null, '', 2); } if ($user->hasPermission('admincp.core.api')) { $navs[2]->addItemToDropdown('core_configuration', 'api', $language->get('admin', 'api'), URL::build('/panel/core/api'), 'top', null, '', 2); } if ($user->hasPermission('admincp.core.seo')) { $navs[2]->addItemToDropdown('core_configuration', 'seo', $language->get('admin', 'seo'), URL::build('/panel/core/seo'), 'top', null, '', 2); } if ($user->hasPermission('admincp.core.avatars')) { $navs[2]->addItemToDropdown('core_configuration', 'avatars', $language->get('admin', 'avatars'), URL::build('/panel/core/avatars'), 'top', null, '', 2); } if ($user->hasPermission('admincp.core.fields')) { $navs[2]->addItemToDropdown('core_configuration', 'custom_profile_fields', $language->get('admin', 'custom_fields'), URL::build('/panel/core/profile_fields'), 'top', null, '', 2); } if ($user->hasPermission('admincp.core.debugging')) { $navs[2]->addItemToDropdown('core_configuration', 'debugging_and_maintenance', $language->get('admin', 'maintenance'), URL::build('/panel/core/debugging_and_maintenance'), 'top', null, '', 2); } if ($user->hasPermission('admincp.core.emails')) { $navs[2]->addItemToDropdown('core_configuration', 'emails', $language->get('admin', 'emails'), URL::build('/panel/core/emails'), 'top', null, '', 2); } if ($user->hasPermission('admincp.core.navigation')) { $navs[2]->addItemToDropdown('core_configuration', 'navigation', $language->get('admin', 'navigation'), URL::build('/panel/core/navigation'), 'top', null, '', 2); } if ($user->hasPermission('admincp.core.terms')) { $navs[2]->addItemToDropdown('core_configuration', 'privacy_and_terms', $language->get('admin', 'privacy_and_terms'), URL::build('/panel/core/privacy_and_terms'), 'top', null, '', 2); } if ($user->hasPermission('admincp.core.queue')) { $navs[2]->addItemToDropdown('core_configuration', 'queue', $language->get('admin', 'queue'), URL::build('/panel/core/queue'), 'top', null, '', 2); } if ($user->hasPermission('admincp.core.reactions')) { $navs[2]->addItemToDropdown('core_configuration', 'reactions', $language->get('user', 'reactions'), URL::build('/panel/core/reactions'), 'top', null, '', 2); } if ($user->hasPermission('admincp.core.registration')) { $navs[2]->addItemToDropdown('core_configuration', 'registration', $language->get('admin', 'registration'), URL::build('/panel/core/registration'), 'top', null, '', 2); } if ($user->hasPermission('admincp.core.social_media')) { $navs[2]->addItemToDropdown('core_configuration', 'social_media', $language->get('admin', 'social_media'), URL::build('/panel/core/social_media'), 'top', null, '', 2); } if ($user->hasPermission('admincp.core.hooks')) { $navs[2]->addItemToDropdown('core_configuration', 'hooks', $language->get('admin', 'hooks'), URL::build('/panel/core/hooks'), 'top', null, '', 2); } } if ($user->hasPermission('admincp.core.announcements') || $user->hasPermission('admincp.core.emails_mass_message')) { $navs[2]->addDropdown('announcements', $language->get('admin', 'communications'), 'top', 4, ''); if ($user->hasPermission('admincp.core.announcements')) { $navs[2]->addItemToDropdown('announcements', 'announcements', $language->get('admin', 'announcements'), URL::build('/panel/core/announcements'), 'top', null, '', 1); } if ($user->hasPermission('admincp.core.emails_mass_message')) { $navs[2]->addItemToDropdown('announcements', 'mass_message', $language->get('admin', 'mass_message'), URL::build('/panel/core/mass_message'), 'top', null, '', 1); } } if ($user->hasPermission('admincp.integrations')) { $navs[2]->addDropdown('integrations', $language->get('admin', 'integrations'), 'top', 5, ''); } if ($user->hasPermission('admincp.integrations.edit')) { $navs[2]->addItemToDropdown('integrations', 'integrations', $language->get('admin', 'general_settings'), URL::build('/panel/core/integrations'), 'top', null, '', 1); } if ($user->hasPermission('admincp.minecraft')) { $navs[2]->addItemToDropdown('integrations', 'minecraft', $language->get('admin', 'minecraft'), URL::build('/panel/minecraft'), 'top', null, '', 5); } if ($user->hasPermission('admincp.styles') || $user->hasPermission('admincp.sitemap') || $user->hasPermission('admincp.widgets')) { $navs[2]->addDropdown('layout', $language->get('admin', 'layout'), 'top', 6, ''); if ($user->hasPermission('admincp.styles.images')) { $navs[2]->addItemToDropdown('layout', 'images', $language->get('admin', 'images'), URL::build('/panel/core/images'), 'top', null, '', 6); } if ($user->hasPermission('admincp.styles.panel_templates')) { $navs[2]->addItemToDropdown('layout', 'panel_templates', $language->get('admin', 'panel_templates'), URL::build('/panel/core/panel_templates'), 'top', null, '', 6); } if ($user->hasPermission('admincp.styles')) { $navs[2]->addItemToDropdown('layout', 'template', $language->get('admin', 'templates'), URL::build('/panel/core/templates'), 'top', null, '', 6); } if ($user->hasPermission('admincp.widgets')) { $navs[2]->addItemToDropdown('layout', 'widgets', $language->get('admin', 'widgets'), URL::build('/panel/core/widgets'), 'top', null, '', 6); } } if ($user->hasPermission('admincp.modules')) { $navs[2]->add('modules', $language->get('admin', 'modules'), URL::build('/panel/core/modules'), 'top', null, 7, ''); } if ($user->hasPermission('admincp.pages')) { $navs[2]->add('custom_pages', $language->get('admin', 'custom_pages'), URL::build('/panel/core/pages'), 'top', null, 8, ''); } if ($user->hasPermission('admincp.groups')) { $navs[2]->add('groups', $language->get('admin', 'groups'), URL::build('/panel/core/groups'), 'top', null, 3, ''); } if ($user->hasPermission('admincp.users')) { $navs[2]->addDropdown('users', $language->get('admin', 'user_management'), 'top', 11, ''); $navs[2]->addItemToDropdown('users', 'users', $language->get('admin', 'users'), URL::build('/panel/users'), 'top', null, '', 11); if ($user->hasPermission('modcp.ip_lookup')) { $navs[2]->addItemToDropdown('users', 'ip_lookup', $language->get('moderator', 'ip_lookup'), URL::build('/panel/users/ip_lookup'), 'top', null, '', 11); } if ($user->hasPermission('modcp.punishments')) { $navs[2]->addItemToDropdown('users', 'punishments', $language->get('moderator', 'punishments'), URL::build('/panel/users/punishments'), 'top', null, '', 11); } if ($user->hasPermission('modcp.reports')) { $navs[2]->addItemToDropdown('users', 'reports', $language->get('moderator', 'reports'), URL::build('/panel/users/reports'), 'top', null, '', 11); } } if ($user->hasPermission('admincp.security')) { $navs[2]->add('security', $language->get('admin', 'security'), URL::build('/panel/security'), 'top', null, 9, ''); } if ($user->hasPermission('admincp.update')) { $navs[2]->add('update', $language->get('admin', 'update'), URL::build('/panel/update'), 'top', null, 10, ''); } // Notices $cache->setCache('notices_cache'); // Email errors? if ($user->hasPermission('admincp.core.emails')) { $email_errors = $cache->fetch('email_orders', fn () => DB::getInstance()->query('SELECT COUNT(*) AS c FROM nl2_email_errors')->first()->c, 120); if (intval($email_errors)) { self::addNotice(URL::build('/panel/core/emails/errors'), $language->get('admin', 'email_errors_logged')); } } if (defined('PANEL_PAGE') && PANEL_PAGE == 'dashboard') { // Dashboard graph $data = $cache->fetch('core_data', function () { $users = DB::getInstance()->query( << ? AND `joined` < UNIX_TIMESTAMP() GROUP BY DATE_FORMAT(FROM_UNIXTIME(`joined`), '%Y-%m-%d') SQL, [strtotime('7 days ago')], ); // Output array $data = []; $data['datasets']['users']['label'] = 'language/admin/registrations'; // for $language->get('admin', 'registrations'); $data['datasets']['users']['colour'] = '#0004FF'; if ($users->count()) { foreach ($users->results() as $day) { $data['_' . $day->d] = ['users' => $day->c]; } } $users = null; $data = self::fillMissingGraphDays($data, 'users'); // Sort by date ksort($data); return $data; }, 120); self::addDataToDashboardGraph($language->get('admin', 'overview'), $data); // Dashboard stats require_once ROOT_PATH . '/modules/Core/collections/panel/TotalUsers.php'; CollectionManager::addItemToCollection('dashboard_stats', new TotalUsersItem($template->getEngine(), $language)); require_once ROOT_PATH . '/modules/Core/collections/panel/RecentUsers.php'; CollectionManager::addItemToCollection('dashboard_stats', new RecentUsersItem($template->getEngine(), $language)); // Dashboard items if ($user->hasPermission('modcp.punishments')) { require_once ROOT_PATH . '/modules/Core/collections/panel/RecentPunishments.php'; CollectionManager::addItemToCollection('dashboard_main_items', new RecentPunishmentsItem($template->getEngine(), $language, $cache)); } if ($user->hasPermission('modcp.reports')) { require_once ROOT_PATH . '/modules/Core/collections/panel/RecentReports.php'; CollectionManager::addItemToCollection('dashboard_main_items', new RecentReportsItem($template->getEngine(), $language, $cache)); } if ($user->hasPermission('admincp.users')) { require_once ROOT_PATH . '/modules/Core/collections/panel/RecentRegistrations.php'; CollectionManager::addItemToCollection('dashboard_main_items', new RecentRegistrationsItem($template->getEngine(), $language, $cache)); } } if ($user->hasPermission('admincp.users.edit')) { self::addUserAction($language->get('general', 'edit'), URL::build('/panel/users/edit/', 'id={id}')); } if ($user->hasPermission('admincp.users.edit')) { self::addUserAction($language->get('admin', 'integrations'), URL::build('/panel/users/integrations/', 'id={id}')); } if ($user->hasPermission('admincp.users.sessions')) { self::addUserAction($language->get('general', 'sessions'), URL::build('/panel/users/sessions', 'id={id}')); } if ($user->hasPermission('modcp.ip_lookup')) { self::addUserAction($language->get('moderator', 'ip_lookup'), URL::build('/panel/users/ip_lookup/', 'uid={id}')); } if ($user->hasPermission('modcp.punishments')) { self::addUserAction($language->get('moderator', 'punish'), URL::build('/panel/users/punishments/', 'user={id}')); } self::addUserAction($language->get('user', 'profile'), URL::build('/profile/{username}')); if ($user->hasPermission('modcp.reports')) { self::addUserAction($language->get('moderator', 'reports'), URL::build('/panel/users/reports/', 'uid={id}')); } } EventHandler::registerListener(UserDeletedEvent::class, DeleteUserHook::class); } public static function addNotice($url, $text): void { self::$_notices[$url] = $text; } public static function addDataToDashboardGraph($title, $data): void { if (isset(self::$_dashboard_graph[$title])) { self::$_dashboard_graph[$title] = array_merge_recursive(self::$_dashboard_graph[$title], $data); } else { self::$_dashboard_graph[$title] = $data; } } /** * Fill missing days in an array containing graph data * * @param array $data Initial data to display on graph * @param string $key Key to output data under * @return array Formatted data under $key */ public static function fillMissingGraphDays(array $data, string $key): array { $start = new DateTime('-7 days'); $end = new DateTime('+1 day'); $interval = new DateInterval('P1D'); $dates = new DatePeriod($start, $interval, $end); foreach ($dates as $date) { $format = $date->format('Y-m-d'); if (!isset($data['_' . $format][$key])) { $data['_' . $format][$key] = 0; } } return $data; } public static function addUserAction($title, $link): void { self::$_user_actions[] = ['title' => $title, 'link' => $link]; } public function getDebugInfo(): array { $servers = []; $group_sync_server_id = Settings::get('group_sync_mc_server'); foreach (DB::getInstance()->get('mc_servers', ['id', '<>', 0])->results() as $server) { $servers[(int)$server->id] = [ 'id' => (int)$server->id, 'name' => $server->name, 'ip' => $server->ip, 'query_ip' => $server->query_ip, 'port' => $server->port, 'query_port' => $server->query_port, 'bedrock' => (bool)$server->bedrock, 'group_sync_server' => $server->id == $group_sync_server_id, ]; } return [ 'minecraft' => [ 'mc_integration' => (bool)Settings::get(Settings::MINECRAFT_INTEGRATION), 'uuid_linking' => (bool)Settings::get('uuid_linking'), 'username_sync' => Settings::get('username_sync'), 'query_type' => Settings::get('query_type', 'internal'), 'servers' => $servers, ] ]; } }