From 0c80570609124f0167583ab610a40abad6e7e1db Mon Sep 17 00:00:00 2001 From: tadhgboyle Date: Sat, 9 Mar 2024 03:19:55 -0800 Subject: [PATCH] Enable StyleCI (#3475) * Create StyleCI config file * Disable `phpdoc_separation` * Apply fixes from StyleCI (#3476) Co-authored-by: StyleCI Bot * style: styleci fixes --------- Co-authored-by: StyleCI Bot Co-authored-by: Sam --- .github/workflows/ci.yml | 12 +- .styleci.yml | 13 + 403.php | 2 +- 404.php | 2 +- core/avatar/face.php | 5 +- core/classes/Avatars/AvatarSource.php | 57 +++-- core/classes/Avatars/AvatarSourceBase.php | 37 +-- core/classes/Collections/Collection.php | 18 +- .../Collections/CollectionItemBase.php | 13 +- .../classes/Collections/CollectionManager.php | 17 +- core/classes/Core/Alert.php | 41 ++-- core/classes/Core/Cache.php | 151 +++++++----- core/classes/Core/Config.php | 54 ++-- core/classes/Core/Configuration.php | 20 +- core/classes/Core/Cookie.php | 36 +-- core/classes/Core/Date.php | 13 +- core/classes/Core/Email.php | 56 +++-- core/classes/Core/Fields.php | 41 ++-- core/classes/Core/HttpClient.php | 60 +++-- core/classes/Core/Input.php | 51 ++-- core/classes/Core/Instanceable.php | 8 +- core/classes/Core/Language.php | 50 ++-- core/classes/Core/Log.php | 35 +-- core/classes/Core/Module.php | 71 +++--- core/classes/Core/Navigation.php | 75 +++--- core/classes/Core/Output.php | 30 +-- core/classes/Core/Pages.php | 72 +++--- core/classes/Core/Paginator.php | 42 ++-- core/classes/Core/PermissionHandler.php | 14 +- core/classes/Core/Redirect.php | 16 +- core/classes/Core/SecureRandom.php | 12 +- core/classes/Core/Session.php | 33 ++- core/classes/Core/Settings.php | 39 +-- core/classes/Core/TimeAgo.php | 61 ++--- core/classes/Core/Token.php | 17 +- core/classes/Core/URL.php | 59 +++-- core/classes/Core/User.php | 232 +++++++++++------- core/classes/Core/Util.php | 104 ++++---- core/classes/Core/Validate.php | 85 +++---- core/classes/DTO/Announcement.php | 12 +- core/classes/DTO/Group.php | 20 +- core/classes/DTO/IntegrationData.php | 8 +- core/classes/DTO/IntegrationUserData.php | 8 +- core/classes/DTO/ProfileField.php | 19 +- core/classes/DTO/Reaction.php | 18 +- core/classes/DTO/UpdateCheck.php | 36 ++- core/classes/DTO/UserData.php | 8 +- core/classes/DTO/UserProfileField.php | 11 +- core/classes/Database/DB.php | 181 ++++++++------ core/classes/Database/DatabaseInitialiser.php | 97 ++++---- core/classes/Database/PhinxAdapter.php | 29 ++- core/classes/Database/QueryRecorder.php | 25 +- core/classes/Endpoints/EndpointBase.php | 24 +- core/classes/Endpoints/Endpoints.php | 27 +- core/classes/Endpoints/KeyAuthEndpoint.php | 21 +- .../classes/Endpoints/ManagesTransformers.php | 27 +- core/classes/Endpoints/MatchesRoutes.php | 21 +- core/classes/Endpoints/NoAuthEndpoint.php | 7 +- core/classes/Events/AbstractEvent.php | 28 ++- core/classes/Events/Cancellable.php | 15 +- core/classes/Events/DiscordDispatchable.php | 5 +- core/classes/Events/DiscordEmbed.php | 71 ++++-- core/classes/Events/DiscordWebhookBuilder.php | 43 ++-- core/classes/Events/EventCollector.php | 23 +- core/classes/Events/EventHandler.php | 53 ++-- core/classes/Events/HasWebhookParams.php | 5 +- core/classes/Events/HookBase.php | 13 +- core/classes/Events/WebhookDispatcher.php | 9 +- .../Group_Sync/BatchableGroupSyncInjector.php | 15 +- core/classes/Group_Sync/GroupSyncInjector.php | 28 +-- core/classes/Group_Sync/GroupSyncManager.php | 47 ++-- core/classes/Integrations/IntegrationBase.php | 72 +++--- core/classes/Integrations/IntegrationUser.php | 68 ++--- core/classes/Integrations/Integrations.php | 20 +- core/classes/Minecraft/ExternalMCQuery.php | 20 +- core/classes/Minecraft/MCQuery.php | 116 ++++----- core/classes/Minecraft/MinecraftProfile.php | 27 +- core/classes/Minecraft/PluginQuery.php | 37 +-- core/classes/Minecraft/ProfileUtils.php | 56 +++-- core/classes/Misc/Announcements.php | 76 +++--- core/classes/Misc/CaptchaBase.php | 76 +++--- core/classes/Misc/DebugBarHelper.php | 15 +- core/classes/Misc/Debugging.php | 19 +- core/classes/Misc/ErrorHandler.php | 85 ++++--- core/classes/Misc/HttpUtils.php | 40 +-- core/classes/Misc/IntegrityChecker.php | 37 +-- core/classes/Misc/MentionsParser.php | 17 +- core/classes/Misc/NamelessOAuth.php | 129 ++++++---- core/classes/Misc/Placeholders.php | 30 ++- .../Misc/ProfilePostReactionContext.php | 41 ++-- core/classes/Misc/ReactionContext.php | 29 +-- core/classes/Misc/ReactionContextsManager.php | 28 ++- core/classes/Misc/Report.php | 19 +- core/classes/Misc/Text.php | 38 +-- core/classes/Misc/UpgradeScript.php | 64 ++--- core/classes/Queue/Queue.php | 38 +-- core/classes/Queue/Task.php | 121 +++++---- core/classes/Templates/AssetResolver.php | 37 +-- core/classes/Templates/AssetTree.php | 12 +- core/classes/Templates/TemplateBase.php | 55 +++-- core/classes/Widgets/AbstractWidget.php | 39 +-- core/classes/Widgets/ProfileWidgetBase.php | 7 +- core/classes/Widgets/WidgetBase.php | 9 +- core/classes/Widgets/WidgetData.php | 7 +- core/classes/Widgets/Widgets.php | 34 ++- core/includes/image_upload.php | 4 +- core/includes/maintenance.php | 4 +- core/includes/tfa_signin.php | 4 +- core/includes/updates/210.php | 6 +- core/includes/updates/211.php | 6 +- core/init.php | 53 ++-- core/installation/includes/functions.php | 20 +- core/installation/steps/ajax_initialise.php | 5 +- .../20220517030607_create_languages_table.php | 1 + .../20220517030609_create_templates_table.php | 1 + .../20220517030611_create_users_table.php | 1 + .../20220517030657_create_reactions_table.php | 1 + ...518024302_create_panel_templates_table.php | 1 + ...20518024945_create_blocked_users_table.php | 3 +- .../20220518025652_create_groups_table.php | 1 + ...220518025817_create_users_groups_table.php | 5 +- .../20220518031216_create_alerts_table.php | 1 + ...2305_create_custom_announcements_table.php | 1 + ...220518032919_create_custom_pages_table.php | 1 + ..._create_custom_pages_permissions_table.php | 1 + ...220518034729_create_email_errors_table.php | 1 + ...18035532_create_groups_templates_table.php | 1 + ...20220518040058_create_group_sync_table.php | 1 + .../20220518040456_create_hooks_table.php | 1 + .../20220518040806_create_ip_bans_table.php | 1 + ...0220519020719_create_infractions_table.php | 1 + .../20220519021237_create_logs_table.php | 1 + ...20220519021711_create_mc_servers_table.php | 1 + .../20220519022400_create_modules_table.php | 1 + .../20220519022945_create_widgets_table.php | 1 + ...20519023439_create_privacy_terms_table.php | 1 + .../20220519023748_create_oauth_table.php | 1 + ...0220519024247_create_oauth_users_table.php | 1 + ...20519024833_create_online_guests_table.php | 1 + ...9025351_create_page_descriptions_table.php | 1 + ...19025851_create_private_messages_table.php | 1 + ..._create_private_messages_replies_table.php | 1 + ...02_create_private_messages_users_table.php | 1 + ...0519031223_create_profile_fields_table.php | 1 + ...1732_create_users_profile_fields_table.php | 1 + ...20519032328_create_users_session_table.php | 1 + .../20220519034124_create_users_ips_table.php | 1 + ...40344_create_users_admin_session_table.php | 1 + ...220519040925_create_integrations_table.php | 1 + ...041811_create_users_integrations_table.php | 1 + ...540_create_placeholders_settings_table.php | 1 + ...151124_create_users_placeholders_table.php | 1 + ...1_create_user_profile_wall_posts_table.php | 1 + ...ser_profile_wall_posts_reactions_table.php | 1 + ..._user_profile_wall_posts_replies_table.php | 1 + .../20220519153135_create_forums_table.php | 1 + .../20220519153136_create_topics_table.php | 1 + .../20220519153137_create_posts_table.php | 1 + .../20220519153139_create_reports_table.php | 1 + ...19153651_create_reports_comments_table.php | 1 + .../20220519154102_create_settings_table.php | 1 + ...220519154314_create_query_errors_table.php | 1 + ...20519154440_create_query_results_table.php | 1 + ...20519154832_create_forums_labels_table.php | 1 + ...19161304_create_topics_following_table.php | 1 + ...161539_create_forums_permissions_table.php | 1 + ...19161812_create_forums_reactions_table.php | 1 + ...61954_create_forums_topic_labels_table.php | 1 + ...20220525051321_create_uuid_cache_table.php | 1 + ...37_create_users_username_history_table.php | 1 + .../20220602132634_nullable_post_date.php | 1 + ...mn_nullable_on_user_integrations_table.php | 1 + ...p_group_html_lg_column_on_groups_table.php | 1 + ...20620183016_add_module_settings_column.php | 9 +- ...20190645_move_email_settings_to_config.php | 9 +- .../20220805152044_forum_post_medium_text.php | 1 + ...0805152052_private_message_medium_text.php | 1 + ...20220805152101_custom_page_medium_text.php | 1 + .../20220805153842_log_info_medium_text.php | 1 + .../20220805174255_settings_value_text.php | 1 + ...2446_add_user_session_activity_columns.php | 1 + ...20807153708_delete_admin_session_table.php | 1 + ...220921014904_create_member_lists_table.php | 1 + ...230144555_reports_reported_id_nullable.php | 1 + ...230114124352_users_night_mode_nullable.php | 1 + ...5140_add_auth_me_columns_to_user_table.php | 1 + .../20230206192726_create_queue_table.php | 1 + ...50_add_order_column_to_reactions_table.php | 1 + ...mage_column_to_page_descriptions_table.php | 1 + ...4231334_delete_users_reputation_column.php | 1 + ...custom_score_column_to_reactions_table.php | 1 + ...t_reaction_scores_member_list_provider.php | 1 + core/migrations/phinx.php | 2 +- core/templates/cc_navbar.php | 4 +- core/templates/footer.php | 8 +- core/templates/frontend_init.php | 8 +- core/templates/navbar.php | 32 +-- core/templates/panel_navbar.php | 2 +- custom/panel_templates/Default/template.php | 28 +-- custom/templates/DefaultRevamp/template.php | 14 +- .../template_settings/settings.php | 28 +-- dev/phpcs.xml | 76 ------ dev/scripts/cli_install.php | 57 ++--- dev/scripts/language_convert.php | 23 +- dev/scripts/seeder/ForumCategorySeeder.php | 7 +- dev/scripts/seeder/ForumPostSeeder.php | 7 +- dev/scripts/seeder/ForumSubforumSeeder.php | 7 +- dev/scripts/seeder/ForumTopicSeeder.php | 7 +- .../seeder/MinecraftPlaceholderDataSeeder.php | 9 +- .../seeder/MinecraftPlaceholderSeeder.php | 11 +- dev/scripts/seeder/MinecraftServerSeeder.php | 7 +- .../seeder/ProfileFieldsDataSeeder.php | 7 +- dev/scripts/seeder/ProfileFieldsSeeder.php | 7 +- dev/scripts/seeder/Seeder.php | 26 +- dev/scripts/seeder/UserProfilePostSeeder.php | 7 +- dev/scripts/seeder/UserSeeder.php | 17 +- dev/scripts/seeder/db_seeder.php | 14 +- dev/scripts/verify_checksums.php | 1 + index.php | 13 +- install.php | 1 + 220 files changed, 2761 insertions(+), 2098 deletions(-) create mode 100644 .styleci.yml delete mode 100644 dev/phpcs.xml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 86974b4295..7c86e6c908 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: operating-system: ["ubuntu-latest"] - php-versions: ["7.4", "8.0", "8.1", "8.2"] + php-versions: ["7.4", "8.0", "8.1", "8.2", "8.3"] steps: - uses: actions/checkout@v2 @@ -23,16 +23,6 @@ jobs: - name: Execute PHPStan run: vendor/bin/phpstan --configuration=dev/phpstan.neon - code-style: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - - name: PHP Code Style (phpcs) - uses: chindit/actions-phpcs@master - with: - cli: -q --standard=dev/phpcs.xml - unused-language-term-check: runs-on: ubuntu-latest steps: diff --git a/.styleci.yml b/.styleci.yml new file mode 100644 index 0000000000..3f49580768 --- /dev/null +++ b/.styleci.yml @@ -0,0 +1,13 @@ +risky: false +version: 7.4 +preset: recommended +monolithic: true +finder: + name: "*.php" +disabled: + - align_double_arrow + - phpdoc_no_package + - concat_without_spaces + - include + - die_to_exit + - phpdoc_separation \ No newline at end of file diff --git a/403.php b/403.php index be16b3ae87..251528e72d 100644 --- a/403.php +++ b/403.php @@ -33,7 +33,7 @@ 'HOME' => $language->get('errors', '403_home'), 'LOGIN' => $language->get('general', 'sign_in'), 'LOGIN_LINK' => URL::build('/login'), - 'PATH' => (defined('CONFIG_PATH') ? CONFIG_PATH : '') + 'PATH' => (defined('CONFIG_PATH') ? CONFIG_PATH : ''), ] ); diff --git a/404.php b/404.php index 95509df970..eed1f38baa 100644 --- a/404.php +++ b/404.php @@ -31,7 +31,7 @@ 'BACK' => $language->get('errors', '404_back'), 'HOME' => $language->get('errors', '404_home'), 'ERROR' => $language->get('errors', '404_error'), - 'PATH' => (defined('CONFIG_PATH') ? CONFIG_PATH : '') + 'PATH' => (defined('CONFIG_PATH') ? CONFIG_PATH : ''), ] ); diff --git a/core/avatar/face.php b/core/avatar/face.php index ffb63109e5..bd91eae52b 100644 --- a/core/avatar/face.php +++ b/core/avatar/face.php @@ -17,8 +17,8 @@ $view = isset($_GET['v']) ? $_GET['v'][0] : 'f'; $view = in_array($view, ['f', 'l', 'r', 'b']) ? $view : 'f'; -function get_skin($user, $cache) { - +function get_skin($user, $cache) +{ // Check cache $cache->setCache('avatarCache_' . $user); if ($cache->isCached($user)) { @@ -49,7 +49,6 @@ function get_skin($user, $cache) { $output .= 'Ne9AAAAAElFTkSuQmCC'; $output = base64_decode($output); if ($user != '') { - $json = HttpClient::get('https://sessionserver.mojang.com/session/minecraft/profile/' . $user)->json(); if (isset($json->properties[0]->value)) { diff --git a/core/classes/Avatars/AvatarSource.php b/core/classes/Avatars/AvatarSource.php index fc647fe956..2de54b628e 100644 --- a/core/classes/Avatars/AvatarSource.php +++ b/core/classes/Avatars/AvatarSource.php @@ -7,8 +7,8 @@ * @version 2.0.0-pr10 * @license MIT */ -class AvatarSource { - +class AvatarSource +{ protected static array $_sources = []; protected static AvatarSourceBase $_active_source; @@ -18,11 +18,12 @@ class AvatarSource { * Uses active avatar source to get the URL of their Minecraft avatar. * * @param string $uuid UUID of avatar to get. - * @param int $size Size in pixels to render avatar at. Default 128 + * @param int $size Size in pixels to render avatar at. Default 128 * * @return string Compiled URL of avatar image. */ - public static function getAvatarFromUUID(string $uuid, int $size = 128): string { + public static function getAvatarFromUUID(string $uuid, int $size = 128): string + { return self::getActiveSource()->getAvatar($uuid, self::getDefaultPerspective(), $size); } @@ -30,14 +31,15 @@ public static function getAvatarFromUUID(string $uuid, int $size = 128): string * Get a user's avatar from their raw data object. * Used by the API for TinyMCE mention avatars to avoid reloading the user from the database. * - * @param object $data User data to use - * @param bool $allow_gifs Whether to allow GIFs or not () - * @param int $size Size in pixels to render avatar at. Default 128 - * @param bool $full Whether to return the full URL or just the path + * @param object $data User data to use + * @param bool $allow_gifs Whether to allow GIFs or not () + * @param int $size Size in pixels to render avatar at. Default 128 + * @param bool $full Whether to return the full URL or just the path * * @return string Full URL of avatar image. */ - public static function getAvatarFromUserData(object $data, bool $allow_gifs = false, int $size = 128, bool $full = false): string { + public static function getAvatarFromUserData(object $data, bool $allow_gifs = false, int $size = 128, bool $full = false): string + { // If custom avatars are enabled, first check if they have gravatar enabled, and then fallback to normal image if (defined('CUSTOM_AVATARS')) { if ($data->gravatar) { @@ -95,10 +97,11 @@ public static function getAvatarFromUserData(object $data, bool $allow_gifs = fa /** * Determine if a URL is a valid image URL for avatars. * - * @param string $url URL to check - * @return bool Whether the URL is a valid image URL + * @param string $url URL to check + * @return bool Whether the URL is a valid image URL */ - private static function validImageUrl(string $url): bool { + private static function validImageUrl(string $url): bool + { $cache = new Cache(['name' => 'nameless', 'extension' => '.cache', 'path' => ROOT_PATH . '/cache/']); $cache->setCache('avatar_validity'); @@ -107,6 +110,7 @@ private static function validImageUrl(string $url): bool { } $is_valid = false; + try { $response = HttpClient::createClient()->head($url); $headers = $response->getHeaders(); @@ -117,6 +121,7 @@ private static function validImageUrl(string $url): bool { } $cache->store($url, $is_valid, 3600); + return $is_valid; } @@ -125,7 +130,8 @@ private static function validImageUrl(string $url): bool { * * @return AvatarSourceBase The active source. */ - public static function getActiveSource(): AvatarSourceBase { + public static function getActiveSource(): AvatarSourceBase + { return self::$_active_source; } @@ -135,7 +141,8 @@ public static function getActiveSource(): AvatarSourceBase { * * @param string $name Name of source to set as active. */ - public static function setActiveSource(string $name): void { + public static function setActiveSource(string $name): void + { $source = self::getSourceByName($name); if ($source === null) { $source = self::getSourceByName('cravatar'); @@ -149,7 +156,8 @@ public static function setActiveSource(string $name): void { * * @return string Perspective. */ - private static function getDefaultPerspective(): string { + private static function getDefaultPerspective(): string + { if (defined('DEFAULT_AVATAR_PERSPECTIVE')) { return DEFAULT_AVATAR_PERSPECTIVE; } @@ -162,7 +170,8 @@ private static function getDefaultPerspective(): string { * * @return AvatarSourceBase|null Instance if found, null if not found. */ - public static function getSourceByName(string $name): ?AvatarSourceBase { + public static function getSourceByName(string $name): ?AvatarSourceBase + { foreach (self::getAllSources() as $source) { if (strtolower($source->getName()) == strtolower($name)) { return $source; @@ -177,7 +186,8 @@ public static function getSourceByName(string $name): ?AvatarSourceBase { * * @return AvatarSourceBase[] */ - public static function getAllSources(): iterable { + public static function getAllSources(): iterable + { return self::$_sources; } @@ -186,10 +196,12 @@ public static function getAllSources(): iterable { * * @return string URL with placeholders. */ - public static function getUrlToFormat(): string { + public static function getUrlToFormat(): string + { // Default to Cravatar if (!isset(self::$_active_source)) { require_once(ROOT_PATH . '/modules/Core/classes/Avatars/CravatarAvatarSource.php'); + return (new CravatarAvatarSource())->getUrlToFormat(self::getDefaultPerspective()); } @@ -201,7 +213,8 @@ public static function getUrlToFormat(): string { * * @param AvatarSourceBase $source Instance of avatar source to register. */ - public static function registerSource(AvatarSourceBase $source): void { + public static function registerSource(AvatarSourceBase $source): void + { self::$_sources[] = $source; } @@ -211,7 +224,8 @@ public static function registerSource(AvatarSourceBase $source): void { * * @return array List of names. */ - public static function getAllSourceNames(): array { + public static function getAllSourceNames(): array + { $names = []; foreach (self::getAllSources() as $source) { @@ -227,7 +241,8 @@ public static function getAllSourceNames(): array { * * @return array> Array of source => [] perspectives. */ - public static function getAllPerspectives(): array { + public static function getAllPerspectives(): array + { $perspectives = []; foreach (self::getAllSources() as $source) { diff --git a/core/classes/Avatars/AvatarSourceBase.php b/core/classes/Avatars/AvatarSourceBase.php index 14ecde017c..867040507c 100644 --- a/core/classes/Avatars/AvatarSourceBase.php +++ b/core/classes/Avatars/AvatarSourceBase.php @@ -7,8 +7,8 @@ * @version 2.0.0-pr10 * @license MIT */ -abstract class AvatarSourceBase { - +abstract class AvatarSourceBase +{ protected string $_name; /** @@ -27,7 +27,8 @@ abstract class AvatarSourceBase { * * @return string Name of this avatar source. */ - public function getName(): string { + public function getName(): string + { return $this->_name; } @@ -36,7 +37,8 @@ public function getName(): string { * * @return string Base url of this source. */ - public function getBaseUrl(): string { + public function getBaseUrl(): string + { return $this->_base_url; } @@ -45,20 +47,22 @@ public function getBaseUrl(): string { * * @return array Array of perspective names. */ - public function getPerspectives(): array { + public function getPerspectives(): array + { return array_keys($this->_perspectives_map); } /** * Get the URL for this users avatar. * - * @param string $uuid UUID of avatar to get. + * @param string $uuid UUID of avatar to get. * @param string $perspective Perspective to render avatar with. - * @param int $size Size in pixels to render avatar at. Default 128 + * @param int $size Size in pixels to render avatar at. Default 128 * * @return string Compiled URL of avatar image. */ - public function getAvatar(string $uuid, string $perspective, int $size = 128): string { + public function getAvatar(string $uuid, string $perspective, int $size = 128): string + { return $this->formatUrl($this->getUrlToFormat($perspective), $uuid, $size); } @@ -66,12 +70,13 @@ public function getAvatar(string $uuid, string $perspective, int $size = 128): s * Replace placeholders in raw url with uuid and size of requested avatar. * * @param string $url_to_format Raw url to replace placeholders in. - * @param string $uuid uuid (or username, yuck!) of avatar to get. - * @param int $size Size of avatar image in pixels to get. + * @param string $uuid uuid (or username, yuck!) of avatar to get. + * @param int $size Size of avatar image in pixels to get. * * @return string Formatted url. */ - public function formatUrl(string $url_to_format, string $uuid, int $size): string { + public function formatUrl(string $url_to_format, string $uuid, int $size): string + { return str_replace( ['{identifier}', '{size}'], [$uuid, $size], @@ -82,7 +87,7 @@ public function formatUrl(string $url_to_format, string $uuid, int $size): strin /** * Get raw URL with placeholders to format. * - `{identifier} = UUID / username` - * - `{size} = size in pixels` + * - `{size} = size in pixels`. * * @param string $perspective Perspective to use in url. * @@ -93,17 +98,19 @@ abstract public function getUrlToFormat(string $perspective): string; /** * Translate NamelessMC perspective name to the relative name for this avatar source. * - * @param string $perspective NamelessMC perspective name to translate. - * @return string Translated perspective name. + * @param string $perspective NamelessMC perspective name to translate. * @throws InvalidArgumentException When an invalid perspective is passed. + * @return string Translated perspective name. */ - public function getRelativePerspective(string $perspective): string { + public function getRelativePerspective(string $perspective): string + { $perspective = strtolower($perspective); if (isset($this->_perspectives_map[$perspective])) { return $this->_perspectives_map[$perspective]; } $class = static::class; + throw new InvalidArgumentException("Attempted to get invalid perspective of: {$perspective} on {$class}"); } } diff --git a/core/classes/Collections/Collection.php b/core/classes/Collections/Collection.php index 66b611ee15..1f2feab15c 100644 --- a/core/classes/Collections/Collection.php +++ b/core/classes/Collections/Collection.php @@ -1,29 +1,32 @@ _items = []; } - public function addItem(CollectionItemBase $item): void { + public function addItem(CollectionItemBase $item): void + { $this->_items[] = $item; } /** * @return CollectionItemBase[] */ - public function getEnabledItems(): array { + public function getEnabledItems(): array + { $items = []; foreach ($this->_items as $item) { @@ -42,7 +45,8 @@ public function getEnabledItems(): array { /** * @return CollectionItemBase[] */ - public function getAllItems(): array { + public function getAllItems(): array + { $items = $this->_items; uasort($items, static function (CollectionItemBase $a, CollectionItemBase $b) { return $a->getOrder() - $b->getOrder(); diff --git a/core/classes/Collections/CollectionItemBase.php b/core/classes/Collections/CollectionItemBase.php index 0bd17f67d6..669eec07c8 100644 --- a/core/classes/Collections/CollectionItemBase.php +++ b/core/classes/Collections/CollectionItemBase.php @@ -8,21 +8,24 @@ * @version 2.0.0-pr8 * @license MIT */ -abstract class CollectionItemBase { - +abstract class CollectionItemBase +{ private int $_order; private bool $_enabled; - public function __construct(int $order, bool $enabled) { + public function __construct(int $order, bool $enabled) + { $this->_order = $order; $this->_enabled = $enabled; } - public function getOrder(): int { + public function getOrder(): int + { return $this->_order; } - public function isEnabled(): bool { + public function isEnabled(): bool + { return $this->_enabled; } diff --git a/core/classes/Collections/CollectionManager.php b/core/classes/Collections/CollectionManager.php index 1f6a7a289e..f07649b470 100644 --- a/core/classes/Collections/CollectionManager.php +++ b/core/classes/Collections/CollectionManager.php @@ -8,12 +8,13 @@ * @version 2.0.0-pr8 * @license MIT */ -class CollectionManager { - +class CollectionManager +{ /** @var Collection[] */ private static array $_collections = []; - public static function addItemToCollection(string $collection, CollectionItemBase $item): void { + public static function addItemToCollection(string $collection, CollectionItemBase $item): void + { if (!isset(self::$_collections[$collection])) { self::$_collections[$collection] = new Collection(); } @@ -22,20 +23,22 @@ public static function addItemToCollection(string $collection, CollectionItemBas } /** - * @param string $collection + * @param string $collection * @return CollectionItemBase[] */ - public static function getFullCollection(string $collection): array { + public static function getFullCollection(string $collection): array + { return isset(self::$_collections[$collection]) ? self::$_collections[$collection]->getAllItems() : []; } /** - * @param string $collection + * @param string $collection * @return CollectionItemBase[] */ - public static function getEnabledCollection(string $collection): array { + public static function getEnabledCollection(string $collection): array + { return isset(self::$_collections[$collection]) ? self::$_collections[$collection]->getEnabledItems() : []; diff --git a/core/classes/Core/Alert.php b/core/classes/Core/Alert.php index 092ee49c3b..fb9d6d675b 100644 --- a/core/classes/Core/Alert.php +++ b/core/classes/Core/Alert.php @@ -7,18 +7,19 @@ * @version 2.0.0-pr8 * @license MIT */ -class Alert { - +class Alert +{ /** * Creates an alert for the specified user. * - * @param int $user_id Contains the ID of the user who we are creating the alert for. - * @param string $type Contains the alert type, eg 'tag' for user tagging. - * @param array $text_short Contains the alert text in short form for the dropdown. - * @param array $text Contains full information about the alert. - * @param string $link Contains link to view the alert, defaults to #. + * @param int $user_id Contains the ID of the user who we are creating the alert for. + * @param string $type Contains the alert type, eg 'tag' for user tagging. + * @param array $text_short Contains the alert text in short form for the dropdown. + * @param array $text Contains full information about the alert. + * @param string $link Contains link to view the alert, defaults to #. */ - public static function create(int $user_id, string $type, array $text_short, array $text, string $link = '#'): void { + public static function create(int $user_id, string $type, array $text_short, array $text, string $link = '#'): void + { $db = DB::getInstance(); $language = $db->query('SELECT nl2_languages.short_code AS `short_code` FROM nl2_users LEFT JOIN nl2_languages ON nl2_languages.id = nl2_users.language_id WHERE nl2_users.id = ?', [$user_id]); @@ -33,21 +34,22 @@ public static function create(int $user_id, string $type, array $text_short, arr 'user_id' => $user_id, 'type' => $type, 'url' => $link, - 'content_short' => str_replace(($text_short['replace'] ?? ''), ($text_short['replace_with'] ?? ''), $language->get($text_short['file'], $text_short['term'])), - 'content' => str_replace(($text['replace'] ?? ''), ($text['replace_with'] ?? ''), $language->get($text['file'], $text['term'])), - 'created' => date('U') + 'content_short' => str_replace($text_short['replace'] ?? '', $text_short['replace_with'] ?? '', $language->get($text_short['file'], $text_short['term'])), + 'content' => str_replace($text['replace'] ?? '', $text['replace_with'] ?? '', $language->get($text['file'], $text['term'])), + 'created' => date('U'), ]); } /** * Get user alerts. * - * @param int $user_id Contains the ID of the user who we are getting alerts for. - * @param bool $all Do we want to get all alerts (including read), or not; defaults to false). + * @param int $user_id Contains the ID of the user who we are getting alerts for. + * @param bool $all Do we want to get all alerts (including read), or not; defaults to false). * * @return array All their alerts. */ - public static function getAlerts(int $user_id, bool $all = false): array { + public static function getAlerts(int $user_id, bool $all = false): array + { $db = DB::getInstance(); if ($all == true) { @@ -60,12 +62,13 @@ public static function getAlerts(int $user_id, bool $all = false): array { /** * Get a users unread messages. * - * @param int $user_id The ID of the user who we are getting messages for. - * @param bool $all Get all alerts (including read), or not. Defaults to false. + * @param int $user_id The ID of the user who we are getting messages for. + * @param bool $all Get all alerts (including read), or not. Defaults to false. * * @return array All their messages matching the $all filter. */ - public static function getPMs(int $user_id, bool $all = false): array { + public static function getPMs(int $user_id, bool $all = false): array + { $db = DB::getInstance(); if ($all == true) { @@ -88,7 +91,7 @@ public static function getPMs(int $user_id, bool $all = false): array { 'created' => $pm_full->created, 'author_id' => $pm_full->author_id, 'last_reply_user' => $pm_full->last_reply_user, - 'last_reply_date' => $pm_full->last_reply_date + 'last_reply_date' => $pm_full->last_reply_date, ]; } @@ -114,7 +117,7 @@ public static function getPMs(int $user_id, bool $all = false): array { 'created' => $pm_full->created, 'author_id' => $pm_full->author_id, 'last_reply_user' => $pm_full->last_reply_user, - 'last_reply_date' => $pm_full->last_reply_date + 'last_reply_date' => $pm_full->last_reply_date, ]; } } diff --git a/core/classes/Core/Cache.php b/core/classes/Core/Cache.php index eac1db5d74..f55c2db5f1 100644 --- a/core/classes/Core/Cache.php +++ b/core/classes/Core/Cache.php @@ -7,34 +7,35 @@ * @version 1.6-Nameless * @license BSD http://www.opensource.org/licenses/bsd-license.php */ -class Cache { - +class Cache +{ /** - * The path to the cache file folder + * The path to the cache file folder. */ private string $_cachepath = 'cache/'; /** - * The name of the default cache file + * The name of the default cache file. */ private string $_cachename = 'default'; /** - * The cache file extension + * The cache file extension. */ private string $_extension = '.cache'; /** - * Create a new Cache instance + * Create a new Cache instance. * - * @param string|array $config (optional) + * @param string|array $config (optional) * @return void */ - public function __construct($config = null) { + public function __construct($config = null) + { if (isset($config)) { if (is_string($config)) { $this->setCache($config); - } else if (is_array($config)) { + } elseif (is_array($config)) { $this->setCache($config['name']); $this->setCachePath($config['path']); $this->setExtension($config['extension']); @@ -43,23 +44,26 @@ public function __construct($config = null) { } /** - * Cache name Setter + * Cache name Setter. * - * @param string $name Name of cache file to use + * @param string $name Name of cache file to use * @return Cache */ - public function setCache(string $name): Cache { + public function setCache(string $name): Cache + { $this->_cachename = $name; + return $this; } /** - * Check whether data is accociated with a key + * Check whether data is accociated with a key. * - * @param string $key The key to check + * @param string $key The key to check * @return bool */ - public function isCached(string $key): bool { + public function isCached(string $key): bool + { if ($this->_loadCache()) { $cachedData = $this->_loadCache(); if (isset($cachedData[$key])) { @@ -76,13 +80,15 @@ public function isCached(string $key): bool { } /** - * Load appointed cache + * Load appointed cache. * * @return mixed */ - private function _loadCache() { + private function _loadCache() + { if (file_exists($this->getCacheDir())) { $file = file_get_contents($this->getCacheDir()); + return json_decode($file, true); } @@ -90,14 +96,16 @@ private function _loadCache() { } /** - * Get the cache directory path + * Get the cache directory path. * * @return string */ - public function getCacheDir(): string { + public function getCacheDir(): string + { if ($this->_checkCacheDir()) { $filename = $this->getCache(); $filename = preg_replace('/[^0-9a-z\.\_\-]/i', '', strtolower($filename)); + return $this->getCachePath() . $this->_getHash($filename) . $this->getExtension(); } @@ -105,11 +113,12 @@ public function getCacheDir(): string { } /** - * Check if a writable cache directory exists and if not create a new one + * Check if a writable cache directory exists and if not create a new one. * * @return bool */ - private function _checkCacheDir(): bool { + private function _checkCacheDir(): bool + { if (!is_dir($this->getCachePath()) && !mkdir($this->getCachePath(), 0775, true)) { throw new RuntimeException('Unable to create cache directory ' . $this->getCachePath()); } @@ -119,98 +128,110 @@ private function _checkCacheDir(): bool { throw new RuntimeException('Your ' . $this->getCachePath() . ' directory must be readable and writeable. Check your file permissions.'); } } + return true; } /** - * Cache path Getter + * Cache path Getter. * * @return string The path to the cache file folder */ - public function getCachePath(): string { + public function getCachePath(): string + { return $this->_cachepath; } /** - * Cache path Setter + * Cache path Setter. * - * @param string $path + * @param string $path * @return Cache */ - public function setCachePath(string $path): Cache { + public function setCachePath(string $path): Cache + { $this->_cachepath = $path; + return $this; } /** - * Cache name Getter + * Cache name Getter. * * @return string Cache name */ - public function getCache(): string { + public function getCache(): string + { return $this->_cachename; } /** - * Get the filename hash + * Get the filename hash. * - * @param string $filename + * @param string $filename * @return string The hashed filename */ - private function _getHash(string $filename): string { + private function _getHash(string $filename): string + { return sha1($filename); } /** - * Cache file extension Getter + * Cache file extension Getter. * * @return string Cache file extension */ - public function getExtension(): string { + public function getExtension(): string + { return $this->_extension; } /** - * Cache file extension Setter + * Cache file extension Setter. * - * @param string $ext Extension to use + * @param string $ext Extension to use * @return Cache */ - public function setExtension(string $ext): Cache { + public function setExtension(string $ext): Cache + { $this->_extension = $ext; + return $this; } /** - * Check whether a timestamp is still in the duration + * Check whether a timestamp is still in the duration. * - * @param int $timestamp Timestamp to check - * @param int $expiration Duration to check + * @param int $timestamp Timestamp to check + * @param int $expiration Duration to check * @return bool True if still in duration */ - private function _checkExpired(int $timestamp, int $expiration): bool { + private function _checkExpired(int $timestamp, int $expiration): bool + { $result = false; if ($expiration !== 0) { $timeDiff = time() - $timestamp; $result = $timeDiff > $expiration; } + return $result; } /** - * Store data in the cache + * Store data in the cache. * - * @param string $key Key to store data under - * @param mixed $data Data to store - * @param int $expiration Expiration time in seconds + * @param string $key Key to store data under + * @param mixed $data Data to store + * @param int $expiration Expiration time in seconds * * @return Cache */ - public function store(string $key, $data, int $expiration = 0): Cache { + public function store(string $key, $data, int $expiration = 0): Cache + { $storeData = [ 'time' => time(), 'expire' => $expiration, - 'data' => serialize($data) + 'data' => serialize($data), ]; $dataArray = $this->_loadCache(); if (is_array($dataArray)) { @@ -220,18 +241,20 @@ public function store(string $key, $data, int $expiration = 0): Cache { } $cacheData = json_encode($dataArray); file_put_contents($this->getCacheDir(), $cacheData); + return $this; } /** - * Retrieve cached data by its key + * Retrieve cached data by its key. * - * @param string $key The key to retrieve - * @param bool $timestamp Whether to check if the cache is expired + * @param string $key The key to retrieve + * @param bool $timestamp Whether to check if the cache is expired * * @return mixed The cached data or null if not found/expired */ - public function retrieve(string $key, bool $timestamp = false) { + public function retrieve(string $key, bool $timestamp = false) + { $cachedData = $this->_loadCache(); $type = $timestamp ? 'time' : 'data'; @@ -250,12 +273,13 @@ public function retrieve(string $key, bool $timestamp = false) { } /** - * Retrieve all cached data + * Retrieve all cached data. * - * @param bool $meta (optional) + * @param bool $meta (optional) * @return array The cached data */ - public function retrieveAll(bool $meta = false): array { + public function retrieveAll(bool $meta = false): array + { if ($meta) { return $this->_loadCache(); } @@ -267,16 +291,18 @@ public function retrieveAll(bool $meta = false): array { $results[$k] = unserialize($v['data']); } } + return $results; } /** - * Erase cached entry by its key + * Erase cached entry by its key. * - * @param string $key The key to erase + * @param string $key The key to erase * @return Cache */ - public function erase(string $key): Cache { + public function erase(string $key): Cache + { $cacheData = $this->_loadCache(); if (is_array($cacheData)) { if (isset($cacheData[$key])) { @@ -287,15 +313,17 @@ public function erase(string $key): Cache { throw new RuntimeException("Error: erase() - Key '$key' not found."); } } + return $this; } /** - * Erase all expired entries + * Erase all expired entries. * * @return int Number of entries erased */ - public function eraseExpired(): int { + public function eraseExpired(): int + { $cacheData = $this->_loadCache(); if (is_array($cacheData)) { $counter = 0; @@ -309,6 +337,7 @@ public function eraseExpired(): int { $cacheData = json_encode($cacheData); file_put_contents($this->getCacheDir(), $cacheData); } + return $counter; } @@ -316,16 +345,18 @@ public function eraseExpired(): int { } /** - * Erase all cached entries + * Erase all cached entries. * * @return Cache */ - public function eraseAll(): Cache { + public function eraseAll(): Cache + { $cacheDir = $this->getCacheDir(); if (file_exists($cacheDir)) { $cacheFile = fopen($cacheDir, 'wb'); fclose($cacheFile); } + return $this; } } diff --git a/core/classes/Core/Config.php b/core/classes/Core/Config.php index 1e82dede81..427b0619a0 100644 --- a/core/classes/Core/Config.php +++ b/core/classes/Core/Config.php @@ -7,15 +7,16 @@ * @version 2.0.0 * @license MIT */ -class Config { - +class Config +{ private static ?array $_config_cache = null; /** * @return bool Whether `/core` folder is writable to create `config.php` file in, - * or if the file exists and is writable. + * or if the file exists and is writable. */ - public static function writeable(): bool { + public static function writeable(): bool + { clearstatcache(); if (self::exists()) { return is_writable(ROOT_PATH . '/core/config.php'); @@ -27,16 +28,18 @@ public static function writeable(): bool { /** * @return bool Whether config file exists */ - public static function exists(): bool { + public static function exists(): bool + { return file_exists(ROOT_PATH . '/core/config.php'); } /** - * Read `core/config.php` file and load into cache + * Read `core/config.php` file and load into cache. * * @return array The entire config array */ - public static function all(): array { + public static function all(): array + { if (self::$_config_cache !== null) { return self::$_config_cache; } @@ -53,7 +56,8 @@ public static function all(): array { * * @param array $config New config array to store. */ - public static function write(array $config): void { + public static function write(array $config): void + { $contents = ' $value) { @@ -151,10 +157,11 @@ public static function setMultiple(array $values): void { * Parse a string path to an array of config paths. * Will log a warning if a legacy path (using `/` is used). * - * @param string $path Path to parse. + * @param string $path Path to parse. * @return string|array Path split into sections or plain string if no section seperator was found. */ - private static function parsePath(string $path) { + private static function parsePath(string $path) + { if (str_contains($path, '.')) { return explode('.', $path); } @@ -162,6 +169,7 @@ private static function parsePath(string $path) { // TODO: Remove for 2.1.0 if (str_contains($path, '/')) { ErrorHandler::logWarning("Legacy config path: {$path}. Please use periods to seperate paths."); + return explode('/', $path); } @@ -172,14 +180,16 @@ private static function parsePath(string $path) { * Converts an array to a string to be inserted into the config file, with shorthand array syntax. * * @link https://gist.github.com/Bogdaan/ffa287f77568fcbb4cffa0082e954022 - * @param array $config Config array to convert to string. + * @param array $config Config array to convert to string. * @return string PHP code for the config array */ - private static function arrayToString(array $config): string { + private static function arrayToString(array $config): string + { $export = var_export($config, true); $export = preg_replace("/^(' '*)(.*)/m", '$1$1$2', $export); $array = preg_split("/\r\n|\n|\r/", $export); $array = preg_replace(["/\s*array\s\($/", "/\)(,)?$/", "/\s=>\s$/"], [null, ']$1', ' => ['], $array); - return implode(PHP_EOL, array_filter(["["] + ($array ?: []))); + + return implode(PHP_EOL, array_filter(['['] + ($array ?: []))); } } diff --git a/core/classes/Core/Configuration.php b/core/classes/Core/Configuration.php index 232a699aee..1710c9d38c 100644 --- a/core/classes/Core/Configuration.php +++ b/core/classes/Core/Configuration.php @@ -8,11 +8,12 @@ * @license MIT * @deprecated Use Util::getSetting and Util::setSetting with $module parameter instead. Will be removed in 2.2.0 */ -class Configuration { - +class Configuration +{ private string $_module; - public function __construct(string $module) { + public function __construct(string $module) + { if ($module === 'Core') { throw new InvalidArgumentException('Configuration class should not be used for the Core module'); } @@ -21,17 +22,19 @@ public function __construct(string $module) { } /** - * Get a configuration value + * Get a configuration value. * * @param string $setting Setting name * * @return mixed The configuration value */ - public function get(string $setting) { + public function get(string $setting) + { $table = 'nl2_' . preg_replace('/[^A-Za-z0-9_]+/', '', $this->_module) . '_settings'; $data = DB::getInstance()->query("SELECT value FROM $table WHERE `name` = ?", [$setting]); if ($data->count()) { $results = $data->results(); + return $results[0]->value; } @@ -39,12 +42,13 @@ public function get(string $setting) { } /** - * Set configuration value + * Set configuration value. * * @param string $setting Setting name - * @param mixed $value New value + * @param mixed $value New value */ - public function set(string $setting, $value): void { + public function set(string $setting, $value): void + { $table = 'nl2_' . preg_replace('/[^A-Za-z0-9_]+/', '', $this->_module) . '_settings'; DB::getInstance()->query("UPDATE $table SET `value` = ? WHERE `name` = ?", [ $value, diff --git a/core/classes/Core/Cookie.php b/core/classes/Core/Cookie.php index 69d1f7cbc0..d778f60b48 100644 --- a/core/classes/Core/Cookie.php +++ b/core/classes/Core/Cookie.php @@ -7,39 +7,42 @@ * @version 2.0.0-pr10 * @license MIT */ -class Cookie { - +class Cookie +{ /** * Check if the specified cookie exists. * - * @param string $name Name of cookie to check - * @return bool Whether this cookie exists or not. + * @param string $name Name of cookie to check + * @return bool Whether this cookie exists or not. */ - public static function exists(string $name): bool { + public static function exists(string $name): bool + { return isset($_COOKIE[$name]); } /** * Return the value of the specified cookie. * - * @param string $name Name of cookie to get the value of - * @return mixed Value of the cookie or an empty string if it doesn't exist + * @param string $name Name of cookie to get the value of + * @return mixed Value of the cookie or an empty string if it doesn't exist */ - public static function get(string $name) { + public static function get(string $name) + { return $_COOKIE[$name] ?? ''; } /** * Create a new cookie. * - * @param string $name Name of cookie to create. - * @param string $value Value to store in cookie. - * @param int $expiry When does the cookie expire? - * @param ?bool $secure Create as secure cookie? - * @param ?bool $httpOnly Create as httpOnly cookie? - * @return bool Whether cookie was set or not + * @param string $name Name of cookie to create. + * @param string $value Value to store in cookie. + * @param int $expiry When does the cookie expire? + * @param ?bool $secure Create as secure cookie? + * @param ?bool $httpOnly Create as httpOnly cookie? + * @return bool Whether cookie was set or not */ - public static function put(string $name, string $value, int $expiry, ?bool $secure = false, ?bool $httpOnly = false): bool { + public static function put(string $name, string $value, int $expiry, ?bool $secure = false, ?bool $httpOnly = false): bool + { return setcookie($name, $value, time() + $expiry, '/', null, $secure, $httpOnly); } @@ -48,7 +51,8 @@ public static function put(string $name, string $value, int $expiry, ?bool $secu * * @param string $name Name of cookie to delete */ - public static function delete(string $name): bool { + public static function delete(string $name): bool + { return setcookie($name, '', time() - 1, '/'); } } diff --git a/core/classes/Core/Date.php b/core/classes/Core/Date.php index 10988d3e41..5ccf413987 100644 --- a/core/classes/Core/Date.php +++ b/core/classes/Core/Date.php @@ -1,21 +1,22 @@ $recipient, 'subject' => $subject, @@ -51,22 +52,25 @@ public static function send(array $recipient, string $subject, string $message, } /** - * Get reply to array for send() + * Get reply to array for send(). * @return array Array with reply-to email address and name */ - public static function getReplyTo(): array { + public static function getReplyTo(): array + { return [ 'email' => Settings::get('incoming_email'), - 'name' => SITE_NAME + 'name' => SITE_NAME, ]; } + /** * Send an email using PHP's `mail()` function. * - * @param array $email Array containing `to`, `subject`, `message` and `headers` values. + * @param array $email Array containing `to`, `subject`, `message` and `headers` values. * @return array|bool Returns true if email sent, otherwise returns an array containing the error. */ - private static function sendPHP(array $email) { + private static function sendPHP(array $email) + { error_clear_last(); $outgoing_email = Settings::get('outgoing_email'); @@ -87,7 +91,7 @@ private static function sendPHP(array $email) { } return [ - 'error' => error_get_last()['message'] ?? 'Unknown error' + 'error' => error_get_last()['message'] ?? 'Unknown error', ]; } @@ -96,10 +100,11 @@ private static function sendPHP(array $email) { * * @see PHPMailer * - * @param array $email Array of email data to send. + * @param array $email Array of email data to send. * @return array|bool Returns true if email sent, otherwise returns an array containing the error. */ - private static function sendMailer(array $email) { + private static function sendMailer(array $email) + { try { // Initialise PHPMailer $mail = new PHPMailer(true); @@ -141,12 +146,11 @@ private static function sendMailer(array $email) { } return [ - 'error' => $mail->ErrorInfo + 'error' => $mail->ErrorInfo, ]; - } catch (Exception $e) { return [ - 'error' => $e->getMessage() + 'error' => $e->getMessage(), ]; } } @@ -154,21 +158,23 @@ private static function sendMailer(array $email) { /** * Add a custom placeholder/variable for email messages. * - * @param string $key The key to use for the placeholder, should be enclosed in square brackets. + * @param string $key The key to use for the placeholder, should be enclosed in square brackets. * @param string|Closure(Language, string): string $value The value to replace the placeholder with. */ - public static function addPlaceholder(string $key, $value): void { + public static function addPlaceholder(string $key, $value): void + { self::$_message_placeholders[$key] = $value; } /** * Format an email template and replace placeholders. * - * @param string $email Name of email to format. - * @param Language $viewing_language Instance of Language class to use for translations. - * @return string Formatted email. + * @param string $email Name of email to format. + * @param Language $viewing_language Instance of Language class to use for translations. + * @return string Formatted email. */ - public static function formatEmail(string $email, Language $viewing_language): string { + public static function formatEmail(string $email, Language $viewing_language): string + { $placeholders = array_keys(self::$_message_placeholders); $placeholder_values = []; diff --git a/core/classes/Core/Fields.php b/core/classes/Core/Fields.php index 32af8d33ed..dc8afaf466 100644 --- a/core/classes/Core/Fields.php +++ b/core/classes/Core/Fields.php @@ -1,14 +1,14 @@ _fields[$key] = [ 'name' => $label, 'type' => $type, @@ -45,22 +46,23 @@ public function add(string $key, int $type, string $label, bool $required = fals 'placeholder' => $placeholder ?? $label, 'info' => $info ?? '', 'options' => [], - 'order' => $order ?? count($this->_fields) + 'order' => $order ?? count($this->_fields), ]; } /** * Add a option to a field. * - * @param string $field Add the option to this field. - * @param string $value Field value. + * @param string $field Add the option to this field. + * @param string $value Field value. * @param string $option The option to display. */ - public function addOption(string $field, string $value, string $option): void { + public function addOption(string $field, string $value, string $option): void + { if (isset($this->_fields[$field])) { $this->_fields[$field]['options'][] = [ 'value' => $value, - 'option' => $option + 'option' => $option, ]; } } @@ -70,7 +72,8 @@ public function addOption(string $field, string $value, string $option): void { * * @return array List of fields. */ - public function getAll(): iterable { + public function getAll(): iterable + { $fields = $this->_fields; uasort($fields, static function ($a, $b) { @@ -79,4 +82,4 @@ public function getAll(): iterable { return $fields; } -} \ No newline at end of file +} diff --git a/core/classes/Core/HttpClient.php b/core/classes/Core/HttpClient.php index 7fb772db22..5a06371380 100755 --- a/core/classes/Core/HttpClient.php +++ b/core/classes/Core/HttpClient.php @@ -3,8 +3,8 @@ use GuzzleHttp\Client; use GuzzleHttp\Exception\GuzzleException; use GuzzleHttp\HandlerStack; -use GuzzleHttp\Profiling\Middleware as ProfilingMiddleware; use GuzzleHttp\Profiling\Debugbar\Profiler; +use GuzzleHttp\Profiling\Middleware as ProfilingMiddleware; use Psr\Http\Message\ResponseInterface; /** @@ -17,12 +17,13 @@ * @version 2.0.0-pr13 * @license MIT */ -class HttpClient { - +class HttpClient +{ private ?ResponseInterface $_response; private string $_error; - private function __construct(?ResponseInterface $response, string $error) { + private function __construct(?ResponseInterface $response, string $error) + { $this->_response = $response; $this->_error = $error; } @@ -31,11 +32,12 @@ private function __construct(?ResponseInterface $response, string $error) { * Make a GET request to a URL. * Failures will automatically be logged along with the error. * - * @param string $url URL to send request to. - * @param array $options Options to set with the GuzzleClient. + * @param string $url URL to send request to. + * @param array $options Options to set with the GuzzleClient. * @return HttpClient New HttpClient instance. */ - public static function get(string $url, array $options = []): HttpClient { + public static function get(string $url, array $options = []): HttpClient + { $guzzleClient = self::createClient($options); $error = ''; @@ -57,12 +59,13 @@ public static function get(string $url, array $options = []): HttpClient { * Make a POST request to a URL. * Failures will automatically be logged along with the error. * - * @param string $url URL to send request to. - * @param string|array $data JSON request body to attach to request, or array of key value pairs if form-urlencoded. - * @param array $options Options to set with the GuzzleClient. - * @return HttpClient New HttpClient instance. + * @param string $url URL to send request to. + * @param string|array $data JSON request body to attach to request, or array of key value pairs if form-urlencoded. + * @param array $options Options to set with the GuzzleClient. + * @return HttpClient New HttpClient instance. */ - public static function post(string $url, $data, array $options = []): HttpClient { + public static function post(string $url, $data, array $options = []): HttpClient + { $guzzleClient = self::createClient($options); $error = ''; @@ -86,10 +89,11 @@ public static function post(string $url, $data, array $options = []): HttpClient /** * Make a new Guzzle Client instance and attach it to the debug bar to display requests. * - * @param array $options Options to provide Guzzle instance. + * @param array $options Options to provide Guzzle instance. * @return Client New Guzzle instance. */ - public static function createClient(array $options = []): Client { + public static function createClient(array $options = []): Client + { $debugBar = DebugBarHelper::getInstance()->getDebugBar(); $stack = HandlerStack::create(); @@ -106,48 +110,53 @@ public static function createClient(array $options = []): Client { } /** - * Get the response body + * Get the response body. * * @return string The response body */ - public function contents(): string { + public function contents(): string + { return $this->_response->getBody()->getContents(); } /** - * Get the response body as a decoded JSON object + * Get the response body as a decoded JSON object. * - * @param bool $assoc Whether to decode the JSON as a PHP array if true or PHP object. + * @param bool $assoc Whether to decode the JSON as a PHP array if true or PHP object. * @return mixed The response body */ - public function json(bool $assoc = false) { + public function json(bool $assoc = false) + { return json_decode($this->contents(), $assoc); } /** - * Get the response HTTP status code + * Get the response HTTP status code. * * @return int The response code */ - public function getStatus(): int { + public function getStatus(): int + { return $this->_response->getStatusCode(); } /** - * Check if the response has an error + * Check if the response has an error. * * @return bool Whether the response has an error or not */ - public function hasError(): bool { + public function hasError(): bool + { return $this->getError() !== ''; } /** - * Get the error message + * Get the error message. * * @return string The error message */ - public function getError(): string { + public function getError(): string + { if ($this->_error !== '') { return Output::getClean($this->_error); } @@ -158,5 +167,4 @@ public function getError(): string { return ''; } - } diff --git a/core/classes/Core/Input.php b/core/classes/Core/Input.php index 0f313d8f98..00e558a563 100644 --- a/core/classes/Core/Input.php +++ b/core/classes/Core/Input.php @@ -1,27 +1,28 @@ get('general', 'spoiler')}', default_link_target: '_blank', skin: '$skin'," . @@ -182,12 +185,12 @@ public static function createTinyEditor(Language $language, string $name, ?strin xhr.send(formData); }, - " . ($admin ? 'valid_children: "+body[style],+body[link],+*[*]",' : '') . " - extended_valid_elements: " . ($admin ? + " . ($admin ? 'valid_children: "+body[style],+body[link],+*[*]",' : '') . ' + extended_valid_elements: ' . ($admin ? '"script[src|async|defer|type|charset],+@[data-options]"' - : 'undefined') . " + : 'undefined') . ' }); - "; + '; return $js; } diff --git a/core/classes/Core/Instanceable.php b/core/classes/Core/Instanceable.php index 103d3cf05f..81d3df3e3a 100644 --- a/core/classes/Core/Instanceable.php +++ b/core/classes/Core/Instanceable.php @@ -8,8 +8,8 @@ * @version 2.0.0-pr13 * @license MIT */ -class Instanceable { - +class Instanceable +{ /** * Stores instances of classes with their class name as key. * @@ -22,9 +22,9 @@ class Instanceable { * * @return static Instance of the class this was called on. */ - final public static function getInstance() { + final public static function getInstance() + { /** @phpstan-ignore-next-line */ return self::$_instances[static::class] ??= new static(); } - } diff --git a/core/classes/Core/Language.php b/core/classes/Core/Language.php index c1cba01cc0..0d878eda0a 100644 --- a/core/classes/Core/Language.php +++ b/core/classes/Core/Language.php @@ -10,8 +10,8 @@ use samerton\i18next\i18next; -class Language { - +class Language +{ /** * @var array Metadata about different languages available */ @@ -174,7 +174,8 @@ class Language { * * @return string Active language name. */ - public function getActiveLanguage(): string { + public function getActiveLanguage(): string + { return $this->_activeLanguage; } @@ -183,18 +184,20 @@ public function getActiveLanguage(): string { * * @return string Active language path. */ - public function getActiveLanguageFile(): string { + public function getActiveLanguageFile(): string + { return $this->_activeLanguageFile; } /** - * Construct Language class + * Construct Language class. * - * @param string $module Path to the custom language files to use, "core" by default for builtin language files. - * @param string|null $active_language The translation to use. + * @param string $module Path to the custom language files to use, "core" by default for builtin language files. + * @param string|null $active_language The translation to use. * @throws RuntimeException If the language file cannot be found. */ - public function __construct(string $module = 'core', string $active_language = null) { + public function __construct(string $module = 'core', string $active_language = null) + { $this->_activeLanguage = $active_language ?? LANGUAGE ?? 'en_UK'; // Require file @@ -224,14 +227,15 @@ public function __construct(string $module = 'core', string $active_language = n } /** - * Return a term in the currently active language + * Return a term in the currently active language. * - * @param string $section Section name. - * @param ?string $term The term to translate. - * @param array $variables Any variables to pass through to the translation. - * @return string Translated phrase. + * @param string $section Section name. + * @param ?string $term The term to translate. + * @param array $variables Any variables to pass through to the translation. + * @return string Translated phrase. */ - public function get(string $section, ?string $term = null, array $variables = []): string { + public function get(string $section, ?string $term = null, array $variables = []): string + { if ($term) { $section .= '/' . $term; } @@ -245,7 +249,8 @@ public function get(string $section, ?string $term = null, array $variables = [] * * @return Closure(int, array)|null Closure or null if not available. */ - public function getPluralForm(): ?Closure { + public function getPluralForm(): ?Closure + { if ($this->_activeLanguage === 'ru_RU' || $this->_activeLanguage === 'uk_UA') { return static function (int $count, array $forms) { if ($count % 10 === 1 && $count % 100 !== 11) { @@ -254,6 +259,7 @@ public function getPluralForm(): ?Closure { if ($count % 10 >= 2 && $count % 10 <= 4 && ($count % 100 < 10 || $count % 100 >= 20)) { return $forms[1]; } + return $forms[2]; }; } @@ -266,25 +272,27 @@ public function getPluralForm(): ?Closure { * Used for email message editing & dropdown name editing. * * @param string $section Name of file without extension to edit. - * @param string $term Term which value to change. - * @param string $value New value to set for term. + * @param string $term Term which value to change. + * @param string $value New value to set for term. */ - public function set(string $section, string $term, string $value): void { + public function set(string $section, string $term, string $value): void + { $json = json_decode(file_get_contents($this->_activeLanguageFile), true); $json[$section . '/' . $term] = $value; ksort($json); - file_put_contents($this->_activeLanguageFile, json_encode($json, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE)); + file_put_contents($this->_activeLanguageFile, json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); } /** * Attempt to get a language code from browser headers for setting an automatic language for guests. * - * @param string $header HTTP_ACCEPT_LANGUAGE header. + * @param string $header HTTP_ACCEPT_LANGUAGE header. * @return false|array The browsers preferred language and its name, or false if there is no valid preferred language. */ - public static function acceptFromHttp(string $header) { + public static function acceptFromHttp(string $header) + { // If the Intl extension is enabled, try to use the Locale::acceptFromHttp class, // which is more accurate than the below method, but often contains more specific languages than we support. if ( diff --git a/core/classes/Core/Log.php b/core/classes/Core/Log.php index 3e261b76f7..6feb389279 100644 --- a/core/classes/Core/Log.php +++ b/core/classes/Core/Log.php @@ -1,14 +1,14 @@ [ 'update' => 'acp_email_update', 'test' => 'acp_email_test', - 'mass_message' => 'acp_email_mass_message' + 'mass_message' => 'acp_email_mass_message', ], 'nav' => 'admin_nav_update', 'reaction' => [ 'update' => 'acp_reaction_update', 'add' => 'acp_reaction_add', - 'delete' => 'acp_reaction_remove' + 'delete' => 'acp_reaction_remove', ], 'social' => 'acp_social_update', 'term' => 'acp_term_update', @@ -165,7 +165,7 @@ class Log extends Instanceable { ], 'misc' => [ 'report' => 'report', - 'curl_error' => 'curl_error' + 'curl_error' => 'curl_error', ], 'api' => [ // TODO @@ -175,23 +175,25 @@ class Log extends Instanceable { 'role_set' => 'discord_role_set', ], 'mc_group_sync' => [ - 'role_set' => 'mc_group_sync_set' - ] + 'role_set' => 'mc_group_sync_set', + ], ]; private DB $_db; - public function __construct() { + public function __construct() + { $this->_db = DB::getInstance(); } /** * Get an action from the Action array. * - * @param string $path The path to the action. + * @param string $path The path to the action. * @return string|array The keys */ - public static function Action(string $path) { + public static function Action(string $path) + { $path = explode('/', $path); $config = self::$_actions; @@ -207,12 +209,13 @@ public static function Action(string $path) { /** * Logs an action. * - * @param string $action The action being logged - * @param string $info Some more information about what the action is about - * @param ?int $user The User ID who is doing the action - * @return bool Return true or false if inserted into the database. + * @param string $action The action being logged + * @param string $info Some more information about what the action is about + * @param ?int $user The User ID who is doing the action + * @return bool Return true or false if inserted into the database. */ - public function log(string $action, string $info = '', ?int $user = null): bool { + public function log(string $action, string $info = '', ?int $user = null): bool + { if ($user === null) { $userTemp = new User(); $user = ($userTemp->isLoggedIn() ? $userTemp->data()->id : 0); diff --git a/core/classes/Core/Module.php b/core/classes/Core/Module.php index 59d7b2d7ad..e53da64187 100644 --- a/core/classes/Core/Module.php +++ b/core/classes/Core/Module.php @@ -7,8 +7,8 @@ * @version 2.0.0-pr13 * @license MIT */ -abstract class Module { - +abstract class Module +{ /** * @var Module[] Array of all modules */ @@ -48,22 +48,24 @@ public function __construct( /** * Call `onPageLoad()` function for all registered modules. * - * @param User $user User viewing the page. - * @param Pages $pages Instance of pages class. - * @param Cache $cache Instance of cache to pass. - * @param Smarty $smarty Instance of smarty to pass. - * @param Navigation[] $navs Array of loaded navigation menus. - * @param Widgets $widgets Instance of widget class to pass. + * @param User $user User viewing the page. + * @param Pages $pages Instance of pages class. + * @param Cache $cache Instance of cache to pass. + * @param Smarty $smarty Instance of smarty to pass. + * @param Navigation[] $navs Array of loaded navigation menus. + * @param Widgets $widgets Instance of widget class to pass. * @param TemplateBase $template Template to pass. */ - public static function loadPage(User $user, Pages $pages, Cache $cache, Smarty $smarty, iterable $navs, Widgets $widgets, TemplateBase $template): void { + public static function loadPage(User $user, Pages $pages, Cache $cache, Smarty $smarty, iterable $navs, Widgets $widgets, TemplateBase $template): void + { foreach (self::getModules() as $module) { $module->onPageLoad($user, $pages, $cache, $smarty, $navs, $widgets, $template); } } /** @return Module[] */ - public static function getModules(): iterable { + public static function getModules(): iterable + { return self::$_modules; } @@ -71,12 +73,12 @@ public static function getModules(): iterable { * Handle page loading for this module. * Often used to register permissions, sitemaps, widgets, etc. * - * @param User $user User viewing the page. - * @param Pages $pages Instance of pages class. - * @param Cache $cache Instance of cache to pass. - * @param Smarty $smarty Instance of smarty to pass. - * @param Navigation[] $navs Array of loaded navigation menus. - * @param Widgets $widgets Instance of widget class to pass. + * @param User $user User viewing the page. + * @param Pages $pages Instance of pages class. + * @param Cache $cache Instance of cache to pass. + * @param Smarty $smarty Instance of smarty to pass. + * @param Navigation[] $navs Array of loaded navigation menus. + * @param Widgets $widgets Instance of widget class to pass. * @param TemplateBase|null $template Active template to render. */ abstract public function onPageLoad(User $user, Pages $pages, Cache $cache, Smarty $smarty, iterable $navs, Widgets $widgets, ?TemplateBase $template); @@ -86,7 +88,8 @@ abstract public function onPageLoad(User $user, Pages $pages, Cache $cache, Smar * * @return array Array with module order and any failed modules. */ - public static function determineModuleOrder(): array { + public static function determineModuleOrder(): array + { $module_order = ['Core']; $failed = []; @@ -110,7 +113,8 @@ public static function determineModuleOrder(): array { return ['modules' => $module_order, 'failed' => $failed]; } - public function getName(): string { + public function getName(): string + { return $this->_name; } @@ -119,7 +123,8 @@ public function getName(): string { * * @return array Array of module names that this module should load after. */ - public function getLoadAfter(): array { + public function getLoadAfter(): array + { return $this->_load_after; } @@ -128,7 +133,8 @@ public function getLoadAfter(): array { * * @return array Array of module names that this module should load before. */ - public function getLoadBefore(): array { + public function getLoadBefore(): array + { return $this->_load_before; } @@ -152,7 +158,8 @@ abstract public function getDebugInfo(): array; * * @return string The author of this module. */ - public function getAuthor(): string { + public function getAuthor(): string + { return $this->_author; } @@ -161,7 +168,8 @@ public function getAuthor(): string { * * @return string The version of this module. */ - public function getVersion(): string { + public function getVersion(): string + { return $this->_version; } @@ -170,28 +178,30 @@ public function getVersion(): string { * * @return string The supported NamelessMC version of this module. */ - public function getNamelessVersion(): string { + public function getNamelessVersion(): string + { return $this->_nameless_version; } /** - * Get this module's ID + * Get this module's ID. * * @return int The ID for the module */ - public function getId(): int { + public function getId(): int + { return DB::getInstance()->query('SELECT `id` FROM nl2_modules WHERE `name` = ?', [$this->_name])->first()->id; } /** - * Get a module ID from name + * Get a module ID from name. * * @param string $name Module name * * @return ?int Module ID - * */ - public static function getIdFromName(string $name): ?int { + public static function getIdFromName(string $name): ?int + { $query = DB::getInstance()->get('modules', ['name', $name]); if ($query->count()) { @@ -202,13 +212,14 @@ public static function getIdFromName(string $name): ?int { } /** - * Get a module name from ID + * Get a module name from ID. * * @param int $id Module ID * * @return ?string Module name */ - public static function getNameFromId(int $id): ?string { + public static function getNameFromId(int $id): ?string + { $query = DB::getInstance()->get('modules', ['id', $id]); if ($query->count()) { diff --git a/core/classes/Core/Navigation.php b/core/classes/Core/Navigation.php index a9f1d10594..185ea56b0e 100644 --- a/core/classes/Core/Navigation.php +++ b/core/classes/Core/Navigation.php @@ -7,8 +7,8 @@ * @version 2.0.0 * @license MIT */ -class Navigation { - +class Navigation +{ /** * @var array Top navigation items. */ @@ -24,20 +24,21 @@ class Navigation { */ private bool $_panel; - public function __construct(bool $panel = false) { + public function __construct(bool $panel = false) + { $this->_panel = $panel; } /** * Add a simple item to this navigation instance. * - * @param string $name Unique name for the navbar item, if the page name equals this the item will display as active. - * @param string $title Item title. - * @param string $link HTML href attribute, can be link built with URL class or hyperlink. - * @param string $location Location to add item to, either 'top' or 'footer' (defaults to 'top'). - * @param string|null $target HTML target attribute (eg '_blank'). - * @param float $order Nav item order (default 10). - * @param string|null $icon Icon to prepend to nav item. + * @param string $name Unique name for the navbar item, if the page name equals this the item will display as active. + * @param string $title Item title. + * @param string $link HTML href attribute, can be link built with URL class or hyperlink. + * @param string $location Location to add item to, either 'top' or 'footer' (defaults to 'top'). + * @param string|null $target HTML target attribute (eg '_blank'). + * @param float $order Nav item order (default 10). + * @param string|null $icon Icon to prepend to nav item. */ public function add( string $name, @@ -69,7 +70,7 @@ public function add( 'link' => $link, 'target' => $target, 'order' => $order, - 'icon' => $icon + 'icon' => $icon, ]; } else { // Add to footer navigation @@ -78,7 +79,7 @@ public function add( 'link' => $link, 'target' => $target, 'order' => $order, - 'icon' => $icon + 'icon' => $icon, ]; } } @@ -86,13 +87,14 @@ public function add( /** * Add a dropdown menu to the navigation. * - * @param string $name Unique name for the dropdown - * @param string $title Dropdown title + * @param string $name Unique name for the dropdown + * @param string $title Dropdown title * @param string $location Location to add item to, either 'top' or 'footer' (defaults to 'top'). - * @param int $order Nav item order (default 10). - * @param string $icon Icon to prepend to nav item. + * @param int $order Nav item order (default 10). + * @param string $icon Icon to prepend to nav item. */ - public function addDropdown(string $name, string $title, string $location = 'top', int $order = 10, string $icon = ''): void { + public function addDropdown(string $name, string $title, string $location = 'top', int $order = 10, string $icon = ''): void + { if ($this->_panel && $location == 'top') { // Discard order // TODO: only a temporary solution to the link conflict issue in the StaffCP @@ -113,7 +115,7 @@ public function addDropdown(string $name, string $title, string $location = 'top 'title' => $title, 'items' => [], 'order' => $order, - 'icon' => $icon + 'icon' => $icon, ]; } else { // Footer @@ -121,7 +123,7 @@ public function addDropdown(string $name, string $title, string $location = 'top 'title' => $title, 'items' => [], 'order' => $order, - 'icon' => $icon + 'icon' => $icon, ]; } } @@ -129,16 +131,17 @@ public function addDropdown(string $name, string $title, string $location = 'top /** * Add an item to a menu dropdown. * - * @param string $dropdown Name of dropdown to add item to. - * @param string $name Unique name for the item, if the page name equals this the item will display as active. - * @param string $title Item title. - * @param string $link HTML href attribute, can be link built with URL class or hyperlink. - * @param string $location Location to add item to, either 'top' or 'footer' (defaults to 'top'). - * @param string|null $target HTML target attribute (eg '_blank') - * @param string $icon Icon to prepend to nav item - * @param int $order Nav item order + * @param string $dropdown Name of dropdown to add item to. + * @param string $name Unique name for the item, if the page name equals this the item will display as active. + * @param string $title Item title. + * @param string $link HTML href attribute, can be link built with URL class or hyperlink. + * @param string $location Location to add item to, either 'top' or 'footer' (defaults to 'top'). + * @param string|null $target HTML target attribute (eg '_blank') + * @param string $icon Icon to prepend to nav item + * @param int $order Nav item order */ - public function addItemToDropdown(string $dropdown, string $name, string $title, string $link, string $location = 'top', string $target = null, string $icon = '', int $order = 10): void { + public function addItemToDropdown(string $dropdown, string $name, string $title, string $link, string $location = 'top', string $target = null, string $icon = '', int $order = 10): void + { // Add the item if ($location == 'top' && isset($this->_topNavbar[$dropdown])) { // Navbar @@ -149,7 +152,7 @@ public function addItemToDropdown(string $dropdown, string $name, string $title, 'icon' => $icon, 'order' => $order, ]; - } else if (isset($this->_footerNav[$dropdown])) { + } elseif (isset($this->_footerNav[$dropdown])) { // Footer $this->_footerNav[$dropdown]['items'][$name] = [ 'title' => $title, @@ -164,10 +167,11 @@ public function addItemToDropdown(string $dropdown, string $name, string $title, /** * Return top navigation. * - * @param string $location Either 'top' or 'footer' (defaults to 'top'). - * @return array Array to pass to template + * @param string $location Either 'top' or 'footer' (defaults to 'top'). + * @return array Array to pass to template */ - public function returnNav(string $location = 'top'): array { + public function returnNav(string $location = 'top'): array + { $return = []; // String to return if ($location == 'top') { if (count($this->_topNavbar)) { @@ -190,6 +194,7 @@ static function ($a, $b) { if ($a['order'] < $b['order']) { return -1; } + return 0; } ); @@ -199,7 +204,7 @@ static function ($a, $b) { } } } - } else if (count($this->_footerNav)) { + } elseif (count($this->_footerNav)) { foreach ($this->_footerNav as $key => $item) { $return[$key] = $item; if (defined('PAGE') && PAGE == $key) { @@ -218,6 +223,7 @@ static function ($a, $b) { if ($a['order'] < $b['order']) { return -1; } + return 0; } ); @@ -229,9 +235,10 @@ static function ($a, $b) { $result = 0; if ($a['order'] > $b['order']) { $result = 1; - } else if ($a['order'] < $b['order']) { + } elseif ($a['order'] < $b['order']) { $result = -1; } + return $result; }); diff --git a/core/classes/Core/Output.php b/core/classes/Core/Output.php index 5d04db595f..dfe189812b 100644 --- a/core/classes/Core/Output.php +++ b/core/classes/Core/Output.php @@ -7,8 +7,8 @@ * @version 2.0.0-pr8 * @license MIT */ -class Output { - +class Output +{ /** * @var HTMLPurifier Static purifier instance. */ @@ -18,20 +18,22 @@ class Output { * Returns a clean version of an inputted string. * Will remove HTML, convert HTML entities, and strip slashes. * - * @param ?string $input The string which will be cleaned + * @param ?string $input The string which will be cleaned * @return ?string Cleaned version of string. */ - public static function getClean(?string $input): ?string { + public static function getClean(?string $input): ?string + { return $input === null ? null : htmlspecialchars($input, ENT_QUOTES); } /** * Returns a decoded version of a clean string. * - * @param ?string $input Contains the clean string which will be decoded. + * @param ?string $input Contains the clean string which will be decoded. * @return ?string Decoded string. */ - public static function getDecoded(?string $input): ?string { + public static function getDecoded(?string $input): ?string + { return $input === null ? null : htmlspecialchars_decode($input, ENT_QUOTES); } @@ -39,14 +41,14 @@ public static function getDecoded(?string $input): ?string { * Returns a purified version of an inputted string with HTMLPurifier. * Will not remove any HTML tags. * - * @param string|null $input String which will be purified. - * @param bool $escape_invalid Should invalid HTML be escaped instead of fully removed? + * @param string|null $input String which will be purified. + * @param bool $escape_invalid Should invalid HTML be escaped instead of fully removed? * * @return string Purified string. */ - public static function getPurified(?string $input, bool $escape_invalid = false): string { + public static function getPurified(?string $input, bool $escape_invalid = false): string + { if (!isset(self::$_purifier)) { - $purifierConfig = HTMLPurifier_Config::createDefault(); // Config settings @@ -81,13 +83,13 @@ public static function getPurified(?string $input, bool $escape_invalid = false) } /** - * urlencode() a string without encoding slashes + * urlencode() a string without encoding slashes. * - * @param string $input String to encode + * @param string $input String to encode * @return string Encoded string */ - public static function urlEncodeAllowSlashes(string $input): string { + public static function urlEncodeAllowSlashes(string $input): string + { return str_replace('%2F', '/', urlencode($input)); } - } diff --git a/core/classes/Core/Pages.php b/core/classes/Core/Pages.php index 556c930b9b..c0a14ba53e 100644 --- a/core/classes/Core/Pages.php +++ b/core/classes/Core/Pages.php @@ -7,8 +7,8 @@ * @version 2.0.0-pr8 * @license MIT */ -class Pages { - +class Pages +{ /** * @var array Array of all the registered pages. */ @@ -37,37 +37,39 @@ class Pages { /** * Defines a page and assigns it to a module. * - * @param string $module Module which the page belongs to. - * @param string $url URL string. - * @param string $file Path (from module folder) to page file. - * @param string $name Name of page. - * @param bool $widgets Can widgets be used on the page? Default false. - */ - public function add(string $module, string $url, string $file, string $name = '', bool $widgets = false): void { + * @param string $module Module which the page belongs to. + * @param string $url URL string. + * @param string $file Path (from module folder) to page file. + * @param string $name Name of page. + * @param bool $widgets Can widgets be used on the page? Default false. + */ + public function add(string $module, string $url, string $file, string $name = '', bool $widgets = false): void + { $this->_pages[$url] = [ 'module' => $module, 'file' => $file, 'name' => $name, 'widgets' => $widgets, - 'id' => $this->_id++ + 'id' => $this->_id++, ]; } /** * Defines a custom page. * - * @param string $url URL string. - * @param string $name Name of page. - * @param bool $widgets Can widgets be used on the page? Default false. + * @param string $url URL string. + * @param string $name Name of page. + * @param bool $widgets Can widgets be used on the page? Default false. */ - public function addCustom(string $url, string $name, bool $widgets = false): void { + public function addCustom(string $url, string $name, bool $widgets = false): void + { $this->_pages[$url] = [ 'module' => 'Core', 'file' => 'custom.php', 'name' => $name, 'widgets' => $widgets, 'custom' => true, - 'id' => $this->_id++ + 'id' => $this->_id++, ]; } @@ -76,7 +78,8 @@ public function addCustom(string $url, string $name, bool $widgets = false): voi * * @return array All pages. */ - public function returnPages(): array { + public function returnPages(): array + { return $this->_pages; } @@ -85,7 +88,8 @@ public function returnPages(): array { * * @return array All pages which allow widgets. */ - public function returnWidgetPages(): array { + public function returnWidgetPages(): array + { $ret = []; foreach ($this->_pages as $page) { @@ -103,7 +107,8 @@ public function returnWidgetPages(): array { * * @param callable $method Array callable of the sitemap class and method to execute. */ - public function registerSitemapMethod(callable $method): void { + public function registerSitemapMethod(callable $method): void + { $this->_sm_methods[] = $method; } @@ -112,20 +117,23 @@ public function registerSitemapMethod(callable $method): void { * * @return array Array of sitemap methods. */ - public function getSitemapMethods(): array { + public function getSitemapMethods(): array + { return $this->_sm_methods; } /** - * Get page by ID + * Get page by ID. * - * @param int $page_id ID of page to find. + * @param int $page_id ID of page to find. * @return array Page information. */ - public function getPageById(int $page_id): ?array { + public function getPageById(int $page_id): ?array + { foreach ($this->_pages as $key => $page) { if ($page['id'] == $page_id) { $page['key'] = $key; + return $page; } } @@ -136,13 +144,15 @@ public function getPageById(int $page_id): ?array { /** * Get page by URL. * - * @param string $url URL of page to find. - * @return array Page information. + * @param string $url URL of page to find. + * @return array Page information. */ - public function getPageByURL(string $url): ?array { + public function getPageByURL(string $url): ?array + { foreach ($this->_pages as $key => $page) { if ($key == $url) { $page['key'] = $key; + return $page; } } @@ -155,14 +165,16 @@ public function getPageByURL(string $url): ?array { * * @return array Details of current page. */ - public function getActivePage(): array { + public function getActivePage(): array + { return $this->_active_page; } /** * Set the page the user currently viewing. */ - public function setActivePage(array $page): void { + public function setActivePage(array $page): void + { $this->_active_page = $page; } @@ -171,7 +183,8 @@ public function setActivePage(array $page): void { * * @param string $script URL of js script to add. */ - public function addAjaxScript(string $script): void { + public function addAjaxScript(string $script): void + { $this->_ajax_requests[] = $script; } @@ -180,7 +193,8 @@ public function addAjaxScript(string $script): void { * * @return array All registered ajax script URLs. */ - public function getAjaxScripts(): array { + public function getAjaxScripts(): array + { return $this->_ajax_requests; } } diff --git a/core/classes/Core/Paginator.php b/core/classes/Core/Paginator.php index 78440bd14b..0cf4930798 100644 --- a/core/classes/Core/Paginator.php +++ b/core/classes/Core/Paginator.php @@ -8,8 +8,8 @@ * @version 2.0.0-pr13 * @license MIT */ -class Paginator { - +class Paginator +{ /** * @var int The number of items per page. */ @@ -41,11 +41,12 @@ class Paginator { private string $_rightContent; /** - * @param array|null $class Optional array of class names, if provided the required element keys are ul, li and a - * @param string|null $leftContent Optional string to display in "previous" button, default « + * @param array|null $class Optional array of class names, if provided the required element keys are ul, li and a + * @param string|null $leftContent Optional string to display in "previous" button, default « * @param string|null $rightContent Optional string to display in "next" button, default » */ - public function __construct(?array $class = [], ?string $leftContent = null, ?string $rightContent = null) { + public function __construct(?array $class = [], ?string $leftContent = null, ?string $rightContent = null) + { if (!is_array($class) || !count($class)) { $this->_class = ['ul' => 'pagination d-inline-flex', 'li' => 'page-item {x}', 'a' => 'page-link']; } else { @@ -57,16 +58,17 @@ public function __construct(?array $class = [], ?string $leftContent = null, ?st } /** - * Generate object of provided data + * Generate object of provided data. * - * @param array $data Data to paginate. - * @param int $limit Number of items per page. - * @param int $page Current page. - * @param int $total Total number of items. + * @param array $data Data to paginate. + * @param int $limit Number of items per page. + * @param int $page Current page. + * @param int $total Total number of items. * * @return object */ - public function getLimited(array $data, int $limit = 10, int $page = 1, int $total = 10): object { + public function getLimited(array $data, int $limit = 10, int $page = 1, int $total = 10): object + { $this->_limit = $limit; $this->_page = $page; @@ -94,11 +96,12 @@ public function getLimited(array $data, int $limit = 10, int $page = 1, int $tot /** * Generate HTML for data to be presented with. * - * @param int $links Number of links to be shown on each page. - * @param string $href URL prefix to use when next page is clicked. + * @param int $links Number of links to be shown on each page. + * @param string $href URL prefix to use when next page is clicked. * @return string Generated HTML to display in template. */ - public function generate(int $links, string $href = '?'): string { + public function generate(int $links, string $href = '?'): string + { $href .= '&'; $last = ceil($this->_total / $this->_limit); @@ -113,13 +116,13 @@ public function generate(int $links, string $href = '?'): string { } if (empty($this->_class['ul'])) { - $class = str_replace('{x}', ($this->_page == 1 ? ' disabled ' : ''), ($this->_class['a'])); + $class = str_replace('{x}', $this->_page == 1 ? ' disabled ' : '', $this->_class['a']); $html .= '' . $this->_leftContent . ''; } else { $class = str_replace('{x}', ($this->_page == 1) ? ' disabled' : '', $this->_class['li']); - $html .= '
  • window.location.replace("' . Output::getClean($location) . '");'; } - die(); + die; } /** @@ -31,7 +32,8 @@ public static function to(string $location): void { * * @return never */ - public static function back(): void { + public static function back(): void + { if (isset($_SESSION['last_page'])) { self::to($_SESSION['last_page']); } diff --git a/core/classes/Core/SecureRandom.php b/core/classes/Core/SecureRandom.php index d3c3049ae6..928a4368fd 100644 --- a/core/classes/Core/SecureRandom.php +++ b/core/classes/Core/SecureRandom.php @@ -1,23 +1,23 @@ query('DELETE FROM `nl2_settings` WHERE `name` = ? AND `module` IS NULL', [$setting]); @@ -96,9 +104,8 @@ public static function set(string $setting, ?string $new_value, string $module = if ($new_value !== null) { $cache[$setting] = $new_value; - } else if (isset($cache[$setting])) { + } elseif (isset($cache[$setting])) { unset($cache[$setting]); } } - } diff --git a/core/classes/Core/TimeAgo.php b/core/classes/Core/TimeAgo.php index f7bb438f61..83b9d812b3 100644 --- a/core/classes/Core/TimeAgo.php +++ b/core/classes/Core/TimeAgo.php @@ -13,8 +13,8 @@ * @license MIT * @site http://github.com/jimmiw/php-time-ago */ -class TimeAgo { - +class TimeAgo +{ // defines the number of seconds per "unit" private int $_secondsPerMinute = 60; private int $_secondsPerHour = 3600; @@ -23,16 +23,18 @@ class TimeAgo { private int $_secondsPerYear = 31104000; private string $_timezone; - public function __construct(string $timezone) { + public function __construct(string $timezone) + { $this->_timezone = $timezone; } /** - * @param string|int $past Past time - * @param Language $language - * @return string Time ago string + * @param string|int $past Past time + * @param Language $language + * @return string Time ago string */ - public function inWords($past, Language $language): string { + public function inWords($past, Language $language): string + { // sets the default timezone date_default_timezone_set($this->_timezone); if (!is_numeric($past)) { @@ -46,21 +48,21 @@ public function inWords($past, Language $language): string { // less than 29secs if ($timeDifference <= 29) { $key = 'less_than_a_minute'; - } else if ($timeDifference <= 89) { + } elseif ($timeDifference <= 89) { // more than 29secs and less than 1min29secss $key = '1_minute'; - } else if ($timeDifference <= (($this->_secondsPerMinute * 44) + 29)) { + } elseif ($timeDifference <= (($this->_secondsPerMinute * 44) + 29)) { // between 1min30secs and 44mins29secs $replace = floor($timeDifference / $this->_secondsPerMinute); $key = '_minutes'; - } else if ( + } elseif ( $timeDifference > (($this->_secondsPerMinute * 44) + 29) && $timeDifference < (($this->_secondsPerMinute * 89) + 29) ) { // between 44mins30secs and 1hour29mins29secs $key = 'about_1_hour'; - } else if ( + } elseif ( $timeDifference > ( ($this->_secondsPerMinute * 89) + 29 @@ -80,7 +82,7 @@ public function inWords($past, Language $language): string { } else { $key = '_hours'; } - } else if ( + } elseif ( $timeDifference > ( ($this->_secondsPerHour * 23) + ($this->_secondsPerMinute * 59) + @@ -95,7 +97,7 @@ public function inWords($past, Language $language): string { ) { // between 23hours59mins30secs and 47hours59mins29sec $key = '1_day'; - } else if ( + } elseif ( $timeDifference > ( ($this->_secondsPerHour * 47) + ($this->_secondsPerMinute * 59) + @@ -112,7 +114,7 @@ public function inWords($past, Language $language): string { // between 47hours59mins30secs and 29days23hours59mins29secs $replace = floor($timeDifference / $this->_secondsPerDay); $key = '_days'; - } else if ( + } elseif ( $timeDifference > ( ($this->_secondsPerDay * 29) + ($this->_secondsPerHour * 23) + @@ -129,7 +131,7 @@ public function inWords($past, Language $language): string { ) { // between 29days23hours59mins30secs and 59days23hours59mins29secs $key = 'about_1_month'; - } else if ( + } elseif ( $timeDifference > ( ($this->_secondsPerDay * 59) + ($this->_secondsPerHour * 23) + @@ -147,7 +149,7 @@ public function inWords($past, Language $language): string { } $key = '_months'; - } else if ( + } elseif ( $timeDifference >= $this->_secondsPerYear && $timeDifference < ($this->_secondsPerYear * 2) @@ -182,7 +184,8 @@ public function inWords($past, Language $language): string { return $term; } - public function dateDifference(string $past, string $now = 'now'): array { + public function dateDifference(string $past, string $now = 'now'): array + { // initializes the placeholders for the different "times" $seconds = 0; $minutes = 0; @@ -206,47 +209,47 @@ public function dateDifference(string $past, string $now = 'now'): array { if ($timeDifference >= 0) { switch ($timeDifference) { // finds the number of years - case ($timeDifference >= $this->_secondsPerYear): + case $timeDifference >= $this->_secondsPerYear: // uses floor to remove decimals $years = floor($timeDifference / $this->_secondsPerYear); // saves the amount of seconds left $timeDifference -= ($years * $this->_secondsPerYear); break; - // finds the number of months - case ($timeDifference >= $this->_secondsPerMonth && $timeDifference <= ($this->_secondsPerYear - 1)): + // finds the number of months + case $timeDifference >= $this->_secondsPerMonth && $timeDifference <= ($this->_secondsPerYear - 1): // uses floor to remove decimals $months = floor($timeDifference / $this->_secondsPerMonth); // saves the amount of seconds left $timeDifference -= ($months * $this->_secondsPerMonth); break; - // finds the number of days - case ($timeDifference >= $this->_secondsPerDay && $timeDifference <= ($this->_secondsPerYear - 1)): + // finds the number of days + case $timeDifference >= $this->_secondsPerDay && $timeDifference <= ($this->_secondsPerYear - 1): // uses floor to remove decimals $days = floor($timeDifference / $this->_secondsPerDay); // saves the amount of seconds left $timeDifference -= ($days * $this->_secondsPerDay); break; - // finds the number of hours - case ($timeDifference >= $this->_secondsPerHour && $timeDifference <= ($this->_secondsPerDay - 1)): + // finds the number of hours + case $timeDifference >= $this->_secondsPerHour && $timeDifference <= ($this->_secondsPerDay - 1): // uses floor to remove decimals $hours = floor($timeDifference / $this->_secondsPerHour); // saves the amount of seconds left $timeDifference -= ($hours * $this->_secondsPerHour); break; - // finds the number of minutes - case ($timeDifference >= $this->_secondsPerMinute && $timeDifference <= ($this->_secondsPerHour - 1)): + // finds the number of minutes + case $timeDifference >= $this->_secondsPerMinute && $timeDifference <= ($this->_secondsPerHour - 1): // uses floor to remove decimals $minutes = floor($timeDifference / $this->_secondsPerMinute); // saves the amount of seconds left $timeDifference -= ($minutes * $this->_secondsPerMinute); break; - // finds the number of seconds - case ($timeDifference <= ($this->_secondsPerMinute - 1)): + // finds the number of seconds + case $timeDifference <= ($this->_secondsPerMinute - 1): // seconds is just what there is in the timeDifference variable $seconds = $timeDifference; } @@ -258,7 +261,7 @@ public function dateDifference(string $past, string $now = 'now'): array { 'days' => $days, 'hours' => $hours, 'minutes' => $minutes, - 'seconds' => $seconds + 'seconds' => $seconds, ]; } } diff --git a/core/classes/Core/Token.php b/core/classes/Core/Token.php index d7f1e43049..ba01daadba 100644 --- a/core/classes/Core/Token.php +++ b/core/classes/Core/Token.php @@ -7,14 +7,15 @@ * @version 2.0.0-pr8 * @license MIT */ -class Token { - +class Token +{ /** * Get current form token. * * @return string current form token. */ - public static function get(): string { + public static function get(): string + { $tokenName = Config::get('session.token_name'); // Return if it already exists @@ -29,9 +30,10 @@ public static function get(): string { } /** - * Generate a form token and store in a session variable + * Generate a form token and store in a session variable. */ - public static function generate(): void { + public static function generate(): void + { // Generate random token using md5 Session::put(Config::get('session.token_name'), md5(uniqid('', true))); } @@ -41,10 +43,11 @@ public static function generate(): void { * * @param string|null $token Contains the form token which will be checked against the session variable. * - * @return bool Whether token matches. * @throws Exception + * @return bool Whether token matches. */ - public static function check(string $token = null): bool { + public static function check(string $token = null): bool + { if ($token === null) { $token = Input::get('token'); } diff --git a/core/classes/Core/URL.php b/core/classes/Core/URL.php index b3e51323a2..b6bd817607 100644 --- a/core/classes/Core/URL.php +++ b/core/classes/Core/URL.php @@ -7,8 +7,8 @@ * @version 2.0.0 * @license MIT */ -class URL { - +class URL +{ private const URL_EXCLUDE_CHARS = [ '?', '&', @@ -20,12 +20,13 @@ class URL { /** * Returns a URL in the correct format (friendly or not). * - * @param string $url Contains the URL which will be formatted. - * @param string $params Contains string with URL parameters. - * @param ?string $force Determines whether to force a URL type (optional, can be either "friendly" or "non-friendly"). - * @return string Assembled URL, false on failure. + * @param string $url Contains the URL which will be formatted. + * @param string $params Contains string with URL parameters. + * @param ?string $force Determines whether to force a URL type (optional, can be either "friendly" or "non-friendly"). + * @return string Assembled URL, false on failure. */ - public static function build(string $url, string $params = '', ?string $force = null): string { + public static function build(string $url, string $params = '', ?string $force = null): string + { if ($force === 'friendly') { return self::buildFriendly($url, $params); } @@ -56,11 +57,12 @@ public static function build(string $url, string $params = '', ?string $force = * Returns a friendly URL. * Internal class use only. All external calls should use `build()`. * - * @param string $url Contains the URL which will be formatted - * @param string $params URL paramaters to append to end. + * @param string $url Contains the URL which will be formatted + * @param string $params URL paramaters to append to end. * @return string Assembled URL. */ - private static function buildFriendly(string $url, string $params): string { + private static function buildFriendly(string $url, string $params): string + { // Check for params if ($params != '') { $params = '?' . $params; @@ -73,11 +75,12 @@ private static function buildFriendly(string $url, string $params): string { * Returns a non-friendly URL. * Internal class use only. All external calls should use `build()`. * - * @param string $url Contains the URL which will be formatted - * @param string $params URL paramaters to append to end. + * @param string $url Contains the URL which will be formatted + * @param string $params URL paramaters to append to end. * @return string Assembled URL. */ - private static function buildNonFriendly(string $url, string $params): string { + private static function buildNonFriendly(string $url, string $params): string + { if ($params != '') { return (defined('CONFIG_PATH') ? CONFIG_PATH : '') . '/index.php?route=' . $url . ((substr($url, -1) == '/') ? '' : '/') . '&' . $params; } @@ -86,22 +89,24 @@ private static function buildNonFriendly(string $url, string $params): string { } /** - * Build an asset path + * Build an asset path. * - * @param string $path Contains the asset path relative to the root Nameless directory + * @param string $path Contains the asset path relative to the root Nameless directory * @return string */ - public static function buildAssetPath(string $path): string { + public static function buildAssetPath(string $path): string + { return (defined('CONFIG_PATH') ? CONFIG_PATH : '') . '/' . ltrim($path, '/'); } /** * Get the server name. * - * @param bool $show_protocol Whether to show http(s) at front or not. + * @param bool $show_protocol Whether to show http(s) at front or not. * @return string Compiled URL. */ - public static function getSelfURL(bool $show_protocol = true): string { + public static function getSelfURL(bool $show_protocol = true): string + { $hostname = Config::get('core.hostname'); if (!$hostname) { @@ -138,7 +143,8 @@ public static function getSelfURL(bool $show_protocol = true): string { * * @return bool Whether URL is external or not. */ - public static function isExternalURL(string $url): bool { + public static function isExternalURL(string $url): bool + { if ($url[0] == '/' && $url[1] != '/') { return false; } @@ -150,12 +156,13 @@ public static function isExternalURL(string $url): bool { /** * Add target and rel attributes to external links only. - * From https://stackoverflow.com/a/53461987 + * From https://stackoverflow.com/a/53461987. * - * @param string $data Data to replace. + * @param string $data Data to replace. * @return string Replaced string. */ - public static function replaceAnchorsWithText(string $data): string { + public static function replaceAnchorsWithText(string $data): string + { return preg_replace_callback('/]*href=["|\']([^"|\']*)["|\'][^>]*>([^<]*)<\/a>/i', static function ($m): string { if (!str_contains($m[1], self::getSelfURL())) { return 'href="' . $m[1] . '" rel="nofollow noopener" target="_blank">' . $m[2] . ''; @@ -169,13 +176,15 @@ public static function replaceAnchorsWithText(string $data): string { * Urlencode, but prettier. * - Spaces are replaced by dashes * - Cyrillic characters are converted to latin - * - Some special characters are removed (see URL::URL_EXCLUDE_CHARS) + * - Some special characters are removed (see URL::URL_EXCLUDE_CHARS). * - * @param string $text String to URLify + * @param string $text String to URLify * @return string Encoded string */ - public static function urlSafe(string $text): string { + public static function urlSafe(string $text): string + { $text = str_replace(self::URL_EXCLUDE_CHARS, '', Util::cyrillicToLatin($text)); + return urlencode(strtolower(str_replace(' ', '-', $text))); } } diff --git a/core/classes/Core/User.php b/core/classes/Core/User.php index 02b10a4e1d..3dd130f8ea 100644 --- a/core/classes/Core/User.php +++ b/core/classes/Core/User.php @@ -9,8 +9,8 @@ * @version 2.1.2 * @license MIT */ -class User { - +class User +{ private static array $_user_cache = []; private static array $_group_cache = []; private static array $_integration_cache = []; @@ -67,7 +67,8 @@ class User { */ private bool $_isAdmLoggedIn = false; - public function __construct(string $user = null, string $field = 'id') { + public function __construct(string $user = null, string $field = 'id') + { $this->_db = DB::getInstance(); $this->_sessionName = Config::get('session.session_name'); $this->_cookieName = Config::get('remember.cookie_name'); @@ -100,9 +101,11 @@ public function __construct(string $user = null, string $field = 'id') { * * @return bool True/false on success or failure respectfully. */ - private function find(string $value, string $field = 'id'): bool { + private function find(string $value, string $field = 'id'): bool + { if (isset(self::$_user_cache["$value.$field"])) { $this->_data = self::$_user_cache["$value.$field"]; + return true; } @@ -115,6 +118,7 @@ private function find(string $value, string $field = 'id'): bool { if ($data->count()) { $this->_data = new UserData($data->first()); self::$_user_cache["$value.$field"] = $this->_data; + return true; } @@ -125,11 +129,12 @@ private function find(string $value, string $field = 'id'): bool { * Add a group to this user. * * @param int $group_id ID of group to give. - * @param int $expire Expiry in epoch time. If not supplied, group will never expire. + * @param int $expire Expiry in epoch time. If not supplied, group will never expire. * * @return bool True on success, false if they already have it. */ - public function addGroup(int $group_id, int $expire = 0): bool { + public function addGroup(int $group_id, int $expire = 0): bool + { if (array_key_exists($group_id, $this->getGroups())) { return false; } @@ -137,6 +142,7 @@ public function addGroup(int $group_id, int $expire = 0): bool { $group = Group::find($group_id); if (!$group) { ErrorHandler::logWarning('Could not add invalid group ' . $group_id . ' to user ' . $this->data()->id); + return false; } @@ -144,7 +150,7 @@ public function addGroup(int $group_id, int $expire = 0): bool { $this->data()->id, $group_id, date('U'), - $expire + $expire, ]); $this->_groups[$group_id] = $group; @@ -163,16 +169,18 @@ public function addGroup(int $group_id, int $expire = 0): bool { * * @return UserData This user's data. */ - public function data(): ?UserData { + public function data(): ?UserData + { return $this->_data ?? null; } /** - * Get this user's main group CSS styling + * Get this user's main group CSS styling. * * @return string The CSS styling. */ - public function getGroupStyle(): string { + public function getGroupStyle(): string + { $group = $this->getMainGroup(); $group_username_color = Output::getClean($group->group_username_color); @@ -192,10 +200,11 @@ public function getGroupStyle(): string { /** * Update a user's data in the database. * - * @param array $fields Column names and values to update. + * @param array $fields Column names and values to update. * @throws Exception */ - public function update(array $fields = []): void { + public function update(array $fields = []): void + { if (!$this->_db->update('users', $this->data()->id, $fields)) { throw new RuntimeException('There was a problem updating your details.'); } @@ -206,7 +215,8 @@ public function update(array $fields = []): void { * * @param array $fields Column names and values to insert to database. */ - public function create(array $fields = []): void { + public function create(array $fields = []): void + { if (!$this->_db->insert('users', $fields)) { throw new RuntimeException('There was a problem creating an account.'); } @@ -219,7 +229,8 @@ public function create(array $fields = []): void { * * @return ?string Their username, null on failure. */ - public function idToName(int $id): ?string { + public function idToName(int $id): ?string + { $data = $this->_db->get('users', ['id', $id]); if ($data->count()) { @@ -236,7 +247,8 @@ public function idToName(int $id): ?string { * * @return ?string Their nickname, null on failure. */ - public function idToNickname(int $id): ?string { + public function idToNickname(int $id): ?string + { $data = $this->_db->get('users', ['id', $id]); if ($data->count()) { @@ -251,16 +263,18 @@ public function idToNickname(int $id): ?string { * * @param string|null $username Their username (or email, depending on $method). * @param string|null $password Their password. - * @param bool $remember Whether to keep them logged in or not. - * @param string $method What column to check for their details in. Can be either `username` or `email` or `oauth`. + * @param bool $remember Whether to keep them logged in or not. + * @param string $method What column to check for their details in. Can be either `username` or `email` or `oauth`. * * @return bool True/false on success or failure respectfully. */ - public function login(?string $username = null, ?string $password = null, bool $remember = false, string $method = 'email'): bool { + public function login(?string $username = null, ?string $password = null, bool $remember = false, string $method = 'email'): bool + { return $this->_commonLogin($username, $password, $remember, $method, false); } - private function _commonLogin(?string $username, ?string $password, bool $remember, string $method, bool $is_admin): bool { + private function _commonLogin(?string $username, ?string $password, bool $remember, string $method, bool $is_admin): bool + { $sessionName = $is_admin ? $this->_admSessionName : $this->_sessionName; if (!$username && $method == 'hash' && $this->exists()) { // Logged in using hash from cookie @@ -268,7 +282,7 @@ private function _commonLogin(?string $username, ?string $password, bool $rememb if (!$is_admin) { $this->_isLoggedIn = true; } - } else if ($this->checkCredentials($username, $password, $method) === true) { + } elseif ($this->checkCredentials($username, $password, $method) === true) { // Valid credentials $hash = SecureRandom::alphanumeric(); @@ -277,7 +291,7 @@ private function _commonLogin(?string $username, ?string $password, bool $rememb 'hash' => $hash, 'remember_me' => $remember, 'active' => 1, - 'login_method' => $is_admin ? 'admin' : $method + 'login_method' => $is_admin ? 'admin' : $method, ]); Session::put($sessionName, $hash); @@ -299,7 +313,8 @@ private function _commonLogin(?string $username, ?string $password, bool $rememb * * @return bool Whether the user exists (has data) or not. */ - public function exists(): bool { + public function exists(): bool + { return !empty($this->_data); } @@ -308,11 +323,12 @@ public function exists(): bool { * * @param string $username Username (or email) to check. * @param string $password Password entered by user. - * @param string $method Column to search for user with. Can be `email` or `username` or `oauth`. If it is `oauth`, then the request will be granted. + * @param string $method Column to search for user with. Can be `email` or `username` or `oauth`. If it is `oauth`, then the request will be granted. * * @return bool True if correct, false otherwise. */ - public function checkCredentials(string $username, string $password, string $method = 'email'): bool { + public function checkCredentials(string $username, string $password, string $method = 'email'): bool + { $user = $this->find($username, $method === 'oauth' ? 'id' : $method); if ($method === 'oauth') { @@ -323,11 +339,13 @@ public function checkCredentials(string $username, string $password, string $met switch ($this->data()->pass_method) { case 'sha256': [$salt, $pass] = explode('$', $this->data()->password); + return $salt . hash('sha256', hash('sha256', $password) . $salt) == $salt . $pass; case 'pbkdf2': [$iterations, $salt, $pass] = explode('$', $this->data()->password); $hashed = hash_pbkdf2('sha256', $password, $salt, $iterations, 64, true); + return $hashed == hex2bin($pass); case 'modernbb': @@ -348,21 +366,23 @@ public function checkCredentials(string $username, string $password, string $met * * @param string|null $username Their username (or email, depending on $method). * @param string|null $password Their password. - * @param string $method What column to check for their details in. Can be either `username` or `email`. + * @param string $method What column to check for their details in. Can be either `username` or `email`. * * @return bool True/false on success or failure respectfully. */ - public function adminLogin(?string $username = null, ?string $password = null, string $method = 'email'): bool { + public function adminLogin(?string $username = null, ?string $password = null, string $method = 'email'): bool + { return $this->_commonLogin($username, $password, true, $method, true); } /** * Get user's display name. * - * @param bool $username If true, will use their username. If false, will use their nickname. + * @param bool $username If true, will use their username. If false, will use their nickname. * @return string Their display name. */ - public function getDisplayname(bool $username = false): string { + public function getDisplayname(bool $username = false): string + { if ($username) { return Output::getClean($this->data()->username); } @@ -375,7 +395,8 @@ public function getDisplayname(bool $username = false): string { * * @return string Compiled profile URL. */ - public function getProfileURL(): string { + public function getProfileURL(): string + { return URL::build('/profile/' . urlencode($this->data()->username)); } @@ -384,7 +405,8 @@ public function getProfileURL(): string { * * @return array Array of all their group IDs. */ - public function getAllGroupIds(): array { + public function getAllGroupIds(): array + { if (!$this->exists()) { return [0 => 0]; } @@ -402,7 +424,8 @@ public function getAllGroupIds(): array { * * @return bool Whether they're logged in. */ - public function isLoggedIn(): bool { + public function isLoggedIn(): bool + { return $this->_isLoggedIn; } @@ -411,7 +434,8 @@ public function isLoggedIn(): bool { * * @return array Array of all their groups HTML. */ - public function getAllGroupHtml(): array { + public function getAllGroupHtml(): array + { $groups = []; foreach ($this->getGroups() as $group) { @@ -426,19 +450,21 @@ public function getAllGroupHtml(): array { * * @return string Their signature. */ - public function getSignature(): string { + public function getSignature(): string + { return $this->data()->signature ?? ''; } /** * Get this user's avatar. * - * @param int $size Size of image to render in pixels. + * @param int $size Size of image to render in pixels. * @param bool $full Whether to use full site URL or not, for external loading - ie discord webhooks. * * @return string URL to their avatar image. */ - public function getAvatar(int $size = 128, bool $full = false): string { + public function getAvatar(int $size = 128, bool $full = false): string + { $data_obj = new stdClass(); // Convert UserData object to stdClass so we can dynamically add the 'uuid' property foreach (get_object_vars($this->data()) as $key => $value) { @@ -462,7 +488,8 @@ public function getAvatar(int $size = 128, bool $full = false): string { * * @return bool Whether they inherit this permission or not. */ - public function hasPermission(string $permission): bool { + public function hasPermission(string $permission): bool + { if (!$this->exists()) { return false; } @@ -485,10 +512,11 @@ public function hasPermission(string $permission): bool { /** * Log the user out from all other sessions. */ - public function logoutAllOtherSessions(): void { + public function logoutAllOtherSessions(): void + { DB::getInstance()->query('UPDATE nl2_users_session SET `active` = 0 WHERE user_id = ? AND hash != ?', [ $this->data()->id, - Session::get(Config::get('session.session_name')) + Session::get(Config::get('session.session_name')), ]); } @@ -496,9 +524,10 @@ public function logoutAllOtherSessions(): void { * Log the user out. * Deletes their cookies, sessions and database session entry. */ - public function logout(): void { + public function logout(): void + { $this->_db->update('users_session', [['user_id', $this->data()->id], ['hash', Session::get($this->_sessionName)]], [ - 'active' => 0 + 'active' => 0, ]); Session::delete($this->_sessionName); @@ -506,11 +535,12 @@ public function logout(): void { } /** - * Process logout if user is admin + * Process logout if user is admin. */ - public function admLogout(): void { + public function admLogout(): void + { $this->_db->update('users_session', [['user_id', $this->data()->id], ['hash', Session::get($this->_admSessionName)]], [ - 'active' => 0 + 'active' => 0, ]); Session::delete($this->_admSessionName); @@ -522,7 +552,8 @@ public function admLogout(): void { * * @return array Their groups. */ - public function getGroups(): array { + public function getGroups(): array + { if (isset($this->_groups)) { return $this->_groups; } @@ -559,7 +590,8 @@ public function getGroups(): array { * * @return IntegrationUser[] Their integrations. */ - public function getIntegrations(): array { + public function getIntegrations(): array + { if (isset($this->_integrations)) { return $this->_integrations; } @@ -598,7 +630,8 @@ public function getIntegrations(): array { * * @return IntegrationUser|null Their integration user if connected otherwise null. */ - public function getIntegration(string $integrationName): ?IntegrationUser { + public function getIntegration(string $integrationName): ?IntegrationUser + { return $this->getIntegrations()[$integrationName] ?? null; } @@ -607,7 +640,8 @@ public function getIntegration(string $integrationName): ?IntegrationUser { * * @return array Their placeholders. */ - public function getPlaceholders(): array { + public function getPlaceholders(): array + { if (isset($this->_placeholders)) { return $this->_placeholders; } @@ -625,7 +659,8 @@ public function getPlaceholders(): array { * * @return array Forum placeholders. */ - public function getForumPlaceholders(): array { + public function getForumPlaceholders(): array + { return array_filter($this->getPlaceholders(), static function ($placeholder) { return $placeholder->show_on_forum; }); @@ -636,7 +671,8 @@ public function getForumPlaceholders(): array { * * @return array Profile placeholders. */ - public function getProfilePlaceholders(): array { + public function getProfilePlaceholders(): array + { return array_filter($this->getPlaceholders(), static function ($placeholder) { return $placeholder->show_on_profile; }); @@ -647,23 +683,26 @@ public function getProfilePlaceholders(): array { * * @return Group The group */ - public function getMainGroup(): Group { + public function getMainGroup(): Group + { return $this->_main_group ??= array_reduce($this->getGroups(), static function (?Group $carry, Group $group) { return $carry === null || $carry->order > $group->order ? $group : $carry; }); } /** - * Set a group to user and remove all other groups + * Set a group to user and remove all other groups. * - * @param int $group_id ID of group to set as main group. - * @param int $expire Expiry in epoch time. If not supplied, group will never expire. + * @param int $group_id ID of group to set as main group. + * @param int $expire Expiry in epoch time. If not supplied, group will never expire. * @return false|void */ - public function setGroup(int $group_id, int $expire = 0) { + public function setGroup(int $group_id, int $expire = 0) + { $group = Group::find($group_id); if (!$group) { ErrorHandler::logWarning('Could not set invalid group ' . $group_id . ' to user ' . $this->data()->id); + return false; } @@ -677,13 +716,12 @@ public function setGroup(int $group_id, int $expire = 0) { $this->data()->id, $group_id, date('U'), - $expire + $expire, ]); $this->_groups = []; $this->_groups[$group_id] = $group; self::$_group_cache[$this->data()->id] = $this->_groups; - } /** @@ -693,7 +731,8 @@ public function setGroup(int $group_id, int $expire = 0) { * * @return bool Returns false if they did not have this group or the admin group is being removed from root user */ - public function removeGroup(?int $group_id): bool { + public function removeGroup(?int $group_id): bool + { if (!array_key_exists($group_id, $this->getGroups())) { return false; } @@ -704,7 +743,7 @@ public function removeGroup(?int $group_id): bool { $this->_db->query('DELETE FROM `nl2_users_groups` WHERE `user_id` = ? AND `group_id` = ?', [ $this->data()->id, - $group_id + $group_id, ]); EventHandler::executeEvent(new UserGroupRemovedEvent( @@ -723,7 +762,8 @@ public function removeGroup(?int $group_id): bool { * * @return bool Whether this user has been validated/activated. */ - public function isValidated(): bool { + public function isValidated(): bool + { return $this->data()->active; } @@ -733,8 +773,9 @@ public function isValidated(): bool { * * @return array Array of usernames. */ - public function listAllOtherUsers(): array { - $data = $this->_db->query("SELECT `username` FROM `nl2_users` WHERE `id` <> ?", [$this->data()->id])->results(); + public function listAllOtherUsers(): array + { + $data = $this->_db->query('SELECT `username` FROM `nl2_users` WHERE `id` <> ?', [$this->data()->id])->results(); $return = []; foreach ($data as $item) { @@ -751,7 +792,8 @@ public function listAllOtherUsers(): array { * * @return ?int ID on success, null on failure. */ - public function nameToId(string $username): ?int { + public function nameToId(string $username): ?int + { $data = $this->_db->get('users', ['username', $username]); if ($data->count()) { @@ -764,10 +806,11 @@ public function nameToId(string $username): ?int { /** * Return an ID from an email. * - * @param string $email Email to get ID for. - * @return ?int ID on success, false on failure. + * @param string $email Email to get ID for. + * @return ?int ID on success, false on failure. */ - public function emailToId(string $email): ?int { + public function emailToId(string $email): ?int + { $data = $this->_db->get('users', ['email', $email]); if ($data->count()) { @@ -780,10 +823,11 @@ public function emailToId(string $email): ?int { /** * Get a list of PMs a user has access to. * - * @param int $user_id ID of user to get PMs for. + * @param int $user_id ID of user to get PMs for. * @return array Array of PMs. */ - public function listPMs(int $user_id): array { + public function listPMs(int $user_id): array + { $return = []; // Array to return containing info of PMs // Get a list of PMs which the user is in @@ -820,13 +864,14 @@ public function listPMs(int $user_id): array { } /** - * Get a specific private message, and see if the user actually has permission to view it + * Get a specific private message, and see if the user actually has permission to view it. * - * @param int $pm_id ID of PM to find. - * @param int $user_id ID of user to check permission for. + * @param int $pm_id ID of PM to find. + * @param int $user_id ID of user to check permission for. * @return array|null Array of info about PM, null on failure. */ - public function getPM(int $pm_id, int $user_id): ?array { + public function getPM(int $pm_id, int $user_id): ?array + { // Get the PM - is the user the author? $data = $this->_db->get('private_messages', ['id', $pm_id]); if ($data->count()) { @@ -869,10 +914,11 @@ public function getPM(int $pm_id, int $user_id): ?array { * Check the user's permission to see if they can view this staffCP page or not. * If they cannot, this will handle appropriate redirection. * - * @param string|null $permission Permission required for this page. + * @param string|null $permission Permission required for this page. * @return bool */ - public function handlePanelPageLoad(string $permission = null): bool { + public function handlePanelPageLoad(string $permission = null): bool + { // Set page user is trying to access in session, to allow for redirection post-auth if (FRIENDLY_URLS === true) { $split = explode('?', $_SERVER['REQUEST_URI']); @@ -910,7 +956,8 @@ public function handlePanelPageLoad(string $permission = null): bool { * * @return bool Whether they can view it or not. */ - public function canViewStaffCP(): bool { + public function canViewStaffCP(): bool + { foreach ($this->getGroups() as $group) { if ($group->admin_cp == 1) { return true; @@ -925,19 +972,21 @@ public function canViewStaffCP(): bool { * * @return bool Whether they're logged in as admin. */ - public function isAdmLoggedIn(): bool { + public function isAdmLoggedIn(): bool + { return $this->_isAdmLoggedIn; } /** - * Get profile fields for this user + * Get profile fields for this user. * * @param bool $show_private Whether to only return public fields or not (default `true`). - * @param bool $only_forum Whether to only return fields which display on forum posts, only if $public is true (default `false`). + * @param bool $only_forum Whether to only return fields which display on forum posts, only if $public is true (default `false`). * * @return array Array of profile fields. */ - public function getProfileFields(bool $show_private = false, bool $only_forum = false): array { + public function getProfileFields(bool $show_private = false, bool $only_forum = false): array + { $rows = DB::getInstance()->query('SELECT pf.*, upf.id as upf_id, upf.value, upf.updated FROM nl2_profile_fields pf LEFT JOIN nl2_users_profile_fields upf ON (pf.id = upf.field_id AND upf.user_id = ?)', [ $this->data()->id, ])->results(); @@ -960,12 +1009,13 @@ public function getProfileFields(bool $show_private = false, bool $only_forum = /** * Is a user blocked? * - * @param int $user ID of first user + * @param int $user ID of first user * @param int $blocked ID of user who may or may not be blocked * * @return bool Whether they are blocked or not. */ - public function isBlocked(int $user, int $blocked): bool { + public function isBlocked(int $user, int $blocked): bool + { if ($user && $blocked) { $possible_users = $this->_db->get('blocked_users', ['user_id', $user]); if ($possible_users->count()) { @@ -987,7 +1037,8 @@ public function isBlocked(int $user, int $blocked): bool { * * @return int Numer of profile views they have */ - public function getProfileViews(): int { + public function getProfileViews(): int + { if ($this->exists()) { return $this->data()->profile_views; } @@ -1000,7 +1051,8 @@ public function getProfileViews(): int { * * @return bool Whether profile privatizing is allowed and if they have permission to use it. */ - public function canPrivateProfile(): bool { + public function canPrivateProfile(): bool + { return Settings::get('private_profile') === '1' && $this->hasPermission('usercp.private_profile'); } @@ -1009,7 +1061,8 @@ public function canPrivateProfile(): bool { * * @return bool Whether the user can bypass private profiles */ - public function canBypassPrivateProfile(): bool { + public function canBypassPrivateProfile(): bool + { return Settings::get('private_profile') === '1' && $this->hasPermission('profile.private.bypass'); } @@ -1018,7 +1071,8 @@ public function canBypassPrivateProfile(): bool { * * @return bool Whether their profile is set to private or not. */ - public function isPrivateProfile(): bool { + public function isPrivateProfile(): bool + { return $this->data()->private_profile ?? false; } @@ -1027,7 +1081,8 @@ public function isPrivateProfile(): bool { * * @return array Templates which the user has access to. */ - public function getUserTemplates(): array { + public function getUserTemplates(): array + { $groups = '('; foreach ($this->getGroups() as $group) { $groups .= ((int) $group->id) . ','; @@ -1040,10 +1095,11 @@ public function getUserTemplates(): array { /** * Save/update this users placeholders. * - * @param int $server_id Server ID from staffcp -> integrations to assoc these placeholders with. + * @param int $server_id Server ID from staffcp -> integrations to assoc these placeholders with. * @param array $placeholders Key/value array of placeholders name/value from API endpoint. */ - public function savePlaceholders(int $server_id, array $placeholders): void { + public function savePlaceholders(int $server_id, array $placeholders): void + { $integrationUser = $this->getIntegration('Minecraft'); if ($integrationUser === null || !$integrationUser->getIntegration()->isEnabled()) { return; @@ -1062,7 +1118,7 @@ public function savePlaceholders(int $server_id, array $placeholders): void { $value, $last_updated, $value, - $last_updated + $last_updated, ]); } } diff --git a/core/classes/Core/Util.php b/core/classes/Core/Util.php index 03f1ce6f1a..25ff848e7c 100644 --- a/core/classes/Core/Util.php +++ b/core/classes/Core/Util.php @@ -10,8 +10,8 @@ * @version 2.0.0-pr13 * @license MIT */ -class Util { - +class Util +{ private static array $_enabled_modules = []; /** @@ -22,18 +22,19 @@ class Util { * * @return string Converted string. */ - public static function cyrillicToLatin(string $string): string { + public static function cyrillicToLatin(string $string): string + { $cyrillic = [ 'а', 'б', 'в', 'г', 'д', 'е', 'ё', 'ж', 'з', 'и', 'й', 'к', 'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш', 'щ', 'ъ', 'ы', 'ь', 'э', 'ю', 'я', 'А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ё', 'Ж', 'З', 'И', 'Й', 'К', 'Л', 'М', 'Н', 'О', 'П', - 'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Ъ', 'Ы', 'Ь', 'Э', 'Ю', 'Я' + 'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Ъ', 'Ы', 'Ь', 'Э', 'Ю', 'Я', ]; $latin = [ 'a', 'b', 'v', 'g', 'd', 'e', 'io', 'zh', 'z', 'i', 'y', 'k', 'l', 'm', 'n', 'o', 'p', 'r', 's', 't', 'u', 'f', 'h', 'ts', 'ch', 'sh', 'sht', 'a', 'i', 'y', 'e', 'yu', 'ya', 'A', 'B', 'V', 'G', 'D', 'E', 'Io', 'Zh', 'Z', 'I', 'Y', 'K', 'L', 'M', 'N', 'O', 'P', - 'R', 'S', 'T', 'U', 'F', 'H', 'Ts', 'Ch', 'Sh', 'Sht', 'A', 'I', 'Y', 'e', 'Yu', 'Ya' + 'R', 'S', 'T', 'U', 'F', 'H', 'Ts', 'Ch', 'Sh', 'Sht', 'A', 'I', 'Y', 'e', 'Yu', 'Ya', ]; return str_replace($cyrillic, $latin, $string); @@ -46,7 +47,8 @@ public static function cyrillicToLatin(string $string): string { * * @return bool Whether the action succeeded or not. */ - public static function recursiveRemoveDirectory(string $directory): bool { + public static function recursiveRemoveDirectory(string $directory): bool + { // safety precaution, only allow deleting files in "custom" directory if (!str_contains($directory, 'custom')) { return false; @@ -74,7 +76,8 @@ public static function recursiveRemoveDirectory(string $directory): bool { * * @return array All timezones. */ - public static function listTimezones(): array { + public static function listTimezones(): array + { // Array to contain timezones $timezones = []; @@ -95,7 +98,7 @@ public static function listTimezones(): array { $offsets[] = $current->getOffset(); // Format timezone offset - $offset = 'GMT ' . (int)($current->getOffset() / 3600) . ':' . str_pad(abs((int)($current->getOffset() % 3600 / 60)), 2, 0); + $offset = 'GMT ' . (int) ($current->getOffset() / 3600) . ':' . str_pad(abs((int) ($current->getOffset() % 3600 / 60)), 2, 0); // Prettify timezone name $name = Output::getClean(str_replace(['/', '_'], [', ', ' '], $timezone)); @@ -114,10 +117,12 @@ public static function listTimezones(): array { * * @return string|UpdateCheck Object with information about any updates, or error message. */ - public static function updateCheck() { + public static function updateCheck() + { $uid = self::getSetting('unique_id'); - $update_check_response = HttpClient::get('https://namelessmc.com/api/v2/updateCheck&uid=' . $uid . + $update_check_response = HttpClient::get( + 'https://namelessmc.com/api/v2/updateCheck&uid=' . $uid . '&version=' . NAMELESS_VERSION . '&php_version=' . urlencode(PHP_VERSION) . '&language=' . LANGUAGE . @@ -134,10 +139,12 @@ public static function updateCheck() { return $update_check->getErrorMessage(); } - self::setSetting("version_checked", date('U')); + self::setSetting('version_checked', date('U')); if ($update_check->updateAvailable()) { - self::setSetting('version_update', $update_check->isUrgent() + self::setSetting( + 'version_update', + $update_check->isUrgent() ? 'urgent' : 'true' ); @@ -151,12 +158,13 @@ public static function updateCheck() { * * @return string NamelessMC news in JSON. */ - public static function getLatestNews(): string { + public static function getLatestNews(): string + { $news = HttpClient::get('https://namelessmc.com/news'); if ($news->hasError()) { return json_encode([ - 'error' => $news->getError() + 'error' => $news->getError(), ]); } @@ -166,37 +174,40 @@ public static function getLatestNews(): string { /** * Get a setting from the database table `nl2_settings`. * - * @param string $setting Setting to check. - * @param ?string $fallback Fallback to return if $setting is not set in DB. Defaults to null. - * @param string $module Module name to keep settings separate from other modules. Set module - * to 'Core' for global settings. + * @param string $setting Setting to check. + * @param ?string $fallback Fallback to return if $setting is not set in DB. Defaults to null. + * @param string $module Module name to keep settings separate from other modules. Set module + * to 'Core' for global settings. * @return ?string Setting from DB or $fallback. * @deprecated Use Settings::get() instead. Will be removed in 2.2.0 */ - public static function getSetting(string $setting, ?string $fallback = null, string $module = 'core'): ?string { + public static function getSetting(string $setting, ?string $fallback = null, string $module = 'core'): ?string + { return Settings::get($setting, $fallback, $module); } /** * Modify a setting in the database table `nl2_settings`. * - * @param string $setting Setting name. + * @param string $setting Setting name. * @param string|null $new_value New setting value, or null to delete - * @param string $module Module name to keep settings separate from other modules. Set module - * to 'Core' for global settings. + * @param string $module Module name to keep settings separate from other modules. Set module + * to 'Core' for global settings. * @deprecated Use Settings::set() instead. Will be removed in 2.2.0 */ - public static function setSetting(string $setting, ?string $new_value, string $module = 'core'): void { + public static function setSetting(string $setting, ?string $new_value, string $module = 'core'): void + { Settings::set($setting, $new_value, $module); } /** - * Determine if a specific module is enabled + * Determine if a specific module is enabled. * - * @param string $name Name of module to check for. - * @return bool Whether this module is enabled or not. + * @param string $name Name of module to check for. + * @return bool Whether this module is enabled or not. */ - public static function isModuleEnabled(string $name): bool { + public static function isModuleEnabled(string $name): bool + { if (in_array($name, self::$_enabled_modules)) { return true; } @@ -208,6 +219,7 @@ public static function isModuleEnabled(string $name): bool { if (in_array($name, array_column($enabled_modules, 'name'))) { self::$_enabled_modules[] = $name; + return true; } @@ -216,11 +228,12 @@ public static function isModuleEnabled(string $name): bool { /** * Read the last part of a file, removing a leading partial line if necessary. - * @param string $file_path Path to file to read - * @param int $max_bytes Max number of bytes to read at end of file + * @param string $file_path Path to file to read + * @param int $max_bytes Max number of bytes to read at end of file * @return string Read string */ - public static function readFileEnd(string $file_path, int $max_bytes = 100_000): string { + public static function readFileEnd(string $file_path, int $max_bytes = 100_000): string + { $fp = fopen($file_path, 'rb'); $size = filesize($file_path); $start = max([$size - $max_bytes, 0]); @@ -233,6 +246,7 @@ public static function readFileEnd(string $file_path, int $max_bytes = 100_000): $first_lf = strpos($content, PHP_EOL); $content = substr($content, $first_lf + 1); } + return $content; } @@ -241,11 +255,12 @@ public static function readFileEnd(string $file_path, int $max_bytes = 100_000): /** * Determine the order of array items with dependencies (denoted by the "after" or "before" field) - * This is a more generic version of the module sort order determination - * @param array $items Items (array of items consisting of after, before and name) + * This is a more generic version of the module sort order determination. + * @param array $items Items (array of items consisting of after, before and name) * @return array Ordered items */ - public static function determineOrder(array $items): array { + public static function determineOrder(array $items): array + { if (empty($items)) { return $items; } @@ -271,11 +286,12 @@ public static function determineOrder(array $items): array { /** * Used by order determination to get items before or after a specified item * Typically not called on its own - use Util::determineOrder in most cases! - * @param array $items Names of items already processed - * @param string $current Name of current item - * @return array Items before and after the current item + * @param array $items Names of items already processed + * @param string $current Name of current item + * @return array Items before and after the current item */ - public static function findBeforeAfter(array $items, string $current): array { + public static function findBeforeAfter(array $items, string $current): array + { $before = [$current]; $after = []; $found = false; @@ -299,15 +315,15 @@ public static function findBeforeAfter(array $items, string $current): array { * Determine whether a module/template version is compatible with the current NamelessMC version. * This ignores patch versions, and only checks major and minor versions. * For example, 2.0.0 and 2.0.1 are compatible, but 2.0.0 and 2.1.0 are not. - * @param string $version Version of module/template to check - * @param string $nameless_version Current NamelessMC version - * @return bool Whether they are compatible or not + * @param string $version Version of module/template to check + * @param string $nameless_version Current NamelessMC version + * @return bool Whether they are compatible or not */ - public static function isCompatible(string $version, string $nameless_version): bool { - [$major, $minor, ] = explode('.', $version); - [$nameless_major, $nameless_minor, ] = explode('.', $nameless_version); + public static function isCompatible(string $version, string $nameless_version): bool + { + [$major, $minor] = explode('.', $version); + [$nameless_major, $nameless_minor] = explode('.', $nameless_version); return $major == $nameless_major && $minor == $nameless_minor; } - } diff --git a/core/classes/Core/Validate.php b/core/classes/Core/Validate.php index b8439ac303..95acaa7cc3 100644 --- a/core/classes/Core/Validate.php +++ b/core/classes/Core/Validate.php @@ -9,8 +9,8 @@ * @version 2.0.0-pr13 * @license MIT */ -class Validate { - +class Validate +{ /** * @var string Ensure this field is not empty */ @@ -115,9 +115,10 @@ class Validate { private array $_errors = []; /** - * Create new `Validate` instance + * Create new `Validate` instance. */ - private function __construct() { + private function __construct() + { // Connect to database for rules which need DB access try { $host = Config::get('mysql.host'); @@ -134,20 +135,19 @@ private function __construct() { * Validate an array of inputs. * * @param array $source inputs (eg: $_POST) - * @param array $items subset of inputs to be validated + * @param array $items subset of inputs to be validated * - * @return Validate New instance of Validate. * @throws Exception If provided configuration for a rule is invalid - not if a provided value is invalid! + * @return Validate New instance of Validate. */ - public static function check(array $source, array $items = []): Validate { + public static function check(array $source, array $items = []): Validate + { $validator = new Validate(); // Loop through the items which need validating foreach ($items as $item => $rules) { - // Loop through each validation rule for the set item foreach ($rules as $rule => $rule_value) { - $value = trim($source[$item]); // Escape the item's contents just in case @@ -164,7 +164,7 @@ public static function check(array $source, array $items = []): Validate { if (empty($source[$array][$matches[1]])) { $missing = true; } - } else if (empty($value) && $value !== '0') { + } elseif (empty($value) && $value !== '0') { $missing = true; } @@ -173,7 +173,7 @@ public static function check(array $source, array $items = []): Validate { $validator->addError([ 'field' => $item, 'rule' => self::REQUIRED, - 'fallback' => "$item is required." + 'fallback' => "$item is required.", ]); continue; } @@ -185,13 +185,12 @@ public static function check(array $source, array $items = []): Validate { // The post array does include this value, continue validating switch ($rule) { - case self::MIN: if (mb_strlen($value) < $rule_value) { $validator->addError([ 'field' => $item, 'rule' => self::MIN, - 'fallback' => "$item must be a minimum of $rule_value characters." + 'fallback' => "$item must be a minimum of $rule_value characters.", ]); } break; @@ -201,7 +200,7 @@ public static function check(array $source, array $items = []): Validate { $validator->addError([ 'field' => $item, 'rule' => self::MAX, - 'fallback' => "$item must be a maximum of $rule_value characters." + 'fallback' => "$item must be a maximum of $rule_value characters.", ]); } break; @@ -211,7 +210,7 @@ public static function check(array $source, array $items = []): Validate { $validator->addError([ 'field' => $item, 'rule' => self::MATCHES, - 'fallback' => "$rule_value must match $item." + 'fallback' => "$rule_value must match $item.", ]); } break; @@ -221,7 +220,7 @@ public static function check(array $source, array $items = []): Validate { $validator->addError([ 'field' => $item, 'rule' => self::AGREE, - 'fallback' => 'You must agree to our terms and conditions in order to register.' + 'fallback' => 'You must agree to our terms and conditions in order to register.', ]); } break; @@ -269,7 +268,7 @@ public static function check(array $source, array $items = []): Validate { $validator->addError([ 'field' => $item, 'rule' => self::UNIQUE, - 'fallback' => "The $rule_value.$item $value already exists!" + 'fallback' => "The $rule_value.$item $value already exists!", ]); } break; @@ -279,7 +278,7 @@ public static function check(array $source, array $items = []): Validate { $validator->addError([ 'field' => $item, 'rule' => self::EMAIL, - 'fallback' => "$value is not a valid email." + 'fallback' => "$value is not a valid email.", ]); } break; @@ -289,7 +288,7 @@ public static function check(array $source, array $items = []): Validate { $validator->addError([ 'field' => $item, 'rule' => self::TIMEZONE, - 'fallback' => "The timezone $value is invalid." + 'fallback' => "The timezone $value is invalid.", ]); } break; @@ -305,7 +304,7 @@ public static function check(array $source, array $items = []): Validate { $validator->addError([ 'field' => $item, 'rule' => self::IS_ACTIVE, - 'fallback' => "That $item is inactive. Have you validated your account or requested a password reset?" + 'fallback' => "That $item is inactive. Have you validated your account or requested a password reset?", ]); } break; @@ -321,7 +320,7 @@ public static function check(array $source, array $items = []): Validate { $validator->addError([ 'field' => $item, 'rule' => self::IS_BANNED, - 'fallback' => "The username $value is banned." + 'fallback' => "The username $value is banned.", ]); } break; @@ -331,7 +330,7 @@ public static function check(array $source, array $items = []): Validate { $validator->addError([ 'field' => $item, 'rule' => self::ALPHANUMERIC, - 'fallback' => "$item must be alphanumeric." + 'fallback' => "$item must be alphanumeric.", ]); } break; @@ -341,7 +340,7 @@ public static function check(array $source, array $items = []): Validate { $validator->addError([ 'field' => $item, 'rule' => self::NUMERIC, - 'fallback' => "$item must be numeric." + 'fallback' => "$item must be numeric.", ]); } break; @@ -351,7 +350,7 @@ public static function check(array $source, array $items = []): Validate { $validator->addError([ 'field' => $item, 'rule' => self::REGEX, - 'fallback' => "$item does not match the pattern $rule_value." + 'fallback' => "$item does not match the pattern $rule_value.", ]); } break; @@ -363,7 +362,7 @@ public static function check(array $source, array $items = []): Validate { $validator->addError([ 'field' => $item, 'rule' => self::NOT_START_WITH, - 'fallback' => "$item must not start with $denied_value." + 'fallback' => "$item must not start with $denied_value.", ]); } break; @@ -395,7 +394,7 @@ public static function check(array $source, array $items = []): Validate { $validator->addError([ 'field' => $item, 'rule' => self::IN, - 'fallback' => "$item must be one of $string_values." + 'fallback' => "$item must be one of $string_values.", ]); } break; @@ -404,7 +403,7 @@ public static function check(array $source, array $items = []): Validate { if (is_array($rule_value) && count($rule_value) === 2) { // If array treat as [limit, seconds] [$limit, $seconds] = $rule_value; - } else if (is_int($rule_value)) { + } elseif (is_int($rule_value)) { // If integer default seconds to 60 [$limit, $seconds] = [$rule_value, 60]; } @@ -462,7 +461,8 @@ public static function check(array $source, array $items = []): Validate { * * @param array $error message to add to error array */ - private function addError(array $error): void { + private function addError(array $error): void + { $this->_to_convert[] = $error; } @@ -473,8 +473,10 @@ private function addError(array $error): void { * * @return Validate This instance of Validate. */ - public function message(string $message): Validate { + public function message(string $message): Validate + { $this->_message = $message; + return $this; } @@ -485,8 +487,10 @@ public function message(string $message): Validate { * * @return Validate This instance of Validate. */ - public function messages(array $messages): Validate { + public function messages(array $messages): Validate + { $this->_messages = $messages; + return $this; } @@ -495,8 +499,8 @@ public function messages(array $messages): Validate { * * @return array Any and all errors for this `Validate` instance. */ - public function errors(): array { - + public function errors(): array + { // If errors have already been translated, don't waste time redoing it if (!empty($this->_errors)) { return $this->_errors; @@ -504,7 +508,6 @@ public function errors(): array { // Loop all errors to convert and get their custom messages foreach ($this->_to_convert as $error) { - $message = $this->getMessage($error['field'], $error['rule'], $error['fallback'], $error['meta']); // If there is no generic `message()` set or the translated message is not equal to generic message @@ -530,17 +533,17 @@ public function errors(): array { * - Message for field, not rule specific * - Result of callable if "*" rule exists * - Generic message set with `message(...)` - * - Fallback message for rule + * - Fallback message for rule. * - * @param string $field name of field to search for. - * @param string $rule rule which check failed. should be from the constants defined above. + * @param string $field name of field to search for. + * @param string $rule rule which check failed. should be from the constants defined above. * @param string $fallback fallback default message if custom message and generic message are not supplied. - * @param ?array $meta optional meta to provide to message. + * @param ?array $meta optional meta to provide to message. * * @return string Message for this field and rule. */ - private function getMessage(string $field, string $rule, string $fallback, ?array $meta = []): string { - + private function getMessage(string $field, string $rule, string $fallback, ?array $meta = []): string + { // No custom messages defined for this field if (!isset($this->_messages[$field])) { if (isset($this->_messages['*'])) { @@ -577,8 +580,8 @@ private function getMessage(string $field, string $rule, string $fallback, ?arra * * @return bool whether this 'Validate' passed or not. */ - public function passed(): bool { + public function passed(): bool + { return $this->_passed; } - } diff --git a/core/classes/DTO/Announcement.php b/core/classes/DTO/Announcement.php index 4010359229..5f5233a3f8 100644 --- a/core/classes/DTO/Announcement.php +++ b/core/classes/DTO/Announcement.php @@ -1,7 +1,7 @@ id = $row->id; $this->pages = $row->pages; $this->groups = $row->groups; @@ -26,11 +27,12 @@ public function __construct(object $row) { $this->order = $row->order; } - public static function find(int $id): ?Announcement { + public static function find(int $id): ?Announcement + { $row = DB::getInstance()->query('SELECT * FROM nl2_custom_announcements WHERE id = ?', [$id])->results(); + return $row ? new Announcement($row[0]) : null; } - } diff --git a/core/classes/DTO/Group.php b/core/classes/DTO/Group.php index bdadfac8ab..7e6e780bfa 100644 --- a/core/classes/DTO/Group.php +++ b/core/classes/DTO/Group.php @@ -7,8 +7,8 @@ * @version 2.0.0-pr13 * @license MIT */ -class Group { - +class Group +{ public int $id; public string $name; public string $group_html; @@ -22,7 +22,8 @@ class Group { public bool $force_tfa; public bool $deleted; - public function __construct(object $row) { + public function __construct(object $row) + { $this->id = $row->id; $this->name = $row->name; $this->group_html = $row->group_html; @@ -40,25 +41,28 @@ public function __construct(object $row) { /** * @return array */ - public static function all(): array { + public static function all(): array + { $rows = DB::getInstance()->query('SELECT * FROM nl2_groups ORDER BY `order`')->results(); $fields = []; foreach ($rows as $row) { $fields[$row->id] = new Group($row); } + return $fields; } /** - * @param string $value - * @param string $column + * @param string $value + * @param string $column * @return Group|null */ - public static function find(string $value, string $column = 'id'): ?Group { + public static function find(string $value, string $column = 'id'): ?Group + { $row = DB::getInstance()->get('groups', [$column, $value])->first(); + return $row ? new Group($row) : null; } - } diff --git a/core/classes/DTO/IntegrationData.php b/core/classes/DTO/IntegrationData.php index e641137837..1f13ceb1f8 100644 --- a/core/classes/DTO/IntegrationData.php +++ b/core/classes/DTO/IntegrationData.php @@ -1,7 +1,7 @@ id = $row->id; $this->name = $row->name; $this->enabled = $row->enabled; @@ -17,5 +18,4 @@ public function __construct(object $row) { $this->required = $row->required; $this->order = $row->order; } - } diff --git a/core/classes/DTO/IntegrationUserData.php b/core/classes/DTO/IntegrationUserData.php index b4ab6b8448..939f23d7d8 100644 --- a/core/classes/DTO/IntegrationUserData.php +++ b/core/classes/DTO/IntegrationUserData.php @@ -1,7 +1,7 @@ id = $row->id; $this->integration_id = $row->integration_id; $this->user_id = $row->user_id; @@ -25,5 +26,4 @@ public function __construct(object $row) { $this->show_publicly = $row->show_publicly; $this->last_sync = $row->last_sync; } - } diff --git a/core/classes/DTO/ProfileField.php b/core/classes/DTO/ProfileField.php index ce05145a45..a6198d198a 100644 --- a/core/classes/DTO/ProfileField.php +++ b/core/classes/DTO/ProfileField.php @@ -7,8 +7,8 @@ * @version 2.0.0-pr13 * @license MIT */ -class ProfileField { - +class ProfileField +{ public int $id; public string $name; public int $type; @@ -19,7 +19,8 @@ class ProfileField { public bool $forum_posts; public bool $editable; - public function __construct(object $row) { + public function __construct(object $row) + { $this->id = $row->id; $this->name = $row->name; $this->type = $row->type; @@ -34,21 +35,24 @@ public function __construct(object $row) { /** * @return array */ - public static function all(): array { + public static function all(): array + { $rows = DB::getInstance()->get('profile_fields', ['id', '<>', 0])->results(); $fields = []; foreach ($rows as $row) { $fields[$row->id] = new ProfileField($row); } + return $fields; } /** - * @param string $value - * @param string $column + * @param string $value + * @param string $column * @return array|ProfileField */ - public static function find(string $value, string $column = 'id') { + public static function find(string $value, string $column = 'id') + { $rows = DB::getInstance()->get('profile_fields', [$column, $value]); if (!$rows->count()) { return []; @@ -65,5 +69,4 @@ public static function find(string $value, string $column = 'id') { return $fields; } - } diff --git a/core/classes/DTO/Reaction.php b/core/classes/DTO/Reaction.php index 525a14b879..9bb21e7b85 100644 --- a/core/classes/DTO/Reaction.php +++ b/core/classes/DTO/Reaction.php @@ -7,8 +7,8 @@ * @version 2.1.0 * @license MIT */ -class Reaction { - +class Reaction +{ public const TYPE_POSITIVE = 2; public const TYPE_NEGATIVE = 0; public const TYPE_NEUTRAL = 1; @@ -23,7 +23,8 @@ class Reaction { public int $order; public ?int $custom_score; - public function __construct(object $row) { + public function __construct(object $row) + { $this->id = $row->id; $this->name = $row->name; $this->html = Text::renderEmojis($row->html); @@ -37,21 +38,24 @@ public function __construct(object $row) { /** * @return array */ - public static function all(): array { + public static function all(): array + { $rows = DB::getInstance()->query('SELECT * FROM nl2_reactions ORDER BY `order`')->results(); $fields = []; foreach ($rows as $row) { $fields[$row->id] = new Reaction($row); } + return $fields; } /** - * @param string $value - * @param string $column + * @param string $value + * @param string $column * @return array|Reaction */ - public static function find(string $value, string $column = 'id') { + public static function find(string $value, string $column = 'id') + { $rows = DB::getInstance()->query("SELECT * FROM nl2_reactions WHERE `$column` = ? ORDER BY `order`", [$value]); if (!$rows->count()) { return []; diff --git a/core/classes/DTO/UpdateCheck.php b/core/classes/DTO/UpdateCheck.php index 42a32a9a62..6852716620 100644 --- a/core/classes/DTO/UpdateCheck.php +++ b/core/classes/DTO/UpdateCheck.php @@ -7,54 +7,64 @@ * @version 2.0.0-pr13 * @license MIT */ -class UpdateCheck { - +class UpdateCheck +{ private ?string $_raw_response; private ?array $_response; - public function __construct(HttpClient $update_check_response) { + public function __construct(HttpClient $update_check_response) + { $this->_raw_response = $update_check_response->contents(); $this->_response = json_decode($this->_raw_response, true); } - public function hasError(): bool { + public function hasError(): bool + { return $this->_response === null || !count($this->_response) || $this->_response['error']; } - public function getErrorMessage(): string { + public function getErrorMessage(): string + { if (isset($this->_response['message'])) { return 'Error from server: ' . $this->_response['message']; } - return 'Invalid response from server: ' . $this->_raw_response; + return 'Invalid response from server: ' . $this->_raw_response; } - public function updateAvailable(): bool { + public function updateAvailable(): bool + { return $this->_response['update_available']; } - public function isUrgent(): bool { + public function isUrgent(): bool + { return $this->_response['urgent']; } - public function instructions(): string { + public function instructions(): string + { return $this->_response['install_instructions']; } - public function version(): string { + public function version(): string + { return $this->_response['name'] . ' (' . $this->_response['version_tag'] . ')'; } - public function upgradeZipLink(): string { + public function upgradeZipLink(): string + { return $this->_response['upgrade_zip_link']; } - public function gitHubLink(): string { + public function gitHubLink(): string + { return $this->_response['github_link']; } // TODO: @samerton - public function checksum(): string { + public function checksum(): string + { return $this->_response['checksum']; } } diff --git a/core/classes/DTO/UserData.php b/core/classes/DTO/UserData.php index a06ebdf108..ada2e0e0fe 100644 --- a/core/classes/DTO/UserData.php +++ b/core/classes/DTO/UserData.php @@ -7,8 +7,8 @@ * @version 2.0.0-pr13 * @license MIT */ -class UserData { - +class UserData +{ public int $id; public string $username; public string $nickname; @@ -42,7 +42,8 @@ class UserData { public ?string $register_method; public bool $authme_sync_password; - public function __construct(object $row) { + public function __construct(object $row) + { $this->id = $row->id; $this->username = $row->username; $this->nickname = $row->nickname; @@ -76,5 +77,4 @@ public function __construct(object $row) { $this->register_method = $row->register_method; $this->authme_sync_password = $row->authme_sync_password; } - } diff --git a/core/classes/DTO/UserProfileField.php b/core/classes/DTO/UserProfileField.php index 3645e5bfbd..6165a40dde 100644 --- a/core/classes/DTO/UserProfileField.php +++ b/core/classes/DTO/UserProfileField.php @@ -7,21 +7,22 @@ * @version 2.0.0-pr13 * @license MIT */ -class UserProfileField extends ProfileField { - +class UserProfileField extends ProfileField +{ public ?string $value; public ?int $updated; public ?int $upf_id; - public function __construct(object $row) { + public function __construct(object $row) + { parent::__construct($row); $this->value = $row->value; $this->updated = $row->updated; $this->upf_id = $row->upf_id; } - - public function updated() { + public function updated() + { return date(DATE_FORMAT, $this->updated); } } diff --git a/core/classes/Database/DB.php b/core/classes/Database/DB.php index 0e38da81bd..e639cb43fb 100644 --- a/core/classes/Database/DB.php +++ b/core/classes/Database/DB.php @@ -7,8 +7,8 @@ * @version 2.0.0-pr13 * @license MIT */ -class DB { - +class DB +{ private static ?DB $_instance = null; private string $_prefix; @@ -73,7 +73,8 @@ public static function getCustomInstance( ); } - public static function getInstance(): DB { + public static function getInstance(): DB + { if (self::$_instance) { return self::$_instance; } @@ -106,30 +107,34 @@ public static function getInstance(): DB { * * @return PDO The PDO instance. */ - public function getPDO(): PDO { + public function getPDO(): PDO + { return $this->_pdo; } /** - * Begin a MySQL transaction + * Begin a MySQL transaction. */ - public function beginTransaction(): void { + public function beginTransaction(): void + { $this->_pdo->beginTransaction(); } /** - * Commit a MySQL transaction + * Commit a MySQL transaction. */ - public function commitTransaction(): void { + public function commitTransaction(): void + { if ($this->_pdo->inTransaction()) { $this->_pdo->commit(); } } /** - * Roll back a MySQL transaction + * Roll back a MySQL transaction. */ - public function rollBackTransaction(): void { + public function rollBackTransaction(): void + { if ($this->_pdo->inTransaction()) { $this->_pdo->rollBack(); } @@ -138,10 +143,11 @@ public function rollBackTransaction(): void { /** * Execute a database query within a MySQL transaction, and get the results of the query, if any. * - * @param Closure(DB): mixed $closure The closure to pass this instance to and execute within a transaction context. - * @return mixed The results of the query, null if none. + * @param Closure(DB): mixed $closure The closure to pass this instance to and execute within a transaction context. + * @return mixed The results of the query, null if none. */ - public function transaction(Closure $closure) { + public function transaction(Closure $closure) + { $result = null; try { @@ -162,7 +168,8 @@ public function transaction(Closure $closure) { * * @return object|null The result object, or null if no result was returned. */ - public function first(): ?object { + public function first(): ?object + { return $this->results()[0] ?? null; } @@ -171,7 +178,8 @@ public function first(): ?object { * * @return array The results of the query. */ - public function results(): array { + public function results(): array + { return $this->_results; } @@ -180,7 +188,8 @@ public function results(): array { * * @return int The number of rows. */ - public function count(): int { + public function count(): int + { return $this->_count; } @@ -189,16 +198,18 @@ public function count(): int { * * @return bool Whether any results exist. */ - public function exists(): bool { + public function exists(): bool + { return $this->_count > 0; } /** - * Get the last inserted ID + * Get the last inserted ID. * * @return string|false ID of the last inserted row or false on failure */ - public function lastId() { + public function lastId() + { return $this->_pdo->lastInsertId(); } @@ -207,18 +218,20 @@ public function lastId() { * * @return bool Whether there was an error. */ - public function error(): bool { + public function error(): bool + { return $this->_error; } /** * Perform a SELECT query on the database. * - * @param string $table The table to select from. - * @param mixed $where The where clause. If not an array, it will be used for "id" column lookup. + * @param string $table The table to select from. + * @param mixed $where The where clause. If not an array, it will be used for "id" column lookup. * @return static|false This instance if successful, false otherwise. */ - public function get(string $table, $where = []) { + public function get(string $table, $where = []) + { if (!is_array($where)) { $where = ['id', '=', $where]; } @@ -229,11 +242,12 @@ public function get(string $table, $where = []) { /** * Perform a DELETE query on the database. * - * @param string $table The table to delete from. - * @param mixed $where The where clause. If not an array, it will be used for "id" column lookup. + * @param string $table The table to delete from. + * @param mixed $where The where clause. If not an array, it will be used for "id" column lookup. * @return static|false This instance if successful, false otherwise. */ - public function delete(string $table, $where) { + public function delete(string $table, $where) + { if (!is_array($where)) { $where = ['id', '=', $where]; } @@ -244,12 +258,13 @@ public function delete(string $table, $where) { /** * Perform a raw SQL query on the database. * - * @param string $sql The SQL query string to execute. - * @param array $params The parameters to bind to the query. - * @param bool $isSelect Whether the statement is a select, defaults to null + * @param string $sql The SQL query string to execute. + * @param array $params The parameters to bind to the query. + * @param bool $isSelect Whether the statement is a select, defaults to null * @return static This DB instance. */ - public function query(string $sql, array $params = [], bool $isSelect = null) { + public function query(string $sql, array $params = [], bool $isSelect = null) + { $this->_error = false; if ($this->_statement = $this->_pdo->prepare($sql)) { $x = 1; @@ -258,7 +273,10 @@ public function query(string $sql, array $params = [], bool $isSelect = null) { if (is_bool($param)) { $param = $param ? 1 : 0; } - $this->_statement->bindValue($x, $param, is_int($param) + $this->_statement->bindValue( + $x, + $param, + is_int($param) ? PDO::PARAM_INT : PDO::PARAM_STR ); @@ -287,12 +305,13 @@ public function query(string $sql, array $params = [], bool $isSelect = null) { /** * Execute some SQL action (which uses a where clause) on the database. * - * @param string $action The action to perform (SELECT, DELETE). - * @param string $table The table to perform the action on. - * @param array $where The where clause. + * @param string $action The action to perform (SELECT, DELETE). + * @param string $table The table to perform the action on. + * @param array $where The where clause. * @return static|false This instance if successful, false otherwise. */ - private function action(string $action, string $table, array $where = []) { + private function action(string $action, string $table, array $where = []) + { [$where, $where_params] = $this->makeWhere($where); $table = $this->_prefix . $table; @@ -308,11 +327,12 @@ private function action(string $action, string $table, array $where = []) { /** * Insert a new row into a table within the database. * - * @param string $table The table to insert into. - * @param array $fields Array of data in "column => value" format to insert. - * @return bool Whether an error occurred or not. + * @param string $table The table to insert into. + * @param array $fields Array of data in "column => value" format to insert. + * @return bool Whether an error occurred or not. */ - public function insert(string $table, array $fields = []): bool { + public function insert(string $table, array $fields = []): bool + { $keys = array_keys($fields); $fieldCount = count($fields); $values = ''; @@ -335,12 +355,13 @@ public function insert(string $table, array $fields = []): bool { /** * Perform an UPDATE query on a table. * - * @param string $table The table to update. - * @param mixed $where The where clause. If not an array, it will be used for "id" column lookup. - * @param array $fields Array of data in "column => value" format to update. - * @return bool Whether an error occurred or not. + * @param string $table The table to update. + * @param mixed $where The where clause. If not an array, it will be used for "id" column lookup. + * @param array $fields Array of data in "column => value" format to update. + * @return bool Whether an error occurred or not. */ - public function update(string $table, $where, array $fields): bool { + public function update(string $table, $where, array $fields): bool + { $set = ''; $x = 1; @@ -367,12 +388,13 @@ public function update(string $table, $where, array $fields): bool { /** * Increment a numeric column value by 1. * - * @param string $table The table to use. - * @param int $id The id of the row to increment a column in. - * @param string $field The field to increment. - * @return bool Whether an error occurred or not. + * @param string $table The table to use. + * @param int $id The id of the row to increment a column in. + * @param string $field The field to increment. + * @return bool Whether an error occurred or not. */ - public function increment(string $table, int $id, string $field): bool { + public function increment(string $table, int $id, string $field): bool + { $table = $this->_prefix . $table; return !$this->query("UPDATE {$table} SET {$field} = {$field} + 1 WHERE id = ?", [$id])->error(); @@ -381,12 +403,13 @@ public function increment(string $table, int $id, string $field): bool { /** * Decrement a numeric column value by 1. * - * @param string $table The table to use. - * @param int $id The id of the row to decrement a column in. - * @param string $field The field to increment. - * @return bool Whether an error occurred or not. + * @param string $table The table to use. + * @param int $id The id of the row to decrement a column in. + * @param string $field The field to increment. + * @return bool Whether an error occurred or not. */ - public function decrement(string $table, int $id, string $field): bool { + public function decrement(string $table, int $id, string $field): bool + { $table = $this->_prefix . $table; return !$this->query("UPDATE {$table} SET {$field} = {$field} - 1 WHERE id = ?", [$id])->error(); @@ -395,12 +418,13 @@ public function decrement(string $table, int $id, string $field): bool { /** * Select rows from the database, ordering by a specific column and sort type. * - * @param string $table The table to use. - * @param string $order The column to order by. - * @param string $sort ASC or DESC + * @param string $table The table to use. + * @param string $order The column to order by. + * @param string $sort ASC or DESC * @return static|false This instance if successful, false otherwise. */ - public function orderAll(string $table, string $order, string $sort) { + public function orderAll(string $table, string $order, string $sort) + { $table = $this->_prefix . $table; $sql = "SELECT * FROM {$table} ORDER BY {$order} {$sort}"; @@ -414,12 +438,13 @@ public function orderAll(string $table, string $order, string $sort) { /** * Select rows from the database with a where clause, ordering by a specific column and sort type. * - * @param string $table The table to use. - * @param string $order The column to order by. - * @param string $sort ASC or DESC + * @param string $table The table to use. + * @param string $order The column to order by. + * @param string $sort ASC or DESC * @return static|false This instance if successful, false otherwise. */ - public function orderWhere(string $table, string $where, string $order, string $sort) { + public function orderWhere(string $table, string $where, string $order, string $sort) + { $table = $this->_prefix . $table; $sql = "SELECT * FROM {$table} WHERE {$where} ORDER BY {$order} {$sort}"; @@ -433,11 +458,12 @@ public function orderWhere(string $table, string $where, string $order, string $ /** * Create a new table in the database. * - * @param string $name The name of the table. - * @param string $table_schema The table SQL schema. - * @return bool Whether an error occurred or not. + * @param string $name The name of the table. + * @param string $table_schema The table SQL schema. + * @return bool Whether an error occurred or not. */ - public function createTable(string $name, string $table_schema): bool { + public function createTable(string $name, string $table_schema): bool + { $name = $this->_prefix . $name; $sql = "CREATE TABLE `{$name}` ({$table_schema}) ENGINE=InnoDB"; @@ -455,10 +481,11 @@ public function createTable(string $name, string $table_schema): bool { /** * Perform a SHOW TABLES LIKE query. * - * @param string $table Name of table to try and lookup. + * @param string $table Name of table to try and lookup. * @return int|false The number of rows affected, or false on failure. */ - public function showTables(string $table) { + public function showTables(string $table) + { $table = $this->_prefix . $table; $sql = "SHOW TABLES LIKE '{$table}'"; @@ -472,12 +499,13 @@ public function showTables(string $table) { /** * Add a new column to a table. * - * @param string $table Name of table to alter. - * @param string $column The column to add. - * @param string $attributes The attributes of the column. - * @return bool Whether an error occurred or not. + * @param string $table Name of table to alter. + * @param string $column The column to add. + * @param string $attributes The attributes of the column. + * @return bool Whether an error occurred or not. */ - public function addColumn(string $table, string $column, string $attributes): bool { + public function addColumn(string $table, string $column, string $attributes): bool + { $table = $this->_prefix . $table; $sql = "ALTER TABLE {$table} ADD {$column} {$attributes}"; @@ -487,11 +515,12 @@ public function addColumn(string $table, string $column, string $attributes): bo /** * Convert an array of where clause data into a MySQL WHERE clause and params. * - * @param array $clauses An array, or nested array, of - * column, operator (default =), value, and glue (default AND). + * @param array $clauses An array, or nested array, of + * column, operator (default =), value, and glue (default AND). * @return array The where clause string, and parameters to bind. */ - public static function makeWhere(array $clauses): array { + public static function makeWhere(array $clauses): array + { if (count($clauses) === count($clauses, COUNT_RECURSIVE)) { return self::makeWhere([$clauses]); } diff --git a/core/classes/Database/DatabaseInitialiser.php b/core/classes/Database/DatabaseInitialiser.php index 22fa054841..dda85fb037 100644 --- a/core/classes/Database/DatabaseInitialiser.php +++ b/core/classes/Database/DatabaseInitialiser.php @@ -1,16 +1,18 @@ _db = DB::getInstance(); $this->_cache = new Cache(['name' => 'nameless', 'extension' => '.cache', 'path' => ROOT_PATH . '/cache/']); } - public static function runPreUser() { + public static function runPreUser() + { $instance = new self(); $instance->initialiseGroups(); $instance->initialiseLanguages(); @@ -23,17 +25,19 @@ public static function runPreUser() { $instance->initialiseWidgets(); } - public static function runPostUser() { + public static function runPostUser() + { $instance = new self(); $instance->initialiseForum(); } - private function initialiseGroups(): void { + private function initialiseGroups(): void + { $this->_db->insert('groups', [ 'name' => 'Member', 'group_html' => 'Member', 'permissions' => '{"usercp.messaging":1,"usercp.signature":1,"usercp.nickname":1,"usercp.private_profile":1,"usercp.profile_banner":1}', - 'order' => 3 + 'order' => 3, ]); $this->_db->insert('groups', [ @@ -62,18 +66,19 @@ private function initialiseGroups(): void { 'group_username_color' => '#6c757d', 'permissions' => '{}', 'default_group' => true, - 'order' => 4 + 'order' => 4, ]); Settings::set('member_list_viewable_groups', json_encode([1, 2, 3, 4]), 'Members'); } - private function initialiseLanguages(): void { + private function initialiseLanguages(): void + { foreach (Language::LANGUAGES as $short_code => $meta) { $this->_db->insert('languages', [ 'name' => $meta['name'], 'short_code' => $short_code, - 'is_default' => (Session::get('default_language') == $short_code) ? 1 : 0 + 'is_default' => (Session::get('default_language') == $short_code) ? 1 : 0, ]); } @@ -81,7 +86,8 @@ private function initialiseLanguages(): void { $this->_cache->store('language', Session::get('default_language')); } - private function initialiseModules(): void { + private function initialiseModules(): void + { $this->_db->insert('modules', [ 'name' => 'Core', 'enabled' => true, @@ -111,23 +117,23 @@ private function initialiseModules(): void { $this->_cache->store('enabled_modules', [ [ 'name' => 'Core', - 'priority' => 1 + 'priority' => 1, ], [ 'name' => 'Forum', - 'priority' => 4 + 'priority' => 4, ], [ 'name' => 'Discord Integration', - 'priority' => 7 + 'priority' => 7, ], [ 'name' => 'Cookie Consent', - 'priority' => 10 + 'priority' => 10, ], [ 'name' => 'Members', - 'priority' => 13 + 'priority' => 13, ], ]); @@ -135,7 +141,8 @@ private function initialiseModules(): void { $this->_cache->store('module_forum', true); } - private function initialiseIntegrations(): void { + private function initialiseIntegrations(): void + { $this->_db->insert('integrations', [ 'name' => 'Minecraft', 'enabled' => true, @@ -148,11 +155,12 @@ private function initialiseIntegrations(): void { 'name' => 'Discord', 'enabled' => true, 'can_unlink' => true, - 'required' => false + 'required' => false, ]); } - private function initialiseReactions(): void { + private function initialiseReactions(): void + { $this->_db->insert('reactions', [ 'name' => 'Like', 'html' => '👍', @@ -197,7 +205,8 @@ private function initialiseReactions(): void { ]); } - private function initialiseSettings(): void { + private function initialiseSettings(): void + { Settings::set('registration_enabled', '1'); Settings::set('displaynames', '0'); Settings::set('uuid_linking', '1'); @@ -235,17 +244,17 @@ private function initialiseSettings(): void { $this->_db->insert('privacy_terms', [ 'name' => 'terms', - 'value' => '

    You agree to be bound by our website rules and any laws which may apply to this website and your participation.

    The website administration have the right to terminate your account at any time, delete any content you may have posted, and your IP address and any data you input to the website is recorded to assist the site staff with their moderation duties.

    The site administration have the right to change these terms and conditions, and any site rules, at any point without warning. Whilst you may be informed of any changes, it is your responsibility to check these terms and the rules at any point.

    ' + 'value' => '

    You agree to be bound by our website rules and any laws which may apply to this website and your participation.

    The website administration have the right to terminate your account at any time, delete any content you may have posted, and your IP address and any data you input to the website is recorded to assist the site staff with their moderation duties.

    The site administration have the right to change these terms and conditions, and any site rules, at any point without warning. Whilst you may be informed of any changes, it is your responsibility to check these terms and the rules at any point.

    ', ]); $this->_db->insert('privacy_terms', [ 'name' => 'cookies', - 'value' => 'What are cookies?
    Cookies are small files which are stored on your device by a website, unique to your web browser. The web browser will send these files to the website each time it communicates with the website.
    Cookies are used by this website for a variety of reasons which are outlined below.

    Necessary cookies
    Necessary cookies are required for this website to function. These are used by the website to maintain your session, allowing for you to submit any forms, log into the website amongst other essential behaviour. It is not possible to disable these within the website, however you can disable cookies altogether via your browser.

    Functional cookies
    Functional cookies allow for the website to work as you choose. For example, enabling the "Remember Me" option as you log in will create a functional cookie to automatically log you in on future visits.

    Analytical cookies
    Analytical cookies allow both this website, and any third party services used by this website, to collect non-personally identifiable data about the user. This allows us (the website staff) to continue to improve the user experience and understand how the website is used.

    Further information about cookies can be found online, including the ICO's website which contains useful links to further documentation about configuring your browser.

    Configuring cookie use
    By default, only necessary cookies are used by this website. However, some website functionality may be unavailable until the use of cookies has been opted into.
    You can opt into, or continue to disallow, the use of cookies using the cookie notice popup on this website. If you would like to update your preference, the cookie notice popup can be re-enabled by clicking the button below.' + 'value' => 'What are cookies?
    Cookies are small files which are stored on your device by a website, unique to your web browser. The web browser will send these files to the website each time it communicates with the website.
    Cookies are used by this website for a variety of reasons which are outlined below.

    Necessary cookies
    Necessary cookies are required for this website to function. These are used by the website to maintain your session, allowing for you to submit any forms, log into the website amongst other essential behaviour. It is not possible to disable these within the website, however you can disable cookies altogether via your browser.

    Functional cookies
    Functional cookies allow for the website to work as you choose. For example, enabling the "Remember Me" option as you log in will create a functional cookie to automatically log you in on future visits.

    Analytical cookies
    Analytical cookies allow both this website, and any third party services used by this website, to collect non-personally identifiable data about the user. This allows us (the website staff) to continue to improve the user experience and understand how the website is used.

    Further information about cookies can be found online, including the ICO's website which contains useful links to further documentation about configuring your browser.

    Configuring cookie use
    By default, only necessary cookies are used by this website. However, some website functionality may be unavailable until the use of cookies has been opted into.
    You can opt into, or continue to disallow, the use of cookies using the cookie notice popup on this website. If you would like to update your preference, the cookie notice popup can be re-enabled by clicking the button below.', ]); $this->_db->insert('privacy_terms', [ 'name' => 'privacy', - 'value' => 'The following privacy policy outlines how your data is used on our website.

    Data
    Basic non-identifiable information about your user on the website is collected; the majority of which is provided during registration, such as email addresses and usernames.
    In addition to this, IP addresses for registered users are stored within the system to aid with moderation duties. This includes spam prevention, and detecting alternative accounts.

    Accounts can be deleted by a site administrator upon request, which will remove all data relating to your user from our system.

    Cookies
    Cookies are used to store small pieces of non-identifiable information with your consent. In order to consent to the use of cookies, you must either close the cookie notice (as explained within the notice) or register on our website.
    Data stored by cookies include any recently viewed topic IDs, along with a unique, unidentifiable hash upon logging in and selecting "Remember Me" to automatically log you in next time you visit.' + 'value' => 'The following privacy policy outlines how your data is used on our website.

    Data
    Basic non-identifiable information about your user on the website is collected; the majority of which is provided during registration, such as email addresses and usernames.
    In addition to this, IP addresses for registered users are stored within the system to aid with moderation duties. This includes spam prevention, and detecting alternative accounts.

    Accounts can be deleted by a site administrator upon request, which will remove all data relating to your user from our system.

    Cookies
    Cookies are used to store small pieces of non-identifiable information with your consent. In order to consent to the use of cookies, you must either close the cookie notice (as explained within the notice) or register on our website.
    Data stored by cookies include any recently viewed topic IDs, along with a unique, unidentifiable hash upon logging in and selecting "Remember Me" to automatically log you in next time you visit.', ]); $nameless_terms = 'This website uses "Nameless" website software. The ' . @@ -257,11 +266,13 @@ private function initialiseSettings(): void { Settings::set('t_and_c', 'By registering on our website, you agree to the following:

    ' . $nameless_terms . '

    '); } - private function initialiseTasks(): void { + private function initialiseTasks(): void + { GenerateSitemap::schedule(new Language('core', 'en_UK')); } - private function initialiseTemplates(): void { + private function initialiseTemplates(): void + { $this->_db->insert('templates', [ 'name' => 'DefaultRevamp', 'enabled' => true, @@ -287,39 +298,41 @@ private function initialiseTemplates(): void { $this->_cache->store('banner_image', $config_path . '/uploads/template_banners/homepage_bg_trimmed.jpg'); } - private function initialiseWidgets(): void { + private function initialiseWidgets(): void + { $this->_db->insert('widgets', [ 'name' => 'Online Staff', 'enabled' => true, - 'pages' => '["index","forum"]' + 'pages' => '["index","forum"]', ]); $this->_db->insert('widgets', [ 'name' => 'Online Users', 'enabled' => true, - 'pages' => '["index","forum"]' + 'pages' => '["index","forum"]', ]); $this->_db->insert('widgets', [ 'name' => 'Statistics', 'enabled' => true, - 'pages' => '["index","forum"]' + 'pages' => '["index","forum"]', ]); $this->_cache->setCache('Core-widgets'); $this->_cache->store('enabled', [ 'Online Staff' => 1, 'Online Users' => 1, - 'Statistics' => 1 + 'Statistics' => 1, ]); } - private function initialiseForum() { + private function initialiseForum() + { $this->_db->insert('forums', [ 'forum_title' => 'Category', 'forum_description' => 'The first forum category!', 'forum_order' => 1, - 'forum_type' => 'category' + 'forum_type' => 'category', ]); $this->_db->insert('forums', [ @@ -328,7 +341,7 @@ private function initialiseForum() { 'forum_order' => 2, 'parent' => 1, 'forum_type' => 'forum', - 'news' => 1 + 'news' => 1, ]); $this->_db->insert('topics', [ @@ -338,14 +351,14 @@ private function initialiseForum() { 'topic_last_user' => 1, 'topic_date' => date('U'), 'topic_reply_date' => date('U'), - 'label' => null + 'label' => null, ]); $this->_db->insert('posts', [ 'forum_id' => 2, 'topic_id' => 1, 'post_creator' => 1, - 'post_content' => << <<<'POST'

    Welcome!

    To get started with NamelessMC, visit your StaffCP using the blue gear icon in the top right of your screen.

    If you need support, visit our Discord server: https://discord.gg/nameless

    @@ -375,7 +388,7 @@ private function initialiseForum() { 'edit_topic' => ($i == 0 ? 0 : 1), 'create_post' => ($i == 0 ? 0 : 1), 'view_other_topics' => true, - 'moderate' => (($i == 2 || $i == 3) ? 1 : 0) + 'moderate' => (($i == 2 || $i == 3) ? 1 : 0), ]); } } @@ -383,32 +396,32 @@ private function initialiseForum() { // Forum Labels $this->_db->insert('forums_labels', [ 'name' => 'Default', - 'html' => '{x}' + 'html' => '{x}', ]); $this->_db->insert('forums_labels', [ 'name' => 'Primary', - 'html' => '{x}' + 'html' => '{x}', ]); $this->_db->insert('forums_labels', [ 'name' => 'Success', - 'html' => '{x}' + 'html' => '{x}', ]); $this->_db->insert('forums_labels', [ 'name' => 'Info', - 'html' => '{x}' + 'html' => '{x}', ]); $this->_db->insert('forums_labels', [ 'name' => 'Warning', - 'html' => '{x}' + 'html' => '{x}', ]); $this->_db->insert('forums_labels', [ 'name' => 'Danger', - 'html' => '{x}' + 'html' => '{x}', ]); } } diff --git a/core/classes/Database/PhinxAdapter.php b/core/classes/Database/PhinxAdapter.php index e421ccc99b..fea7a6f2a6 100644 --- a/core/classes/Database/PhinxAdapter.php +++ b/core/classes/Database/PhinxAdapter.php @@ -1,16 +1,16 @@ count($missing), - 'extra' => count($extra) + 'extra' => count($extra), ]; } @@ -80,15 +81,15 @@ static function ($file_name) { } if ($missing_count > 0 || $extra_count > 0) { - die(); + die; } } /** * Runs any pending migrations. Used for installation and upgrades. Resource heavy, only call when needed. - * Logs output of Phinx to other-log.log file + * Logs output of Phinx to other-log.log file. * - * @param string $module Module name + * @param string $module Module name * @param ?string $migrationDir Migration directory to use * * @return string Output of the migration command from Phinx as if it was executed in the console. @@ -123,15 +124,14 @@ public static function migrate( /** * Rolls back migrations - * Logs output of Phinx to other-log.log file + * Logs output of Phinx to other-log.log file. * - * @param string $module Module name + * @param string $module Module name * @param string $migrationDir Migration directory to use - * @param int $since Version of earliest migration to rollback, default 0 for all - * - * @return string Output of the migration command from Phinx as if it was executed in the console. + * @param int $since Version of earliest migration to rollback, default 0 for all * * @throws Exception If unable to rollback + * @return string Output of the migration command from Phinx as if it was executed in the console. */ public static function rollback( string $module, @@ -168,5 +168,4 @@ public static function rollback( return $output; } - } diff --git a/core/classes/Database/QueryRecorder.php b/core/classes/Database/QueryRecorder.php index 7034cee875..6eda0d14cb 100644 --- a/core/classes/Database/QueryRecorder.php +++ b/core/classes/Database/QueryRecorder.php @@ -8,8 +8,8 @@ * @version 2.0.0-pr13 * @license MIT */ -class QueryRecorder extends Instanceable { - +class QueryRecorder extends Instanceable +{ private array $_query_stack = []; private int $_query_stack_num = 1; @@ -18,7 +18,8 @@ class QueryRecorder extends Instanceable { * * @return array SQL queries */ - public function getSqlStack(): array { + public function getSqlStack(): array + { $stack = array_reverse($this->_query_stack); // Compile queries - replace bound parameters with their values and syntax highlight @@ -35,10 +36,11 @@ public function getSqlStack(): array { /** * Add a query to the stack. * - * @param string $sql Raw SQL query executed - * @param array $params Bound parameters used in the query + * @param string $sql Raw SQL query executed + * @param array $params Bound parameters used in the query */ - public function pushQuery(string $sql, array $params): void { + public function pushQuery(string $sql, array $params): void + { if (!Debugging::canViewDetailedError()) { return; } @@ -60,7 +62,8 @@ public function pushQuery(string $sql, array $params): void { * * @return array debug_backtrace entry */ - private function lastReleventBacktrace(): array { + private function lastReleventBacktrace(): array + { $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); $current_file = $last_file = $backtrace[0]['file']; @@ -81,18 +84,18 @@ private function lastReleventBacktrace(): array { * Get a compiled SQL query with bound parameters replaced with their values * and syntax highlighted. * - * @param string $sql Raw SQL query - * @param array $params Bound parameters + * @param string $sql Raw SQL query + * @param array $params Bound parameters * @return string Compiled + syntax highlighted SQL query */ - private function compileQuery(string $sql, array $params): string { + private function compileQuery(string $sql, array $params): string + { $comp = ''; $split = explode(' ?', $sql); $i = 0; foreach ($split as $section) { - if ($section == '') { continue; } diff --git a/core/classes/Endpoints/EndpointBase.php b/core/classes/Endpoints/EndpointBase.php index 35d222b9a2..1614f5b2a4 100644 --- a/core/classes/Endpoints/EndpointBase.php +++ b/core/classes/Endpoints/EndpointBase.php @@ -7,8 +7,8 @@ * @version 2.0.0-pr13 * @license MIT */ -abstract class EndpointBase { - +abstract class EndpointBase +{ public const AUTH_TYPE_API_KEY = 'API Key'; public const AUTH_TYPE_NONE = 'None'; public const AUTH_TYPE_CUSTOM = 'Custom'; @@ -23,7 +23,8 @@ abstract class EndpointBase { * * @return string Endpoint's route. */ - final public function getRoute(): string { + final public function getRoute(): string + { return $this->_route; } @@ -32,7 +33,8 @@ final public function getRoute(): string { * * @return string Endpoint's modules name. */ - final public function getModule(): string { + final public function getModule(): string + { return $this->_module; } @@ -41,7 +43,8 @@ final public function getModule(): string { * * @return string Endpoint's description. */ - final public function getDescription(): string { + final public function getDescription(): string + { return $this->_description; } @@ -50,7 +53,8 @@ final public function getDescription(): string { * * @return string Endpoint's method. */ - final public function getMethod(): string { + final public function getMethod(): string + { return $this->_method; } @@ -61,7 +65,8 @@ final public function getMethod(): string { * * @return string The auth type. */ - final public function getAuthType(): string { + final public function getAuthType(): string + { switch (get_parent_class($this)) { case KeyAuthEndpoint::class: return self::AUTH_TYPE_API_KEY; @@ -76,11 +81,10 @@ final public function getAuthType(): string { * Determine if this request is authorized to use this Endpoint. * Default implementations: * - NoAuthEndpoint to return true - * - KeyAuthEndpoint to return true if the API key in header is valid + * - KeyAuthEndpoint to return true if the API key in header is valid. * - * @param Nameless2API $api Instance of Nameless2API. + * @param Nameless2API $api Instance of Nameless2API. * @return bool */ abstract public function isAuthorised(Nameless2API $api): bool; - } diff --git a/core/classes/Endpoints/Endpoints.php b/core/classes/Endpoints/Endpoints.php index b3615ccf3b..f61c2e13dc 100644 --- a/core/classes/Endpoints/Endpoints.php +++ b/core/classes/Endpoints/Endpoints.php @@ -1,5 +1,7 @@ _endpoints; } /** * Find an endpoint which matches this request and `execute()` it. * - * @param string $route Route to find endpoint for. - * @param string $method HTTP method to find endpoint for. - * @param Nameless2API $api Instance of api instance to provide the endpoint. + * @param string $route Route to find endpoint for. + * @param string $method HTTP method to find endpoint for. + * @param Nameless2API $api Instance of api instance to provide the endpoint. */ - public function handle(string $route, string $method, Nameless2API $api): void { + public function handle(string $route, string $method, Nameless2API $api): void + { $available_methods = []; $matched_endpoint = null; @@ -60,7 +64,7 @@ public function handle(string $route, string $method, Nameless2API $api): void { $reflection = new ReflectionMethod($endpoint, 'execute'); if ($reflection->getNumberOfParameters() !== (count($vars) + 1)) { - throw new InvalidArgumentException("Endpoint's 'execute()' method must take " . (count($vars) + 1) . " arguments. Endpoint: " . $endpoint->getRoute()); + throw new InvalidArgumentException("Endpoint's 'execute()' method must take " . (count($vars) + 1) . ' arguments. Endpoint: ' . $endpoint->getRoute()); } $endpoint->execute( @@ -69,6 +73,7 @@ public function handle(string $route, string $method, Nameless2API $api): void { return $this::transform($api, $type, $value); }, array_keys($vars), $vars) ); + return; } } @@ -88,12 +93,14 @@ public function handle(string $route, string $method, Nameless2API $api): void { * * @param string $path Path to scan from. */ - public function loadEndpoints(string $path): void { + public function loadEndpoints(string $path): void + { $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS)); foreach ($rii as $file) { if ($file->isDir()) { $this->loadEndpoints($file); + return; } diff --git a/core/classes/Endpoints/KeyAuthEndpoint.php b/core/classes/Endpoints/KeyAuthEndpoint.php index 436b73bbfa..db5fbcfb98 100644 --- a/core/classes/Endpoints/KeyAuthEndpoint.php +++ b/core/classes/Endpoints/KeyAuthEndpoint.php @@ -1,5 +1,7 @@ getRoute()); $endpoint_vars = []; @@ -41,7 +42,7 @@ private function matchRoute(EndpointBase $endpoint, string $route) { foreach ($route_parts as $i => $part) { if (array_key_exists($i, $endpoint_vars)) { $route_vars[$endpoint_vars[$i]] = $part; - } else if ($endpoint_parts[$i] !== $part) { + } elseif ($endpoint_parts[$i] !== $part) { return false; } } @@ -49,11 +50,13 @@ private function matchRoute(EndpointBase $endpoint, string $route) { return $route_vars; } - private function isVariable(string $type) : bool { + private function isVariable(string $type): bool + { return str_starts_with($type, '{') && str_ends_with($type, '}'); } - private function stripVariable(string $type) : string { + private function stripVariable(string $type): string + { return substr($type, 1, -1); } } diff --git a/core/classes/Endpoints/NoAuthEndpoint.php b/core/classes/Endpoints/NoAuthEndpoint.php index a01de2129b..f3e3035f3c 100644 --- a/core/classes/Endpoints/NoAuthEndpoint.php +++ b/core/classes/Endpoints/NoAuthEndpoint.php @@ -7,9 +7,10 @@ * @version 2.0.0-pr13 * @license MIT */ -class NoAuthEndpoint extends EndpointBase { - - final public function isAuthorised(Nameless2API $api): bool { +class NoAuthEndpoint extends EndpointBase +{ + final public function isAuthorised(Nameless2API $api): bool + { return true; } } diff --git a/core/classes/Events/AbstractEvent.php b/core/classes/Events/AbstractEvent.php index 63f2d7b29f..d346d349d0 100644 --- a/core/classes/Events/AbstractEvent.php +++ b/core/classes/Events/AbstractEvent.php @@ -7,15 +7,16 @@ * @version 2.2.0 * @license MIT */ -abstract class AbstractEvent { - +abstract class AbstractEvent +{ /** * Convert the class name to the event name. - * Example: UserDeletedEvent -> userDeleted + * Example: UserDeletedEvent -> userDeleted. * * @return string The name of the subclass, without the "Event" suffix */ - public static function name(): string { + public static function name(): string + { return lcfirst(str_replace('Event', '', static::class)); } @@ -31,7 +32,8 @@ abstract public static function description(): string; * * @return bool Whether to return the response after executing the event */ - public static function return(): bool { + public static function return(): bool + { return false; } @@ -40,7 +42,8 @@ public static function return(): bool { * * @return bool Whether to hide this hook from users in the StaffCP */ - public static function internal(): bool { + public static function internal(): bool + { return false; } @@ -50,7 +53,8 @@ public static function internal(): bool { * * @return array The parameters of the event */ - final public function params(): array { + final public function params(): array + { return get_object_vars($this); } @@ -58,11 +62,12 @@ final public function params(): array { * Helper method to dispatch an event, equivalent to * ```php * EventHandler::executeEvent(new EventClass(...)); - * ``` + * ```. * * @return array|null The response from the event, or null if the event is not returning a response */ - final public static function dispatch(): ?array { + final public static function dispatch(): ?array + { return EventHandler::executeEvent( self::fromArray(func_get_args()) ); @@ -71,10 +76,11 @@ final public static function dispatch(): ?array { /** * Create an instance of the event from an array of parameters. * - * @param array $params The parameters to pass to the event + * @param array $params The parameters to pass to the event * @return AbstractEvent The event instance */ - final public static function fromArray(array $params): AbstractEvent { + final public static function fromArray(array $params): AbstractEvent + { /** @phpstan-ignore-next-line */ return new static(...$params); } diff --git a/core/classes/Events/Cancellable.php b/core/classes/Events/Cancellable.php index 13ab369f63..2b7c60be78 100644 --- a/core/classes/Events/Cancellable.php +++ b/core/classes/Events/Cancellable.php @@ -1,20 +1,23 @@ _cancelled = $cancelled; $this->_reason = $reason; } - public function isCancelled(): bool { + public function isCancelled(): bool + { return $this->_cancelled; } - public function getCancelledReason(): string { + public function getCancelledReason(): string + { return $this->_reason; } -} \ No newline at end of file +} diff --git a/core/classes/Events/DiscordDispatchable.php b/core/classes/Events/DiscordDispatchable.php index 56dcccb17d..ef56418abc 100644 --- a/core/classes/Events/DiscordDispatchable.php +++ b/core/classes/Events/DiscordDispatchable.php @@ -7,13 +7,12 @@ * @version 2.2.0 * @license MIT */ -interface DiscordDispatchable { - +interface DiscordDispatchable +{ /** * Build a Discord webhook to represent the event as a Discord embed. * * @return DiscordWebhookBuilder The webhook builder to send the event as an embed */ public function toDiscordWebhook(): DiscordWebhookBuilder; - } diff --git a/core/classes/Events/DiscordEmbed.php b/core/classes/Events/DiscordEmbed.php index a9a8723fef..1f483344e0 100644 --- a/core/classes/Events/DiscordEmbed.php +++ b/core/classes/Events/DiscordEmbed.php @@ -7,11 +7,11 @@ * @version 2.2.0 * @license MIT */ -class DiscordEmbed { - +class DiscordEmbed +{ private ?string $_title = null; private ?array $_author = null; - /** @var float|int|null $_color */ + /** @var float|int|null */ private $_color = null; private ?string $_url = null; private ?string $_description = null; @@ -20,20 +20,25 @@ class DiscordEmbed { private ?array $_thumbnail = null; private ?array $_footer = null; - public function getTitle(): ?string { + public function getTitle(): ?string + { return $this->_title; } - public function setTitle(?string $title): self { + public function setTitle(?string $title): self + { $this->_title = $title; + return $this; } - public function getAuthor(): ?array { + public function getAuthor(): ?array + { return $this->_author; } - public function setAuthor(string $name, ?string $icon_url = null, ?string $url = null): self { + public function setAuthor(string $name, ?string $icon_url = null, ?string $url = null): self + { $this->_author = array_filter([ 'name' => $name, 'icon_url' => $icon_url, @@ -43,42 +48,53 @@ public function setAuthor(string $name, ?string $icon_url = null, ?string $url = return $this; } - public function getColor(): ?int { + public function getColor(): ?int + { return $this->_color; } - public function setColor($color): self { + public function setColor($color): self + { if (is_string($color)) { $color = hexdec($color); } $this->_color = $color; + return $this; } - public function getUrl(): ?string { + public function getUrl(): ?string + { return $this->_url; } - public function setUrl(?string $url): self { + public function setUrl(?string $url): self + { $this->_url = $url; + return $this; } - public function getDescription(): ?string { + public function getDescription(): ?string + { return $this->_description; } - public function setDescription(string $description): self { + public function setDescription(string $description): self + { $this->_description = $description; + return $this; } - public function getFields(): ?array { + public function getFields(): ?array + { return $this->_fields; } - public function addField(string $name, string $value, bool $inline = false): self { + public function addField(string $name, string $value, bool $inline = false): self + { if ($this->_fields === null) { $this->_fields = []; } @@ -88,40 +104,51 @@ public function addField(string $name, string $value, bool $inline = false): sel 'value' => $value, 'inline' => $inline, ]; + return $this; } - public function getImage(): ?array { + public function getImage(): ?array + { return $this->_image; } - public function setImage(string $image_url): self { + public function setImage(string $image_url): self + { $this->_image = ['url' => $image_url]; + return $this; } - public function getThumbnail(): ?array { + public function getThumbnail(): ?array + { return $this->_thumbnail; } - public function setThumbnail(string $thumbnail_url): self { + public function setThumbnail(string $thumbnail_url): self + { $this->_thumbnail = ['url' => $thumbnail_url]; + return $this; } - public function getFooter(): ?array { + public function getFooter(): ?array + { return $this->_footer; } - public function setFooter(?string $footer_text, ?string $footer_icon_url = null): self { + public function setFooter(?string $footer_text, ?string $footer_icon_url = null): self + { $this->_footer = [ 'text' => $footer_text, 'icon_url' => $footer_icon_url, ]; + return $this; } - public function toArray(): array { + public function toArray(): array + { return array_filter([ 'title' => $this->_title, 'author' => $this->_author, diff --git a/core/classes/Events/DiscordWebhookBuilder.php b/core/classes/Events/DiscordWebhookBuilder.php index 2f53b4b93c..52a9b34245 100644 --- a/core/classes/Events/DiscordWebhookBuilder.php +++ b/core/classes/Events/DiscordWebhookBuilder.php @@ -7,61 +7,74 @@ * @version 2.2.0 * @license MIT */ -class DiscordWebhookBuilder { - +class DiscordWebhookBuilder +{ private ?string $_username = null; private ?string $_avatar_url = null; private ?string $_content = null; /** @var DiscordEmbed[] */ private ?array $_embeds = null; - private function __construct() { + private function __construct() + { // ... } - public static function make(): self { + public static function make(): self + { return new self(); } - public function getUsername(): ?string { + public function getUsername(): ?string + { return $this->_username; } - public function setUsername(?string $username): self { + public function setUsername(?string $username): self + { $this->_username = $username; + return $this; } - public function getAvatarUrl(): ?string { + public function getAvatarUrl(): ?string + { return $this->_avatar_url; } - public function setAvatarUrl(?string $avatar_url): self { + public function setAvatarUrl(?string $avatar_url): self + { $this->_avatar_url = $avatar_url; + return $this; } - public function getContent(): ?string { + public function getContent(): ?string + { return $this->_content; } - public function setContent(string $content): self { + public function setContent(string $content): self + { $this->_content = $content; + return $this; } /** * @return DiscordEmbed[]|null */ - public function getEmbeds(): ?array { + public function getEmbeds(): ?array + { return $this->_embeds; } /** - * @param Closure(DiscordEmbed): DiscordEmbed $closure + * @param Closure(DiscordEmbed): DiscordEmbed $closure * @return $this */ - public function addEmbed(Closure $closure): self { + public function addEmbed(Closure $closure): self + { if ($this->_embeds === null) { $this->_embeds = []; } @@ -72,10 +85,12 @@ public function addEmbed(Closure $closure): self { } $this->_embeds[] = $embed; + return $this; } - public function toArray(): array { + public function toArray(): array + { return array_filter([ 'username' => $this->_username, 'avatar_url' => $this->_avatar_url, diff --git a/core/classes/Events/EventCollector.php b/core/classes/Events/EventCollector.php index 6402e4111a..ccc0c24162 100644 --- a/core/classes/Events/EventCollector.php +++ b/core/classes/Events/EventCollector.php @@ -13,27 +13,30 @@ * @version 2.2.0 * @license MIT */ -class EventCollector extends DataCollector implements Renderable, AssetProvider { - +class EventCollector extends DataCollector implements Renderable, AssetProvider +{ private array $_events = []; private static EventCollector $_instance; - public static function getInstance(): EventCollector { + public static function getInstance(): EventCollector + { return self::$_instance ??= new self(); } - public function called(string $event, array $params): void { + public function called(string $event, array $params): void + { $this->_events[] = [ 'event' => $event, - 'params' => $params + 'params' => $params, ]; } - public function collect(): array { + public function collect(): array + { $events = []; foreach ($this->_events as $i => $event) { - ++$i; + $i++; $events["{$event['event']} #$i"] = [ $this->getVarDumper()->renderVar($event['params']), ]; @@ -45,11 +48,13 @@ public function collect(): array { ]; } - public function getName(): string { + public function getName(): string + { return 'events'; } - public function getAssets(): array { + public function getAssets(): array + { return $this->getVarDumper()->getAssets(); } diff --git a/core/classes/Events/EventHandler.php b/core/classes/Events/EventHandler.php index 700d969988..4281926182 100644 --- a/core/classes/Events/EventHandler.php +++ b/core/classes/Events/EventHandler.php @@ -8,8 +8,8 @@ * @version 2.1.0 * @license MIT */ -class EventHandler { - +class EventHandler +{ private static array $_events = []; private static array $_webhooks = []; @@ -18,7 +18,8 @@ class EventHandler { * * @param array $webhooks Array of webhooks to register */ - public static function registerWebhooks(array $webhooks): void { + public static function registerWebhooks(array $webhooks): void + { self::$_webhooks = $webhooks; } @@ -26,11 +27,11 @@ public static function registerWebhooks(array $webhooks): void { * Register an event. * This must be called in the module's constructor. * - * @param class-string|string $event Name of event to add. - * @param string $description Human readable description. - * @param array $params Array of available parameters and their descriptions. - * @param bool $return Whether to return $params afterwards - * @param bool $internal Whether to hide this hook from users in the StaffCP (ie for internal events) + * @param class-string|string $event Name of event to add. + * @param string $description Human readable description. + * @param array $params Array of available parameters and their descriptions. + * @param bool $return Whether to return $params afterwards + * @param bool $internal Whether to hide this hook from users in the StaffCP (ie for internal events) */ public static function registerEvent( string $event, @@ -39,7 +40,7 @@ public static function registerEvent( bool $return = false, bool $internal = false ): void { - if (class_exists($event) && is_subclass_of($event, AbstractEvent::class)) { + if (class_exists($event) && is_subclass_of($event, AbstractEvent::class)) { $class_name = $event; $name = $event::name(); // We lazy load descriptions for class-based events to avoid loading new Language instances unnecessarily @@ -63,6 +64,7 @@ public static function registerEvent( 'params' => $params, 'listeners' => self::$_events[$name]['listeners'], ]; + return; } @@ -80,11 +82,12 @@ public static function registerEvent( * Register an event listener for a module. * This must be called in the module's constructor. * - * @param string $event Event name to listen to. + * @param string $event Event name to listen to. * @param callable|class-string $callback Listener callback to execute when event is executed. If class name is provided, we will assume there is a static "execute" method on the class. - * @param int $priority Execution priority - higher gets executed first + * @param int $priority Execution priority - higher gets executed first */ - public static function registerListener(string $event, $callback, int $priority = 10): void { + public static function registerListener(string $event, $callback, int $priority = 10): void + { $name = class_exists($event) && is_subclass_of($event, AbstractEvent::class) ? $event::name() : $event; @@ -107,11 +110,12 @@ public static function registerListener(string $event, $callback, int $priority /** * Execute an event. * - * @param AbstractEvent|string $event Event name to call, or instance of event to execute. - * @param array $params Params to pass to the event's function, not required when a class-based event is used. - * @return array|null Response of lissteners, can be any type or null + * @param AbstractEvent|string $event Event name to call, or instance of event to execute. + * @param array $params Params to pass to the event's function, not required when a class-based event is used. + * @return array|null Response of lissteners, can be any type or null */ - public static function executeEvent($event, array $params = []): ?array { + public static function executeEvent($event, array $params = []): ?array + { if ($event instanceof AbstractEvent) { $name = $event::name(); $params = $event->params(); @@ -135,6 +139,7 @@ public static function executeEvent($event, array $params = []): ?array { } catch (Error $error) { if (str_contains($error->getMessage(), 'Unknown named parameter')) { $parameter = str_replace('Unknown named parameter ', '', $error->getMessage()); + throw new InvalidArgumentException("Unknown parameter $parameter array passed to event '$name' executor"); } @@ -157,7 +162,7 @@ public static function executeEvent($event, array $params = []): ?array { if (isset(self::$_events[$name]['listeners'])) { $listeners = self::$_events[$name]['listeners']; - usort($listeners, static function($a, $b) { + usort($listeners, static function ($a, $b) { return $b['priority'] <=> $a['priority']; }); @@ -207,7 +212,8 @@ public static function executeEvent($event, array $params = []): ?array { * * @return array List of all currently registered events */ - public static function getEvents(bool $showInternal = false): array { + public static function getEvents(bool $showInternal = false): array + { $return = []; foreach (self::$_events as $name => $meta) { @@ -239,7 +245,8 @@ public static function getEvents(bool $showInternal = false): array { * @param string $event Name of event to get data for. * @returns array Event data. */ - public static function getEvent(string $event): array { + public static function getEvent(string $event): array + { if (!isset(self::$_events[$event])) { throw new InvalidArgumentException("Invalid event name: $event"); } @@ -252,17 +259,19 @@ public static function getEvent(string $event): array { * Example: `function (UserRegisteredEvent $event) {}` should be passed an event object, * whereas `function (array $params) {}` should be passed an array. * - * @param callable $callback Callback to check. - * @return bool Whether the callback should be passed an event object or an array. + * @param callable $callback Callback to check. * @throws ReflectionException If the callback is not a valid callable. + * @return bool Whether the callback should be passed an event object or an array. */ - private static function shouldPassEventObject(callable $callback): bool { + private static function shouldPassEventObject(callable $callback): bool + { // We need to convert [ClassName::class, 'method'] arrays to closures, and "ClassName::method" strings to closures. if (is_array($callback) || is_string($callback)) { $callback = Closure::fromCallable($callback); } $reflection = new ReflectionFunction($callback); $param_type = $reflection->getParameters()[0]->getType(); + return !(!$param_type || $param_type->getName() === 'array'); } } diff --git a/core/classes/Events/HasWebhookParams.php b/core/classes/Events/HasWebhookParams.php index 0569224bcf..9982f254e0 100644 --- a/core/classes/Events/HasWebhookParams.php +++ b/core/classes/Events/HasWebhookParams.php @@ -7,11 +7,10 @@ * @version 2.2.0 * @license MIT */ -interface HasWebhookParams { - +interface HasWebhookParams +{ /** * @return array Array of parameters to send to the webhook */ public function webhookParams(): array; - } diff --git a/core/classes/Events/HookBase.php b/core/classes/Events/HookBase.php index 35136acf25..29d64cb21f 100644 --- a/core/classes/Events/HookBase.php +++ b/core/classes/Events/HookBase.php @@ -1,23 +1,24 @@ getColumnName(), $this->getColumnNames())) { throw new RuntimeException("GroupSyncInjector column name {$injector->getColumnName()} already taken."); } @@ -33,7 +34,8 @@ public function registerInjector(GroupSyncInjector $injector): void { * * @return string[] All column names */ - public function getColumnNames(): array { + public function getColumnNames(): array + { return array_map(static function (GroupSyncInjector $injector) { return $injector->getColumnName(); }, $this->_injectors); @@ -45,7 +47,8 @@ public function getColumnNames(): array { * * @param GroupSyncInjector $injector Injector to add column for. */ - public function registerInjectorColumn(GroupSyncInjector $injector): void { + public function registerInjectorColumn(GroupSyncInjector $injector): void + { DB::getInstance()->addColumn('group_sync', $injector->getColumnName(), "{$injector->getColumnType()} NULL DEFAULT NULL"); } @@ -54,7 +57,8 @@ public function registerInjectorColumn(GroupSyncInjector $injector): void { * * @return GroupSyncInjector[] Registered injectors */ - public function getInjectors(): iterable { + public function getInjectors(): iterable + { return $this->_injectors; } @@ -62,14 +66,16 @@ public function getInjectors(): iterable { * Create a new `Validate` instance and add the injector defined * rules and messages to it. * - * @param array $source Input array to validate, often `$_POST` + * @param array $source Input array to validate, often `$_POST` * @param Language $language Language to use for error messages * * @return Validate New `Validate` instance */ - public function makeValidator(array $source, Language $language): Validate { + public function makeValidator(array $source, Language $language): Validate + { return Validate::check( - $source, $this->compileValidatorRules() + $source, + $this->compileValidatorRules() )->messages( $this->compileValidatorMessages($language) ); @@ -81,7 +87,8 @@ public function makeValidator(array $source, Language $language): Validate { * * @return array> Array of each enabled injectors array of rules */ - private function compileValidatorRules(): array { + private function compileValidatorRules(): array + { $rules = []; foreach ($this->getEnabledInjectors() as $injector) { @@ -103,7 +110,8 @@ private function compileValidatorRules(): array { * * @return GroupSyncInjector[] Enabled injectors */ - public function getEnabledInjectors(): iterable { + public function getEnabledInjectors(): iterable + { if (!isset($this->_enabled_injectors)) { $this->_enabled_injectors = []; @@ -126,7 +134,8 @@ public function getEnabledInjectors(): iterable { * * @return array> */ - private function compileValidatorMessages(Language $language): array { + private function compileValidatorMessages(Language $language): array + { $messages = []; foreach ($this->getEnabledInjectors() as $column_name => $injector) { @@ -140,13 +149,14 @@ private function compileValidatorMessages(Language $language): array { * Execute respective `addGroup()` or `removeGroup()` function on each of the injectors * synced to the changed group. * - * @param User $user NamelessMC user to apply changes to + * @param User $user NamelessMC user to apply changes to * @param string $sending_injector_class Class name of injector broadcasting this change - * @param array $group_ids Array of Group IDs native to the sending injector which were added/removed to the user + * @param array $group_ids Array of Group IDs native to the sending injector which were added/removed to the user * * @return array Array of logs of changed groups */ - public function broadcastChange(User $user, string $sending_injector_class, array $group_ids): array { + public function broadcastChange(User $user, string $sending_injector_class, array $group_ids): array + { $sending_injector = $this->getInjectorByClass($sending_injector_class); if ($sending_injector === null) { @@ -175,9 +185,7 @@ public function broadcastChange(User $user, string $sending_injector_class, arra $batched_changes = []; foreach ($rules as $rule) { - foreach ($this->getEnabledInjectors() as $injector) { - if ($injector == $sending_injector) { continue; } @@ -281,9 +289,10 @@ public function broadcastChange(User $user, string $sending_injector_class, arra * @param string $class Class name to get injector from * * @return GroupSyncInjector|null Instance of injector, null if it doesn't exist - * or isn't enabled + * or isn't enabled */ - public function getInjectorByClass(string $class): ?GroupSyncInjector { + public function getInjectorByClass(string $class): ?GroupSyncInjector + { foreach ($this->getEnabledInjectors() as $injector) { if ($injector instanceof $class) { return $injector; diff --git a/core/classes/Integrations/IntegrationBase.php b/core/classes/Integrations/IntegrationBase.php index 0da1b893e3..1b695fd17c 100644 --- a/core/classes/Integrations/IntegrationBase.php +++ b/core/classes/Integrations/IntegrationBase.php @@ -7,9 +7,8 @@ * @version 2.1.0 * @license MIT */ - -abstract class IntegrationBase { - +abstract class IntegrationBase +{ private DB $_db; private IntegrationData $_data; protected string $_icon; @@ -20,7 +19,8 @@ abstract class IntegrationBase { protected string $_name; protected ?int $_order; - public function __construct() { + public function __construct() + { $this->_db = DB::getInstance(); $integration = $this->_db->query('SELECT * FROM nl2_integrations WHERE name = ?', [$this->_name]); @@ -32,7 +32,7 @@ public function __construct() { } else { // Register integration to database $this->_db->query('INSERT INTO nl2_integrations (name) VALUES (?)', [ - $this->_name + $this->_name, ]); $integration = $this->_db->query('SELECT * FROM nl2_integrations WHERE name = ?', [$this->_name])->first(); @@ -47,7 +47,8 @@ public function __construct() { * * @return string Name of integration. */ - public function getName(): string { + public function getName(): string + { return $this->_name; } @@ -56,7 +57,8 @@ public function getName(): string { * * @return string Icon of integration. */ - public function getIcon(): string { + public function getIcon(): string + { return $this->_icon; } @@ -65,16 +67,18 @@ public function getIcon(): string { * * @return string Integration settings path. */ - public function getSettings(): ?string { + public function getSettings(): ?string + { return $this->_settings; } /** - * Get if this integration is enabled + * Get if this integration is enabled. * * @return bool Check if integration is enabled */ - public function isEnabled(): bool { + public function isEnabled(): bool + { return $this->data()->enabled; } @@ -83,7 +87,8 @@ public function isEnabled(): bool { * * @return int Display order of integration. */ - public function getOrder(): ?int { + public function getOrder(): ?int + { return $this->_order; } @@ -92,34 +97,38 @@ public function getOrder(): ?int { * * @return IntegrationData This integration's data. */ - public function data(): IntegrationData { + public function data(): IntegrationData + { return $this->_data; } /** - * Add an error to the errors array + * Add an error to the errors array. * * @param string $error The error message */ - public function addError(string $error): void { + public function addError(string $error): void + { $this->_errors[] = $error; } /** - * Get any errors from the functions given by this integration + * Get any errors from the functions given by this integration. * * @return array Any errors */ - public function getErrors(): array { + public function getErrors(): array + { return $this->_errors; } /** - * Get language + * Get language. * * @return Language Get language */ - public function getLanguage(): Language { + public function getLanguage(): Language + { return $this->_language; } @@ -128,35 +137,36 @@ public function getLanguage(): Language { * * @return bool Whether to allow linking with this integration */ - public function allowLinking(): bool { + public function allowLinking(): bool + { return true; } /** - * Called when user wants to link their account from user connections page, Does not need to be verified + * Called when user wants to link their account from user connections page, Does not need to be verified. */ abstract public function onLinkRequest(User $user); /** - * Called when user wants to continue to verify their integration user from connections page + * Called when user wants to continue to verify their integration user from connections page. */ abstract public function onVerifyRequest(User $user); /** - * Called when user wants to unlink their integration user from connections page + * Called when user wants to unlink their integration user from connections page. */ abstract public function onUnlinkRequest(User $user); /** - * Called when the user have successfully validated the ownership of the account + * Called when the user have successfully validated the ownership of the account. */ abstract public function onSuccessfulVerification(IntegrationUser $integrationUser); /** * Validate username when it being linked or updated. * - * @param string $username The username value to validate. - * @param int $integration_user_id The integration user id to ignore during duplicate check. + * @param string $username The username value to validate. + * @param int $integration_user_id The integration user id to ignore during duplicate check. * * @return bool Whether this validation passed or not. */ @@ -165,30 +175,30 @@ abstract public function validateUsername(string $username, int $integration_use /** * Validate identifier when it being linked or updated. * - * @param string $identifier The identifier value to validate. - * @param int $integration_user_id The integration user id to ignore during duplicate check. + * @param string $identifier The identifier value to validate. + * @param int $integration_user_id The integration user id to ignore during duplicate check. * * @return bool Whether this validation passed or not. */ abstract public function validateIdentifier(string $identifier, int $integration_user_id = 0): bool; /** - * Called when register page being loaded + * Called when register page being loaded. */ abstract public function onRegistrationPageLoad(Fields $fields); /** - * Called before registration validation + * Called before registration validation. */ abstract public function beforeRegistrationValidation(Validate $validate); /** - * Called after registration validation + * Called after registration validation. */ abstract public function afterRegistrationValidation(); /** - * Called when user is successfully registered + * Called when user is successfully registered. */ abstract public function successfulRegistration(User $user); diff --git a/core/classes/Integrations/IntegrationUser.php b/core/classes/Integrations/IntegrationUser.php index a9a3ca8845..60e32b9d40 100644 --- a/core/classes/Integrations/IntegrationUser.php +++ b/core/classes/Integrations/IntegrationUser.php @@ -1,20 +1,21 @@ _db = DB::getInstance(); $this->_integration = $integration; @@ -25,27 +26,29 @@ public function __construct(IntegrationBase $integration, string $value = null, if ($data->count()) { $this->_data = new IntegrationUserData($data->first()); } - } else if ($query_data) { + } elseif ($query_data) { // Load data from existing query. $this->_data = new IntegrationUserData($query_data); } } /** - * Get the integration + * Get the integration. * * @return IntegrationBase Integration type for this user */ - public function getIntegration(): IntegrationBase { + public function getIntegration(): IntegrationBase + { return $this->_integration; } /** - * Get the NamelessMC User that belong to this integration user + * Get the NamelessMC User that belong to this integration user. * * @return User NamelessMC User that belong to this integration user */ - public function getUser(): User { + public function getUser(): User + { return $this->_user ??= new User($this->data()->user_id); } @@ -54,7 +57,8 @@ public function getUser(): User { * * @return IntegrationUserData This integration user data. */ - public function data(): IntegrationUserData { + public function data(): IntegrationUserData + { return $this->_data; } @@ -63,8 +67,9 @@ public function data(): IntegrationUserData { * * @return bool Whether the user exists (has data) or not. */ - public function exists(): bool { - return (!empty($this->_data)); + public function exists(): bool + { + return !empty($this->_data); } /** @@ -72,17 +77,19 @@ public function exists(): bool { * * @return bool Whether this integration user has been verified. */ - public function isVerified(): bool { + public function isVerified(): bool + { return $this->data()->verified; } /** * Update integration user data in the database. * - * @param array $fields Column names and values to update. + * @param array $fields Column names and values to update. * @throws Exception */ - public function update(array $fields = []): void { + public function update(array $fields = []): void + { if (!$this->_db->update('users_integrations', $this->data()->id, $fields)) { throw new RuntimeException('There was a problem updating integration user.'); } @@ -91,22 +98,24 @@ public function update(array $fields = []): void { /** * Save a new user linked to a specific integration. * - * @param User $user The user to link + * @param User $user The user to link * @param string|null $identifier The id of the integration account - * @param string|null $username The username of the integration account - * @param bool $verified Verified the ownership of the integration account - * @param string|null $code (optional) The verification code to verify the ownership + * @param string|null $username The username of the integration account + * @param bool $verified Verified the ownership of the integration account + * @param string|null $code (optional) The verification code to verify the ownership */ - public function linkIntegration(User $user, ?string $identifier, ?string $username, bool $verified = false, string $code = null): void { + public function linkIntegration(User $user, ?string $identifier, ?string $username, bool $verified = false, string $code = null): void + { $this->_db->query( - 'INSERT INTO nl2_users_integrations (user_id, integration_id, identifier, username, verified, date, code) VALUES (?, ?, ?, ?, ?, ?, ?)', [ + 'INSERT INTO nl2_users_integrations (user_id, integration_id, identifier, username, verified, date, code) VALUES (?, ?, ?, ?, ?, ?, ?)', + [ $user->data()->id, $this->_integration->data()->id, Output::getClean($identifier), Output::getClean($username), $verified ? 1 : 0, date('U'), - $code + $code, ] ); @@ -119,12 +128,13 @@ public function linkIntegration(User $user, ?string $identifier, ?string $userna } /** - * Verify user integration + * Verify user integration. */ - public function verifyIntegration(): void { + public function verifyIntegration(): void + { $this->update([ 'verified' => true, - 'code' => null + 'code' => null, ]); $this->_integration->onSuccessfulVerification($this); @@ -137,11 +147,13 @@ public function verifyIntegration(): void { /** * Delete integration user data. */ - public function unlinkIntegration(): void { + public function unlinkIntegration(): void + { $this->_db->query( - 'DELETE FROM nl2_users_integrations WHERE user_id = ? AND integration_id = ?', [ + 'DELETE FROM nl2_users_integrations WHERE user_id = ? AND integration_id = ?', + [ $this->data()->user_id, - $this->_integration->data()->id + $this->_integration->data()->id, ] ); diff --git a/core/classes/Integrations/Integrations.php b/core/classes/Integrations/Integrations.php index 22f2134fdc..ded7a162e2 100644 --- a/core/classes/Integrations/Integrations.php +++ b/core/classes/Integrations/Integrations.php @@ -1,16 +1,16 @@ _integrations[$integration->getName()] = $integration; } @@ -30,7 +31,8 @@ public function registerIntegration(IntegrationBase $integration): void { * * @return IntegrationBase|null Instance of integration with same name, null if it doesnt exist. */ - public function getIntegration(string $name): ?IntegrationBase { + public function getIntegration(string $name): ?IntegrationBase + { foreach ($this->_integrations as $integration) { if (strcasecmp($name, $integration->getName()) == 0) { return $integration; @@ -45,7 +47,8 @@ public function getIntegration(string $name): ?IntegrationBase { * * @return IntegrationBase[] List of integrations. */ - public function getAll(): iterable { + public function getAll(): iterable + { $integrations = $this->_integrations; uasort($integrations, static function (IntegrationBase $a, IntegrationBase $b) { @@ -60,7 +63,8 @@ public function getAll(): iterable { * * @return IntegrationBase[] List of integrations. */ - public function getEnabledIntegrations(): iterable { + public function getEnabledIntegrations(): iterable + { $integrations = $this->_integrations; $enabled_integrations = []; diff --git a/core/classes/Minecraft/ExternalMCQuery.php b/core/classes/Minecraft/ExternalMCQuery.php index 4259a606b8..247ae740a0 100644 --- a/core/classes/Minecraft/ExternalMCQuery.php +++ b/core/classes/Minecraft/ExternalMCQuery.php @@ -7,17 +7,18 @@ * @version 2.0.0-pr13 * @license MIT */ -class ExternalMCQuery { - +class ExternalMCQuery +{ /** * Basic server query. * - * @param string $ip IP to query - * @param int $port Port to query, `25565` by default. - * @param bool $bedrock Whether this is a Bedrock server or not. + * @param string $ip IP to query + * @param int $port Port to query, `25565` by default. + * @param bool $bedrock Whether this is a Bedrock server or not. * @return object|false Query result, false on failure. */ - public static function query(string $ip, int $port = 25565, bool $bedrock = false) { + public static function query(string $ip, int $port = 25565, bool $bedrock = false) + { $client = HttpClient::get('https://api.namelessmc.com/api/' . ($bedrock ? 'bedrock' : 'server') . '/' . $ip . '/' . $port); if (!$client->hasError()) { @@ -30,11 +31,12 @@ public static function query(string $ip, int $port = 25565, bool $bedrock = fals /** * Get a server's favicon. * - * @param string $ip Server's IP. - * @param bool $bedrock Whether this is a Bedrock server or not. + * @param string $ip Server's IP. + * @param bool $bedrock Whether this is a Bedrock server or not. * @return string|false Server's favicon, false on failure. */ - public static function getFavicon(string $ip, bool $bedrock = false) { + public static function getFavicon(string $ip, bool $bedrock = false) + { $query_ip = explode(':', $ip); if (count($query_ip) !== 2 && count($query_ip) !== 1) { diff --git a/core/classes/Minecraft/MCQuery.php b/core/classes/Minecraft/MCQuery.php index bdd07578cb..4fdc7b9dfa 100644 --- a/core/classes/Minecraft/MCQuery.php +++ b/core/classes/Minecraft/MCQuery.php @@ -11,8 +11,8 @@ * @version 2.0.0-pr13 * @license MIT */ -class MCQuery { - +class MCQuery +{ private const COLOUR_CHAR = '§'; private const COLOURS = [ @@ -35,15 +35,16 @@ class MCQuery { ]; /** - * Query a single server + * Query a single server. * - * @param array $ip Array ['ip' => string, 'pre' => int] - 'ip' contains ip:port, 'pre' 1 for pre-Minecraft 1.7 otherwise 0 - * @param string $type Type of query to use (`internal` or `external`). - * @param bool $bedrock Whether this is a Bedrock server or not. - * @param Language $language Query language object. - * @return array Array containing query result. + * @param array $ip Array ['ip' => string, 'pre' => int] - 'ip' contains ip:port, 'pre' 1 for pre-Minecraft 1.7 otherwise 0 + * @param string $type Type of query to use (`internal` or `external`). + * @param bool $bedrock Whether this is a Bedrock server or not. + * @param Language $language Query language object. + * @return array Array containing query result. */ - public static function singleQuery(array $ip, string $type, bool $bedrock, Language $language): array { + public static function singleQuery(array $ip, string $type, bool $bedrock, Language $language): array + { try { $query_ip = explode(':', $ip['ip']); if ($type == 'internal') { @@ -55,7 +56,7 @@ public static function singleQuery(array $ip, string $type, bool $bedrock, Langu if (count($query_ip) != 2) { return [ 'error' => true, - 'value' => 'split IP by : must contain exactly two components' + 'value' => 'split IP by : must contain exactly two components', ]; } @@ -85,13 +86,14 @@ public static function singleQuery(array $ip, string $type, bool $bedrock, Langu is_string($text = $query['description']) ? $text : $text['text'], $query['description']['extra'] ?? [], ), - 'version' => $query['version']['name'] + 'version' => $query['version']['name'], ]; } } else { $querier = new MinecraftQuery(); $querier->ConnectBedrock($query_ip[0], $query_ip[1], 5); $query = $querier->GetInfo(); + return [ 'status_value' => 1, 'status' => $language->get('general', 'online'), @@ -99,14 +101,14 @@ public static function singleQuery(array $ip, string $type, bool $bedrock, Langu 'player_count_max' => Output::getClean($query['MaxPlayers']), 'x_players_online' => $language->get('general', 'currently_x_players_online', ['count' => Output::getClean($query['Players'])]), 'motd' => $query['HostName'], - 'version' => $query['Version'] + 'version' => $query['Version'], ]; } return [ 'status_value' => 0, 'status' => $language->get('general', 'offline'), - 'server_offline' => $language->get('general', 'server_offline') + 'server_offline' => $language->get('general', 'server_offline'), ]; } @@ -114,11 +116,11 @@ public static function singleQuery(array $ip, string $type, bool $bedrock, Langu if (count($query_ip) > 2) { return [ 'error' => true, - 'value' => 'split IP by : contains more than two components' + 'value' => 'split IP by : contains more than two components', ]; } - $query = ExternalMCQuery::query($query_ip[0], ($query_ip[1] ?? ($bedrock ? 19132 : 25565)), $bedrock); + $query = ExternalMCQuery::query($query_ip[0], $query_ip[1] ?? ($bedrock ? 19132 : 25565), $bedrock); if ($query !== false && !$query->error && isset($query->response)) { $player_list = $query->response->players->list ?? []; @@ -142,7 +144,7 @@ public static function singleQuery(array $ip, string $type, bool $bedrock, Langu return [ 'status_value' => 0, 'status' => $language->get('general', 'offline'), - 'server_offline' => $language->get('general', 'server_offline') + 'server_offline' => $language->get('general', 'server_offline'), ]; } catch (Exception $e) { $error = $e->getMessage(); @@ -150,15 +152,15 @@ public static function singleQuery(array $ip, string $type, bool $bedrock, Langu $query_ip = explode(':', $ip['ip']); DB::getInstance()->insert('query_errors', [ - 'date' => date('U'), - 'error' => $error, - 'ip' => $query_ip[0], - 'port' => $query_ip[1] ?? 25565 + 'date' => date('U'), + 'error' => $error, + 'ip' => $query_ip[0], + 'port' => $query_ip[1] ?? 25565, ]); return [ 'error' => true, - 'value' => $error + 'value' => $error, ]; } } @@ -166,15 +168,16 @@ public static function singleQuery(array $ip, string $type, bool $bedrock, Langu /** * Formats a list of players into something useful for the frontend. * - * @param array $player_list Unformatted array of players in format 'id' => string (UUID), 'name' => string (username) + * @param array $player_list Unformatted array of players in format 'id' => string (UUID), 'name' => string (username) * @return array Array of formatted players **/ - public static function formatPlayerList(array $player_list): array { + public static function formatPlayerList(array $player_list): array + { $formatted = []; $integration = Integrations::getInstance()->getIntegration('Minecraft'); foreach ($player_list as $player) { - $player = (array)$player; + $player = (array) $player; $integration_user = new IntegrationUser($integration, str_replace('-', '', $player['id']), 'identifier'); if ($integration_user->exists()) { @@ -195,7 +198,7 @@ public static function formatPlayerList(array $player_list): array { 'username' => Output::getClean($player['name']), 'uuid' => Output::getClean($player['id']), 'avatar' => $avatar, - 'profile' => $profile + 'profile' => $profile, ]; } @@ -203,15 +206,16 @@ public static function formatPlayerList(array $player_list): array { } /** - * Query multiple servers + * Query multiple servers. * - * @param array $servers Servers - * @param string $type Type of query to use (internal or external) - * @param Language $language Query language object - * @param bool $accumulate Whether to return as one accumulated result or not - * @return array Array containing query result + * @param array $servers Servers + * @param string $type Type of query to use (internal or external) + * @param Language $language Query language object + * @param bool $accumulate Whether to return as one accumulated result or not + * @return array Array containing query result */ - public static function multiQuery(array $servers, string $type, Language $language, bool $accumulate): array { + public static function multiQuery(array $servers, string $type, Language $language, bool $accumulate): array + { $to_return = []; $total_count = 0; $status = 0; @@ -226,10 +230,10 @@ public static function multiQuery(array $servers, string $type, Language $langua try { if ($server['bedrock']) { $ping = new MinecraftQuery(); - $ping->ConnectBedrock($query_ip[0], ($query_ip[1] ?? 19132), 5); + $ping->ConnectBedrock($query_ip[0], $query_ip[1] ?? 19132, 5); $query = $ping->GetInfo(); } else { - $ping = new MinecraftPing($query_ip[0], ($query_ip[1] ?? 25565), 5); + $ping = new MinecraftPing($query_ip[0], $query_ip[1] ?? 25565, 5); if ($server['pre'] == 1) { $query = $ping->QueryOldPre17(); @@ -244,7 +248,7 @@ public static function multiQuery(array $servers, string $type, Language $langua 'date' => date('U'), 'error' => $e->getMessage(), 'ip' => $query_ip[0], - 'port' => ($query_ip[1] ?? ($server['bedrock'] ? 19132 : 25565)) + 'port' => ($query_ip[1] ?? ($server['bedrock'] ? 19132 : 25565)), ]); } @@ -265,7 +269,7 @@ public static function multiQuery(array $servers, string $type, Language $langua } $total_count += $query['Players']; } - } else if (isset($query['players'])) { + } elseif (isset($query['players'])) { if ($accumulate === false) { $to_return[] = [ 'name' => Output::getClean($server['name']), @@ -281,12 +285,12 @@ public static function multiQuery(array $servers, string $type, Language $langua } $total_count += $query['players']['online']; } - } else if ($accumulate === true) { + } elseif ($accumulate === true) { $to_return[] = [ 'name' => Output::getClean($server['name']), 'status_value' => 0, 'status' => $language->get('general', 'offline'), - 'server_offline' => $language->get('general', 'server_offline') + 'server_offline' => $language->get('general', 'server_offline'), ]; } } @@ -294,7 +298,6 @@ public static function multiQuery(array $servers, string $type, Language $langua if (isset($ping) && $ping instanceof MinecraftPing) { $ping->close(); } - } else { // External query foreach ($servers as $server) { @@ -305,7 +308,7 @@ public static function multiQuery(array $servers, string $type, Language $langua $is_bedrock = isset($server['bedrock']) && $server['bedrock'] === true; - $query = ExternalMCQuery::query($query_ip[0], ($query_ip[1] ?? ($is_bedrock ? 19132 : 25565)), $is_bedrock); + $query = ExternalMCQuery::query($query_ip[0], $query_ip[1] ?? ($is_bedrock ? 19132 : 25565), $is_bedrock); if ($query !== false && !$query->error && isset($query->response)) { if ($accumulate === false) { @@ -323,12 +326,12 @@ public static function multiQuery(array $servers, string $type, Language $langua } $total_count += $query->response->players->online; } - } else if ($accumulate === true) { + } elseif ($accumulate === true) { $to_return[] = [ 'name' => Output::getClean($server['name']), 'status_value' => 0, 'status' => $language->get('general', 'offline'), - 'server_offline' => $language->get('general', 'server_offline') + 'server_offline' => $language->get('general', 'server_offline'), ]; } } @@ -351,13 +354,14 @@ public static function multiQuery(array $servers, string $type, Language $langua } /** - * Convert a Minecraft MOTD to its legacy colour codes + * Convert a Minecraft MOTD to its legacy colour codes. * - * @param string $text Legacy MOTD single-line text - * @param array $modern_format Array of modern MOTD format strings + * @param string $text Legacy MOTD single-line text + * @param array $modern_format Array of modern MOTD format strings * @return string MOTD as legacy MC colours */ - private static function getMotd(string $text, array $modern_format): string { + private static function getMotd(string $text, array $modern_format): string + { if ($text !== '') { return $text; } @@ -389,18 +393,19 @@ private static function getMotd(string $text, array $modern_format): string { } /** - * Find the closest MC colour to a given hex colour + * Find the closest MC colour to a given hex colour. * - * @param string $rgb RGB colour code + * @param string $rgb RGB colour code * @return string The closest Minecraft colour code to the given RGB value */ - private static function getColor(string $rgb): string { + private static function getColor(string $rgb): string + { if (strpos($rgb, '#') === 0) { $rgb = substr($rgb, 1); } $smallestDiff = null; - $closestColor = ""; + $closestColor = ''; foreach (self::COLOURS as $hex => $char) { $diff = self::colorDiff($hex, $rgb); if ($smallestDiff === null || $diff < $smallestDiff) { @@ -413,13 +418,14 @@ private static function getColor(string $rgb): string { } /** - * Find the numerical difference between two RGB colours + * Find the numerical difference between two RGB colours. * - * @param mixed $rgb1 RGB colour code - * @param mixed $rgb2 RGB colour code - * @return int The difference between two RGB colours + * @param mixed $rgb1 RGB colour code + * @param mixed $rgb2 RGB colour code + * @return int The difference between two RGB colours */ - private static function colorDiff($rgb1, $rgb2): int { + private static function colorDiff($rgb1, $rgb2): int + { $red1 = hexdec(substr($rgb1, 0, 2)); $green1 = hexdec(substr($rgb1, 2, 2)); $blue1 = hexdec(substr($rgb1, 4, 2)); diff --git a/core/classes/Minecraft/MinecraftProfile.php b/core/classes/Minecraft/MinecraftProfile.php index 2db9eaa09d..4c753a7002 100644 --- a/core/classes/Minecraft/MinecraftProfile.php +++ b/core/classes/Minecraft/MinecraftProfile.php @@ -9,18 +9,19 @@ * @version 2.0.0-pr13 * @license MIT */ -class MinecraftProfile { - +class MinecraftProfile +{ private string $_username; private string $_uuid; private array $_properties; /** - * @param string $username The player's username. - * @param string $uuid The player's UUID. - * @param array $properties The player's properties specified on their Mojang profile. + * @param string $username The player's username. + * @param string $uuid The player's UUID. + * @param array $properties The player's properties specified on their Mojang profile. */ - public function __construct(string $username, string $uuid, array $properties = []) { + public function __construct(string $username, string $uuid, array $properties = []) + { $this->_username = $username; $this->_uuid = $uuid; $this->_properties = $properties; @@ -29,32 +30,36 @@ public function __construct(string $username, string $uuid, array $properties = /** * @return string The player's username. */ - public function getUsername(): string { + public function getUsername(): string + { return $this->_username; } /** * @return string The player's UUID. */ - public function getUUID(): string { + public function getUUID(): string + { return $this->_uuid; } /** * @return array The player's properties listed on their mojang profile. */ - public function getProperties(): array { + public function getProperties(): array + { return $this->_properties; } /** * @return array Returns an array with keys of 'properties, usernname and uuid'. */ - public function getProfileAsArray(): array { + public function getProfileAsArray(): array + { return [ 'username' => $this->_username, 'uuid' => $this->_uuid, - 'properties' => $this->_properties + 'properties' => $this->_properties, ]; } } diff --git a/core/classes/Minecraft/PluginQuery.php b/core/classes/Minecraft/PluginQuery.php index 4d38ae3e54..eb2de962b2 100644 --- a/core/classes/Minecraft/PluginQuery.php +++ b/core/classes/Minecraft/PluginQuery.php @@ -7,17 +7,17 @@ * @version 2.0.1 * @license MIT */ -class PluginQuery { - +class PluginQuery +{ /** - * Query a server by its server id + * Query a server by its server id. * - * @param int $server_id The Nameless server id to get the data for. - * @param Language $language Query language object. - * @return array Array containing query result. + * @param int $server_id The Nameless server id to get the data for. + * @param Language $language Query language object. + * @return array Array containing query result. */ - public static function singleQuery(int $server_id, Language $language): array { - + public static function singleQuery(int $server_id, Language $language): array + { $player_list_limit = Settings::get('player_list_limit', 20); $cache = new Cache(['name' => 'nameless', 'extension' => '.cache', 'path' => ROOT_PATH . '/cache/']); @@ -27,7 +27,7 @@ public static function singleQuery(int $server_id, Language $language): array { return [ 'status_value' => 0, 'status' => $language->get('general', 'offline'), - 'server_offline' => $language->get('general', 'server_offline') + 'server_offline' => $language->get('general', 'server_offline'), ]; } @@ -43,19 +43,20 @@ public static function singleQuery(int $server_id, Language $language): array { 'format_player_list' => MCQuery::formatPlayerList($player_list), 'x_players_online' => $language->get('general', 'currently_x_players_online', ['count' => $data['player_count']]), 'motd' => $data['motd'] ?? '', - 'version' => '' + 'version' => '', ]; } /** - * Query multiple servers + * Query multiple servers. * - * @param array $servers Servers - * @param Language $language Query language object - * @param bool $accumulate Whether to return as one accumulated result or not - * @return array Array containing query result + * @param array $servers Servers + * @param Language $language Query language object + * @param bool $accumulate Whether to return as one accumulated result or not + * @return array Array containing query result */ - public static function multiQuery(array $servers, Language $language, bool $accumulate) : array { + public static function multiQuery(array $servers, Language $language, bool $accumulate): array + { $to_return = []; $total_count = 0; $status = 0; @@ -64,13 +65,13 @@ public static function multiQuery(array $servers, Language $language, bool $accu foreach ($servers as $server) { $server_id = $server['id']; - + if (!$cache->isCached($server_id) && $accumulate === true) { $to_return[] = [ 'name' => Output::getClean($server['name']), 'status_value' => 0, 'status' => $language->get('general', 'offline'), - 'server_offline' => $language->get('general', 'server_offline') + 'server_offline' => $language->get('general', 'server_offline'), ]; } else { // Server is online diff --git a/core/classes/Minecraft/ProfileUtils.php b/core/classes/Minecraft/ProfileUtils.php index e5d8750e38..4de7891066 100644 --- a/core/classes/Minecraft/ProfileUtils.php +++ b/core/classes/Minecraft/ProfileUtils.php @@ -9,15 +9,16 @@ * @version 2.0.0-pr13 * @license MIT */ -class ProfileUtils { - +class ProfileUtils +{ /** * Get a MinecraftProfile from a username or UUID. * - * @param string $identifier Either the player's Username or UUID. + * @param string $identifier Either the player's Username or UUID. * @return MinecraftProfile|null Returns null if fetching of profile failed. Else returns completed user profile. */ - public static function getProfile(string $identifier): ?MinecraftProfile { + public static function getProfile(string $identifier): ?MinecraftProfile + { if (strlen($identifier) <= 16) { $result = self::getUUIDFromUsername($identifier); if ($result === null) { @@ -32,6 +33,7 @@ public static function getProfile(string $identifier): ?MinecraftProfile { if (!$client->hasError()) { $data = $client->json(true); + return new MinecraftProfile($data['name'], $data['id'], $data['properties']); } @@ -41,10 +43,11 @@ public static function getProfile(string $identifier): ?MinecraftProfile { /** * Get a Minecraft UUID from a Minecraft username. * - * @param string $username Minecraft username. - * @return array (Key => Value) "username" => Minecraft username (properly capitalized) "uuid" => Minecraft UUID or null + * @param string $username Minecraft username. + * @return array (Key => Value) "username" => Minecraft username (properly capitalized) "uuid" => Minecraft UUID or null */ - private static function getUUIDFromUsername(string $username): ?array { + private static function getUUIDFromUsername(string $username): ?array + { if (strlen($username) > 16) { return ['username' => '', 'uuid' => '']; } @@ -57,7 +60,7 @@ private static function getUUIDFromUsername(string $username): ?array { if ($ress['name'] != null && $ress['id'] != null) { return [ 'username' => $ress['name'], - 'uuid' => $ress['id'] + 'uuid' => $ress['id'], ]; } } @@ -68,33 +71,36 @@ private static function getUUIDFromUsername(string $username): ?array { /** * Generate an offline minecraft UUID v3 based on the case sensitive player name. * - * @param string $username + * @param string $username * @return array */ - public static function getOfflineModeUuid(string $username): array { - $data = hex2bin(md5("OfflinePlayer:" . $username)); - $data[6] = chr(ord($data[6]) & 0x0f | 0x30); - $data[8] = chr(ord($data[8]) & 0x3f | 0x80); + public static function getOfflineModeUuid(string $username): array + { + $data = hex2bin(md5('OfflinePlayer:' . $username)); + $data[6] = chr(ord($data[6]) & 0x0F | 0x30); + $data[8] = chr(ord($data[8]) & 0x3F | 0x80); return [ 'uuid' => bin2hex($data), - 'username' => $username + 'username' => $username, ]; } /** - * Add dashes to UUID - * - * @param string $uuid string UUID to format - * @return string Properly formatted UUID (According to UUID v4 Standards xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx WHERE y = 8,9,A,or B and x = random digits.) - */ - public static function formatUUID(string $uuid): string { - $uid = ""; - $uid .= substr($uuid, 0, 8)."-"; - $uid .= substr($uuid, 8, 4)."-"; - $uid .= substr($uuid, 12, 4)."-"; - $uid .= substr($uuid, 16, 4)."-"; + * Add dashes to UUID. + * + * @param string $uuid string UUID to format + * @return string Properly formatted UUID (According to UUID v4 Standards xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx WHERE y = 8,9,A,or B and x = random digits.) + */ + public static function formatUUID(string $uuid): string + { + $uid = ''; + $uid .= substr($uuid, 0, 8).'-'; + $uid .= substr($uuid, 8, 4).'-'; + $uid .= substr($uuid, 12, 4).'-'; + $uid .= substr($uuid, 16, 4).'-'; $uid .= substr($uuid, 20); + return $uid; } } diff --git a/core/classes/Misc/Announcements.php b/core/classes/Misc/Announcements.php index 8bb59db802..1fba61420c 100644 --- a/core/classes/Misc/Announcements.php +++ b/core/classes/Misc/Announcements.php @@ -7,11 +7,12 @@ * @version 2.1.0 * @license MIT */ -class Announcements { - +class Announcements +{ private Cache $_cache; - public function __construct(Cache $cache) { + public function __construct(Cache $cache) + { $this->_cache = $cache; } @@ -19,13 +20,14 @@ public function __construct(Cache $cache) { * Get all announcements matching the param filters. * If they have a cookie set for an announcement, it will be skipped. * - * @param string|null $page Name of the page they're viewing. + * @param string|null $page Name of the page they're viewing. * @param string|null $custom_page Title of custom page they're viewing. - * @param array $user_groups All this user's groups. + * @param array $user_groups All this user's groups. * * @return Announcement[] Array of announcements they should see on this specific page with their groups. */ - public function getAvailable(?string $page = null, ?string $custom_page = null, array $user_groups = [0]): iterable { + public function getAvailable(?string $page = null, ?string $custom_page = null, array $user_groups = [0]): iterable + { $announcements = []; foreach ($this->getAll() as $announcement) { @@ -54,7 +56,8 @@ public function getAvailable(?string $page = null, ?string $custom_page = null, * * @return Announcement[] All announcements. */ - public function getAll(): iterable { + public function getAll(): iterable + { $this->_cache->setCache('custom_announcements'); if ($this->_cache->isCached('custom_announcements')) { @@ -79,7 +82,8 @@ public function getAll(): iterable { * * @return array Name of all pages announcements can be on. */ - public static function getPages(Pages $pages): array { + public static function getPages(Pages $pages): array + { $available_pages = []; foreach ($pages->returnPages() as $page) { @@ -98,7 +102,8 @@ public static function getPages(Pages $pages): array { * * @return string Comma seperated list of page names. */ - public static function getPagesCsv(?string $pages_json = null): ?string { + public static function getPagesCsv(?string $pages_json = null): ?string + { $pages = json_decode($pages_json); if (!$pages) { @@ -111,18 +116,19 @@ public static function getPagesCsv(?string $pages_json = null): ?string { /** * Edit an existing announcement. * - * @param int $id ID of announcement to edit. - * @param array $pages Array of page names this announcement should be on. - * @param array $groups Array of group IDs this announcement should be visible to. - * @param string $text_colour Hex code of text colour to use. - * @param string $background_colour Hex code of background banner colour of announcement. - * @param string $icon HTML to use to display icon on announcement. - * @param bool $closable Whether this announcement should have an "x" to close and hide, or be shown 24/7. - * @param string $header Header text to show at top of announcement. - * @param string $message Main text to show in announcement. - * @param int $order Order of this announcement to use for sorting. + * @param int $id ID of announcement to edit. + * @param array $pages Array of page names this announcement should be on. + * @param array $groups Array of group IDs this announcement should be visible to. + * @param string $text_colour Hex code of text colour to use. + * @param string $background_colour Hex code of background banner colour of announcement. + * @param string $icon HTML to use to display icon on announcement. + * @param bool $closable Whether this announcement should have an "x" to close and hide, or be shown 24/7. + * @param string $header Header text to show at top of announcement. + * @param string $message Main text to show in announcement. + * @param int $order Order of this announcement to use for sorting. */ - public function edit(int $id, array $pages, array $groups, string $text_colour, string $background_colour, string $icon, bool $closable, string $header, string $message, int $order): bool { + public function edit(int $id, array $pages, array $groups, string $text_colour, string $background_colour, string $icon, bool $closable, string $header, string $message, int $order): bool + { DB::getInstance()->update('custom_announcements', $id, [ 'pages' => json_encode($pages), 'groups' => json_encode($groups), @@ -132,7 +138,7 @@ public function edit(int $id, array $pages, array $groups, string $text_colour, 'closable' => $closable ? 1 : 0, 'header' => $header, 'message' => $message, - 'order' => $order + 'order' => $order, ]); $this->resetCache(); @@ -144,7 +150,8 @@ public function edit(int $id, array $pages, array $groups, string $text_colour, * Erase and regenerate announcement cache file. * Used when creating or editing announcements. */ - public function resetCache(): void { + public function resetCache(): void + { $this->_cache->setCache('custom_announcements'); if ($this->_cache->isCached('custom_announcements')) { @@ -157,18 +164,19 @@ public function resetCache(): void { /** * Create an announcement. * - * @param User $user User who is creating the announcement. - * @param array $pages Array of page names this announcement should be on. - * @param array $groups Array of group IDs this announcement should be visible to. - * @param string $text_colour Hex code of text colour to use. - * @param string $background_colour Hex code of background banner colour of announcement. - * @param string $icon HTML to use to display icon on announcement. - * @param bool $closable Whether this announcement should have an "x" to close and hide, or be shown 24/7. - * @param string $header Header text to show at top of announcement. - * @param string $message Main text to show in announcement. - * @param int $order Order of this announcement to use for sorting. + * @param User $user User who is creating the announcement. + * @param array $pages Array of page names this announcement should be on. + * @param array $groups Array of group IDs this announcement should be visible to. + * @param string $text_colour Hex code of text colour to use. + * @param string $background_colour Hex code of background banner colour of announcement. + * @param string $icon HTML to use to display icon on announcement. + * @param bool $closable Whether this announcement should have an "x" to close and hide, or be shown 24/7. + * @param string $header Header text to show at top of announcement. + * @param string $message Main text to show in announcement. + * @param int $order Order of this announcement to use for sorting. */ - public function create(User $user, array $pages, array $groups, string $text_colour, string $background_colour, string $icon, bool $closable, string $header, string $message, int $order): bool { + public function create(User $user, array $pages, array $groups, string $text_colour, string $background_colour, string $icon, bool $closable, string $header, string $message, int $order): bool + { DB::getInstance()->insert('custom_announcements', [ 'pages' => json_encode($pages), 'groups' => json_encode($groups), @@ -178,7 +186,7 @@ public function create(User $user, array $pages, array $groups, string $text_col 'closable' => $closable ? 1 : 0, 'header' => $header, 'message' => $message, - 'order' => $order + 'order' => $order, ]); $this->resetCache(); diff --git a/core/classes/Misc/CaptchaBase.php b/core/classes/Misc/CaptchaBase.php index e9a0e8f1db..54dae90421 100644 --- a/core/classes/Misc/CaptchaBase.php +++ b/core/classes/Misc/CaptchaBase.php @@ -7,8 +7,8 @@ * @version 2.0.0-pr10 * @license MIT */ -abstract class CaptchaBase { - +abstract class CaptchaBase +{ /** * @var array All registered captcha providers. */ @@ -35,48 +35,53 @@ abstract class CaptchaBase { protected ?string $_privateKey; /** - * Register a provider + * Register a provider. * * @param CaptchaBase $provider Provider instance to register */ - public static function addProvider(CaptchaBase $provider): void { + public static function addProvider(CaptchaBase $provider): void + { self::$_providers[$provider->_name] = $provider; } /** - * Return active provider + * Return active provider. * * @return CaptchaBase Active provider */ - public static function getActiveProvider(): CaptchaBase { + public static function getActiveProvider(): CaptchaBase + { return self::$_providers[self::$_activeProvider]; } /** - * Set active provider + * Set active provider. * * @param string $provider Provider name to set as active */ - public static function setActiveProvider(string $provider): void { + public static function setActiveProvider(string $provider): void + { self::$_activeProvider = $provider; } /** - * Return all providers + * Return all providers. * * @return CaptchaBase[] All providers */ - public static function getAllProviders(): iterable { + public static function getAllProviders(): iterable + { return self::$_providers; } /** * Is captcha enabled for a given key? * - * @param string $key Key to lookup in db, defaults to simply recaptcha (for register, contact pages etc) - * @return bool Whether captcha is enabled or not + * @param string $key Key to lookup in db, defaults to simply recaptcha (for register, contact pages etc) + * @return bool Whether captcha is enabled or not */ - public static function isCaptchaEnabled(string $key = 'recaptcha'): bool { + public static function isCaptchaEnabled(string $key = 'recaptcha'): bool + { if (!Config::get('core.captcha')) { return false; } @@ -85,74 +90,77 @@ public static function isCaptchaEnabled(string $key = 'recaptcha'): bool { } /** - * Get provider name + * Get provider name. * * @return string Provider name */ - public function getName(): string { + public function getName(): string + { return $this->_name; } /** - * Get public key + * Get public key. * * @return string Public key */ - public function getPublicKey(): string { + public function getPublicKey(): string + { return $this->_publicKey; } /** - * Get private key + * Get private key. * * @return string Private key */ - public function getPrivateKey(): string { + public function getPrivateKey(): string + { return $this->_privateKey; } /** - * Validate a Captcha token + * Validate a Captcha token. * - * @param array $post Post body to validate - * @return bool Whether the token was valid or not + * @param array $post Post body to validate + * @return bool Whether the token was valid or not */ abstract public function validateToken(array $post): bool; /** - * Validate if the private key is valid + * Validate if the private key is valid. * - * @param string $secret The secret key to validate - * @return bool Whether the private key is valid or not + * @param string $secret The secret key to validate + * @return bool Whether the private key is valid or not */ - abstract public function validateSecret(string $secret) : bool; + abstract public function validateSecret(string $secret): bool; /** - * Validate if the public key is valid or not + * Validate if the public key is valid or not. * - * @param string $key The public key to validate - * @return bool Whether the public key is valid or not + * @param string $key The public key to validate + * @return bool Whether the public key is valid or not */ - abstract public function validateKey(string $key) : bool; + abstract public function validateKey(string $key): bool; /** - * Get form input HTML to display + * Get form input HTML to display. * * @return string|null HTML to display */ abstract public function getHtml(): ?string; /** - * Get JavaScript source URL + * Get JavaScript source URL. * * @return string JS source URL */ abstract public function getJavascriptSource(): string; /** - * Get JavaScript on submit function + * Get JavaScript on submit function. * - * @param string $id ID attribute of form + * @param string $id ID attribute of form * @return string|null JS for submit function */ abstract public function getJavascriptSubmit(string $id): ?string; diff --git a/core/classes/Misc/DebugBarHelper.php b/core/classes/Misc/DebugBarHelper.php index 7998d0934b..1a8d4eea06 100644 --- a/core/classes/Misc/DebugBarHelper.php +++ b/core/classes/Misc/DebugBarHelper.php @@ -2,11 +2,11 @@ use DebugBar\DataCollector\ConfigCollector; use DebugBar\DataCollector\MemoryCollector; +use DebugBar\DataCollector\PDO\PDOCollector; use DebugBar\DataCollector\PhpInfoCollector; use DebugBar\DataCollector\RequestDataCollector; use DebugBar\DataCollector\TimeDataCollector; use DebugBar\DebugBar; -use DebugBar\DataCollector\PDO\PDOCollector; use Junker\DebugBar\Bridge\SmartyCollector; /** @@ -17,14 +17,15 @@ * @version 2.0.0-pr13 * @license MIT */ -class DebugBarHelper extends Instanceable { - +class DebugBarHelper extends Instanceable +{ private ?DebugBar $_debugBar = null; /** - * Enable the PHPDebugBar + * Enable the PHPDebugBar. */ - public function enable(Smarty $smarty): void { + public function enable(Smarty $smarty): void + { $debugbar = new DebugBar(); $debugbar->addCollector(new TimeDataCollector()); @@ -56,8 +57,8 @@ public function enable(Smarty $smarty): void { $this->_debugBar = $debugbar; } - public function getDebugBar(): ?DebugBar { + public function getDebugBar(): ?DebugBar + { return $this->_debugBar; } - } diff --git a/core/classes/Misc/Debugging.php b/core/classes/Misc/Debugging.php index ce5be2e4d1..d59f6b09b5 100644 --- a/core/classes/Misc/Debugging.php +++ b/core/classes/Misc/Debugging.php @@ -1,32 +1,35 @@ getMessage(); $error_file = is_null($exception) ? $error_file : $exception->getFile(); - $error_line = is_null($exception) ? (int)$error_line : $exception->getLine(); + $error_line = is_null($exception) ? (int) $error_line : $exception->getLine(); // Create a log entry for viewing in staffcp self::logError('fatal', $error_file . '(' . $error_line . '): ' . $error_string); @@ -89,21 +91,19 @@ public static function catchException(?Throwable $exception, ?string $error_stri // Loop all frames in the exception trace & get relevent information if ($exception != null) { - $i = count($exception->getTrace()); foreach ($exception->getTrace() as $frame) { - // Check if previous frame had same file and line number (ie: DB->query(...) reports same file and line twice in a row) if (end($frames)['file'] == $frame['file'] && end($frames)['line'] == $frame['line']) { - ++$skip_frames; + $skip_frames++; continue; } // Skip frame if it is a closure // @phpstan-ignore-next-line (it does not know that $frame['function'] is valid) if (isset($frame['function']) && $frame['function'] === '{closure}') { - ++$skip_frames; + $skip_frames++; continue; } @@ -177,7 +177,7 @@ public static function catchException(?Throwable $exception, ?string $error_stri ]); $smarty->display(ROOT_PATH . '/core/includes/error.tpl'); - die(); + die; } /** @@ -185,18 +185,21 @@ public static function catchException(?Throwable $exception, ?string $error_stri * * @return bool Whether the error page should be in plain text rather than a user friendly HTML page. */ - private static function shouldUsePlainText(): bool { + private static function shouldUsePlainText(): bool + { $route = $_REQUEST['route'] ?? ''; + return str_contains($route, '/api/v2/') || str_contains($route, '/queries/') || isset($_SERVER['HTTP_X_REQUESTED_WITH']); } /** * Write error to specific log file. * - * @param string $type Which category/file to log this to. Must be: `warning`, `notice`, `other` or `fatal`. + * @param string $type Which category/file to log this to. Must be: `warning`, `notice`, `other` or `fatal`. * @param string $contents The message to be saved. */ - private static function logError(string $type, string $contents): void { + private static function logError(string $type, string $contents): void + { $dir_exists = false; try { @@ -218,15 +221,16 @@ private static function logError(string $type, string $contents): void { /** * Returns frame array from specified information. - * Leaving number as null will use Exception trace count + 1 (for most recent frame) + * Leaving number as null will use Exception trace count + 1 (for most recent frame). * - * @param Throwable|null $exception Exception object caught and whose trace to count. If null, $number will be used for frame number. - * @param string $frame_file Path to file which was referenced in this frame. - * @param int $frame_line Line number of $frame_file which Exception was thrown at. - * @param int|null $number Higher number = more recent frame. If null, will use $exception trace count + 1. - * @return array This frame in an array form. + * @param Throwable|null $exception Exception object caught and whose trace to count. If null, $number will be used for frame number. + * @param string $frame_file Path to file which was referenced in this frame. + * @param int $frame_line Line number of $frame_file which Exception was thrown at. + * @param int|null $number Higher number = more recent frame. If null, will use $exception trace count + 1. + * @return array This frame in an array form. */ - public static function parseFrame(?Throwable $exception, string $frame_file, int $frame_line, ?int $number = null): array { + public static function parseFrame(?Throwable $exception, string $frame_file, int $frame_line, ?int $number = null): array + { $lines = file($frame_file); return [ @@ -235,18 +239,19 @@ public static function parseFrame(?Throwable $exception, string $frame_file, int 'line' => $frame_line, 'start_line' => (is_array($lines) && count($lines) >= self::LINE_BUFFER && ($frame_line - self::LINE_BUFFER > 0)) ? ($frame_line - self::LINE_BUFFER) : 1, 'highlight_line' => (is_array($lines) && count($lines) >= self::LINE_BUFFER && $frame_line - self::LINE_BUFFER > 0) ? (self::LINE_BUFFER + 1) : $frame_line, - 'code' => self::parseFile($lines, $frame_line) + 'code' => self::parseFile($lines, $frame_line), ]; } /** * Create purified and truncated string from a file for use with error source code preview. * - * @param array|bool $lines Array of lines in this file. If false, will return nothing (means PHP cannot access file). - * @param int $error_line Line to center output around. - * @return string Truncated string from this file. + * @param array|bool $lines Array of lines in this file. If false, will return nothing (means PHP cannot access file). + * @param int $error_line Line to center output around. + * @return string Truncated string from this file. */ - private static function parseFile($lines, int $error_line): string { + private static function parseFile($lines, int $error_line): string + { if ($lines == false || count($lines) < 1) { return ''; } @@ -269,7 +274,8 @@ private static function parseFile($lines, int $error_line): string { * Called at end of every execution on page load. * If an error exists, and the type is fatal, pass execution to catchException(). */ - public static function catchShutdownError(): void { + public static function catchShutdownError(): void + { $error = error_get_last(); if ($error === null) { @@ -287,7 +293,8 @@ public static function catchShutdownError(): void { * * @param string $contents Error to write to file. */ - public static function logCustomError(string $contents): void { + public static function logCustomError(string $contents): void + { self::logError('other', $contents); } @@ -296,8 +303,8 @@ public static function logCustomError(string $contents): void { * * @param string $contents Warning to write to file. */ - public static function logWarning(string $contents): void { + public static function logWarning(string $contents): void + { self::logError('warning', $contents); } - } diff --git a/core/classes/Misc/HttpUtils.php b/core/classes/Misc/HttpUtils.php index 3faf256d94..5003160d93 100644 --- a/core/classes/Misc/HttpUtils.php +++ b/core/classes/Misc/HttpUtils.php @@ -10,14 +10,15 @@ * @version 2.0.0 * @license MIT */ -class HttpUtils { - +class HttpUtils +{ /** * Get the client's true IP address, using proxy headers if necessary. * * @return ?string Client IP address, or null if there is no remote address, for example in CLI environment */ - public static function getRemoteAddress(): ?string { + public static function getRemoteAddress(): ?string + { if (!self::isTrustedProxy()) { // Client is not a trusted proxy, we can only trust its actual remote address return $_SERVER['REMOTE_ADDR']; @@ -62,7 +63,7 @@ public static function getRemoteAddress(): ?string { foreach (explode(';', trim($part1)) as $part2) { $part2 = explode('=', $part2); if (count($part2) != 2) { - die("Invalid Forwarded header"); + die('Invalid Forwarded header'); } if ($part2[0] === 'for') { @@ -92,12 +93,14 @@ public static function getRemoteAddress(): ?string { * * @return string 'http' if HTTP or 'https' if HTTPS. If the protocol is not known, for example when using the CLI, 'http' is always returned. */ - public static function getProtocol(): string { + public static function getProtocol(): string + { $x_forwarded_proto = self::getHeader('X-Forwarded-Proto'); if ($x_forwarded_proto !== null) { if ($x_forwarded_proto !== 'http' && $x_forwarded_proto !== 'https') { die('Invalid X-Forwarded-Proto header, should be "http" or "https" but it is "' . Output::getClean($x_forwarded_proto) . '".'); } + return $x_forwarded_proto; } @@ -113,7 +116,8 @@ public static function getProtocol(): string { * * @return ?int Port number, or null when using the CLI */ - public static function getPort(): ?int { + public static function getPort(): ?int + { $x_forwarded_port = self::getHeader('X-Forwarded-Port'); if ($x_forwarded_port !== null) { return (int) $x_forwarded_port; @@ -125,7 +129,7 @@ public static function getPort(): ?int { if ($x_forwarded_proto !== null) { if ($x_forwarded_proto === 'https') { return 443; - } else if ($x_forwarded_proto === 'http') { + } elseif ($x_forwarded_proto === 'http') { return 80; } } @@ -142,16 +146,19 @@ public static function getPort(): ?int { * * @return bool Whether the trusted proxies option is configured or not */ - public static function isTrustedProxiesConfigured(): bool { + public static function isTrustedProxiesConfigured(): bool + { $config_proxies = Config::get('core.trustedProxies'); $env_proxies = getenv('NAMELESS_TRUSTED_PROXIES'); + return ($config_proxies !== false && is_array($config_proxies)) || $env_proxies !== false; } /** * @return array List of trusted proxy networks according to config file and environment */ - public static function getTrustedProxies(): array { + public static function getTrustedProxies(): array + { $trusted_proxies = []; // Add trusted proxies from config file @@ -178,7 +185,8 @@ public static function getTrustedProxies(): array { * * @return bool Whether the client is a trusted proxy or not. */ - private static function isTrustedProxy(): bool { + private static function isTrustedProxy(): bool + { $trusted_proxies = self::getTrustedProxies(); foreach ($trusted_proxies as $trustedProxy) { @@ -195,7 +203,8 @@ private static function isTrustedProxy(): bool { * * @return string Address that may be used for security purposes */ - private static function firstNonProxyAddress(array $addresses): string { + private static function firstNonProxyAddress(array $addresses): string + { if (count($addresses) === 0) { throw new InvalidArgumentException('Addresses must not be empty'); } @@ -228,18 +237,19 @@ private static function firstNonProxyAddress(array $addresses): string { } /** - * Get header value - * @param string $header_name Header name + * Get header value. + * @param string $header_name Header name * @return ?string Header value, or null if header is not present in request */ - public static function getHeader(string $header_name): ?string { + public static function getHeader(string $header_name): ?string + { $headers = getallheaders(); foreach ($headers as $key => $value) { if (strcasecmp($key, $header_name) === 0) { return $value; } } + return null; } - } diff --git a/core/classes/Misc/IntegrityChecker.php b/core/classes/Misc/IntegrityChecker.php index 60dc12b499..ac1b12a362 100644 --- a/core/classes/Misc/IntegrityChecker.php +++ b/core/classes/Misc/IntegrityChecker.php @@ -1,21 +1,21 @@ _db = DB::getInstance(); } /** * Add an OAuth provider to the system. * - * @param string $name The name of the provider (Discord, Google, etc). - * @param string $module Name of the module which registered this provider. - * @param array $data Metadata about the provider: class, user_id_name, scope_id_name, icon - * @param array $extra_options Extra options to pass to the provider constructor. Example: keycloak needs some specific options + * @param string $name The name of the provider (Discord, Google, etc). + * @param string $module Name of the module which registered this provider. + * @param array $data Metadata about the provider: class, user_id_name, scope_id_name, icon + * @param array $extra_options Extra options to pass to the provider constructor. Example: keycloak needs some specific options */ - public function registerProvider(string $name, string $module, array $data, array $extra_options = []): void { + public function registerProvider(string $name, string $module, array $data, array $extra_options = []): void + { $this->_providers[$name] = array_merge(['module' => $module, 'extra_options' => $extra_options], $data); } @@ -38,7 +40,8 @@ public function registerProvider(string $name, string $module, array $data, arra * * @return array An array of all registered OAuth providers. */ - public function getProviders(): array { + public function getProviders(): array + { return $this->_providers; } @@ -47,12 +50,14 @@ public function getProviders(): array { * * @return bool If any provider is setup */ - public function isAvailable(): bool { + public function isAvailable(): bool + { foreach (array_keys($this->_providers) as $provider) { if ($this->isSetup($provider)) { return true; } } + return false; } @@ -61,7 +66,8 @@ public function isAvailable(): bool { * * @return array Array of provider names and their instances */ - public function getProvidersAvailable(): array { + public function getProvidersAvailable(): array + { $providers = []; foreach ($this->_providers as $provider_name => $provider_data) { if (!$this->isSetup($provider_name)) { @@ -97,10 +103,11 @@ public function getProvidersAvailable(): array { /** * Get or create an instance of a specific provider. * - * @param string $provider The provider name + * @param string $provider The provider name * @return AbstractProvider The provider instance */ - public function getProviderInstance(string $provider): AbstractProvider { + public function getProviderInstance(string $provider): AbstractProvider + { if (!array_key_exists($provider, $this->_providers)) { throw new RuntimeException("Unknown provider: $provider"); } @@ -110,7 +117,7 @@ public function getProviderInstance(string $provider): AbstractProvider { } [$clientId, $clientSecret] = $this->getCredentials($provider); - $url = rtrim(URL::getSelfURL(), '/') . URL::build('/oauth', "provider=" . urlencode($provider), 'non-friendly'); + $url = rtrim(URL::getSelfURL(), '/') . URL::build('/oauth', 'provider=' . urlencode($provider), 'non-friendly'); $options = [ 'clientId' => $clientId, 'clientSecret' => $clientSecret, @@ -126,11 +133,12 @@ public function getProviderInstance(string $provider): AbstractProvider { * Determine if the email returned from a provider is verified on their end. * Used during registration to auto verify emails (if they enter the same one as the provider returned). * - * @param string $provider The provider name - * @param array $provider_user The provider user data (aka resource owner) - * @return bool Whether the email returned from the provider is verified or not + * @param string $provider The provider name + * @param array $provider_user The provider user data (aka resource owner) + * @return bool Whether the email returned from the provider is verified or not */ - public function hasVerifiedEmail(string $provider, array $provider_user): bool { + public function hasVerifiedEmail(string $provider, array $provider_user): bool + { if (!array_key_exists($provider, $this->_providers)) { throw new RuntimeException("Unknown provider: $provider"); } @@ -141,10 +149,11 @@ public function hasVerifiedEmail(string $provider, array $provider_user): bool { /** * Determine if a provider is enabled (different from setup!). * - * @param string $provider The provider name - * @return bool If the provider is enabled + * @param string $provider The provider name + * @return bool If the provider is enabled */ - public function isEnabled(string $provider): bool { + public function isEnabled(string $provider): bool + { return $this->_db->get('oauth', ['provider', $provider])->first()->enabled == '1'; } @@ -152,20 +161,22 @@ public function isEnabled(string $provider): bool { * Set a provider as enabled or disabled (`1` or `0` respectively). * * @param string $provider The provider name - * @param int $enabled Whether to enable or disable the provider + * @param int $enabled Whether to enable or disable the provider */ - public function setEnabled(string $provider, int $enabled): void { - $this->_db->query("UPDATE nl2_oauth SET enabled = ? WHERE provider = ?", [$enabled, $provider]); + public function setEnabled(string $provider, int $enabled): void + { + $this->_db->query('UPDATE nl2_oauth SET enabled = ? WHERE provider = ?', [$enabled, $provider]); } /** * Determine if a provider is setup. * A provider is considered setup if it has a client ID and a client secret set. * - * @param string $provider The provider name - * @return bool If the provider is setup + * @param string $provider The provider name + * @return bool If the provider is setup */ - public function isSetup(string $provider): bool { + public function isSetup(string $provider): bool + { if (!$this->isEnabled($provider)) { return false; } @@ -179,10 +190,11 @@ public function isSetup(string $provider): bool { * Get the array key for a specific providers client ID. * Discord uses `id` and Google uses `sub`, so we have to be able to differentiate. * - * @param string $provider The provider name + * @param string $provider The provider name * @return string The array key for the provider's client ID */ - public function getUserIdName(string $provider): string { + public function getUserIdName(string $provider): string + { if (array_key_exists($provider, $this->_providers)) { return $this->_providers[$provider]['user_id_name']; } @@ -193,11 +205,13 @@ public function getUserIdName(string $provider): string { /** * Get the client ID and client secret for a specific provider. * - * @param string $provider The provider name - * @return array The configured credentials for this provider + * @param string $provider The provider name + * @return array The configured credentials for this provider */ - public function getCredentials(string $provider): array { + public function getCredentials(string $provider): array + { $data = $this->_db->get('oauth', ['provider', $provider])->first(); + return [ $data->client_id, $data->client_secret, @@ -207,11 +221,12 @@ public function getCredentials(string $provider): array { /** * Update the client ID and client secret for a specific provider. * - * @param string $provider The provider name - * @param string $client_id The new client ID + * @param string $provider The provider name + * @param string $client_id The new client ID * @param string $client_secret The new client secret */ - public function setCredentials(string $provider, string $client_id, string $client_secret): void { + public function setCredentials(string $provider, string $client_id, string $client_secret): void + { $this->_db->query( 'INSERT INTO nl2_oauth (provider, client_id, client_secret) VALUES(?, ?, ?) ON DUPLICATE KEY UPDATE client_id=?, client_secret=?', [$provider, $client_id, $client_secret, $client_id, $client_secret] @@ -221,11 +236,12 @@ public function setCredentials(string $provider, string $client_id, string $clie /** * Check if a NamelessMC user has already connected their account to a specific provider. * - * @param string $provider The provider name - * @param string $provider_id The provider user ID - * @return bool Whether the user is already linked to the provider + * @param string $provider The provider name + * @param string $provider_id The provider user ID + * @return bool Whether the user is already linked to the provider */ - public function userExistsByProviderId(string $provider, string $provider_id): bool { + public function userExistsByProviderId(string $provider, string $provider_id): bool + { return $this->_db->query( 'SELECT user_id FROM nl2_oauth_users WHERE provider = ? AND provider_id = ?', [$provider, $provider_id] @@ -235,11 +251,12 @@ public function userExistsByProviderId(string $provider, string $provider_id): b /** * Get the NamelessMC user ID for a specific provider user ID. * - * @param string $provider The provider name - * @param string $provider_id The provider user ID for lookup - * @return int The NamelessMC user ID of the user linked to the provider + * @param string $provider The provider name + * @param string $provider_id The provider user ID for lookup + * @return int The NamelessMC user ID of the user linked to the provider */ - public function getUserIdFromProviderId(string $provider, string $provider_id): int { + public function getUserIdFromProviderId(string $provider, string $provider_id): int + { return $this->_db->query( 'SELECT user_id FROM nl2_oauth_users WHERE provider = ? AND provider_id = ?', [$provider, $provider_id] @@ -249,11 +266,12 @@ public function getUserIdFromProviderId(string $provider, string $provider_id): /** * Save a new user linked to a specific provider. * - * @param string $user_id The NamelessMC user ID - * @param string $provider The provider name - * @param string $provider_id The provider user ID + * @param string $user_id The NamelessMC user ID + * @param string $provider The provider name + * @param string $provider_id The provider user ID */ - public function saveUserProvider(string $user_id, string $provider, string $provider_id): void { + public function saveUserProvider(string $user_id, string $provider, string $provider_id): void + { $this->_db->query( 'INSERT INTO nl2_oauth_users (user_id, provider, provider_id) VALUES (?, ?, ?)', [$user_id, $provider, $provider_id] @@ -261,12 +279,13 @@ public function saveUserProvider(string $user_id, string $provider, string $prov } /** - * Get an array of provider names and provider user IDs for a specific user + * Get an array of provider names and provider user IDs for a specific user. * - * @param int $user_id The NamelessMC user ID + * @param int $user_id The NamelessMC user ID * @return array The array */ - public function getAllProvidersForUser(int $user_id): array { + public function getAllProvidersForUser(int $user_id): array + { return $this->_db->query( 'SELECT * FROM nl2_oauth_users WHERE user_id = ?', [$user_id] @@ -276,10 +295,11 @@ public function getAllProvidersForUser(int $user_id): array { /** * Delete a user's provider data. * - * @param int $user_id The provider name + * @param int $user_id The provider name * @param string $provider The provider user ID */ - public function unlinkProviderForUser(int $user_id, string $provider): void { + public function unlinkProviderForUser(int $user_id, string $provider): void + { $this->_db->query( 'DELETE FROM nl2_oauth_users WHERE user_id = ? AND provider = ?', [$user_id, $provider] @@ -289,10 +309,11 @@ public function unlinkProviderForUser(int $user_id, string $provider): void { /** * Format an array of CSS rules into a string, appending `!important` to each rule. * - * @param array $css CSS rule => value array + * @param array $css CSS rule => value array * @return string The CSS string */ - private function formatCss(array $css): string { + private function formatCss(array $css): string + { return implode(' ', array_map(static function ($rule, $value) { return $rule . ': ' . $value . ' !important;'; }, array_keys($css), array_values($css))); diff --git a/core/classes/Misc/Placeholders.php b/core/classes/Misc/Placeholders.php index 36a5b59ae4..2df5adadcc 100644 --- a/core/classes/Misc/Placeholders.php +++ b/core/classes/Misc/Placeholders.php @@ -7,13 +7,14 @@ * @version 2.0.0-pr12 * @license MIT */ -class Placeholders extends Instanceable { - +class Placeholders extends Instanceable +{ private DB $_db; private array $_all_placeholders; - public function __construct() { + public function __construct() + { $this->_db = DB::getInstance(); $placeholders_query = $this->_db->get('placeholders_settings', ['name', '<>', ''])->results(); @@ -49,7 +50,8 @@ public function __construct() { * * @return array All placeholders. */ - public function getAllPlaceholders(): array { + public function getAllPlaceholders(): array + { return $this->_all_placeholders; } @@ -60,7 +62,8 @@ public function getAllPlaceholders(): array { * * @param string $name Name of placeholder */ - public function registerPlaceholder(int $server_id, string $name): void { + public function registerPlaceholder(int $server_id, string $name): void + { $this->_db->query('INSERT IGNORE INTO nl2_placeholders_settings (server_id, name) VALUES (?, ?)', [$server_id, $name]); } @@ -71,7 +74,8 @@ public function registerPlaceholder(int $server_id, string $name): void { * * @return array Their placeholders. */ - public function loadUserPlaceholders(string $uuid): array { + public function loadUserPlaceholders(string $uuid): array + { $binUuid = hex2bin(str_replace('-', '', $uuid)); $placeholder_query = $this->_db->query('SELECT * FROM nl2_users_placeholders up JOIN nl2_placeholders_settings ps ON up.name = ps.name AND up.server_id = ps.server_id WHERE up.uuid = ?', [$binUuid]); @@ -105,7 +109,8 @@ public function loadUserPlaceholders(string $uuid): array { * * @return array Array of placeholders which have leaderboard enabled. */ - public function getLeaderboardPlaceholders(): array { + public function getLeaderboardPlaceholders(): array + { return array_filter($this->_all_placeholders, static function ($placeholder) { return $placeholder->leaderboard; }); @@ -114,13 +119,13 @@ public function getLeaderboardPlaceholders(): array { /** * Get leaderboard data for a specific leaderboard. * - * @param int $server_id Server ID to get this placeholder from. + * @param int $server_id Server ID to get this placeholder from. * @param string $placeholder_name Unique name of placeholder to get data for. * * @return array Array of leaderboard data. */ - public function getLeaderboardData(int $server_id, string $placeholder_name): array { - + public function getLeaderboardData(int $server_id, string $placeholder_name): array + { $sort = $this->getPlaceholder($server_id, sha1($placeholder_name))->leaderboard_sort; // We have to add 0 to value so mysql converts from the TEXT field to an integer value @@ -136,12 +141,13 @@ public function getLeaderboardData(int $server_id, string $placeholder_name): ar /** * Get placeholder data by server id and name of placeholder. * - * @param int $server_id Server ID to get this placeholder from, if it exists across multiple. + * @param int $server_id Server ID to get this placeholder from, if it exists across multiple. * @param string $placeholder_name Name of placeholder - must be hashed with sha1. * * @return object|null This placeholder's data, null if not exist. */ - public function getPlaceholder(int $server_id, string $placeholder_name): ?object { + public function getPlaceholder(int $server_id, string $placeholder_name): ?object + { foreach ($this->_all_placeholders as $placeholder) { if ($placeholder->server_id == $server_id && $placeholder->safe_name == $placeholder_name) { return $placeholder; diff --git a/core/classes/Misc/ProfilePostReactionContext.php b/core/classes/Misc/ProfilePostReactionContext.php index fd37e7c22e..d51da7bb6e 100644 --- a/core/classes/Misc/ProfilePostReactionContext.php +++ b/core/classes/Misc/ProfilePostReactionContext.php @@ -8,27 +8,32 @@ * @license MIT * @see ReactionContext, ReactionContextsManager */ -class ProfilePostReactionContext extends ReactionContext { - - public function name(): string { +class ProfilePostReactionContext extends ReactionContext +{ + public function name(): string + { return 'profile_post'; } - public function friendlyName(Language $language): string { + public function friendlyName(Language $language): string + { return $language->get('user', 'profile_posts_score'); } - public function getUserReceived(User $user): array { + public function getUserReceived(User $user): array + { return DB::getInstance()->query('SELECT r.reaction_id FROM nl2_user_profile_wall_posts_reactions r JOIN nl2_user_profile_wall_posts w ON r.post_id = w.id WHERE w.author_id = ?', [ - $user->data()->id + $user->data()->id, ])->results(); } - public function getUserGiven(User $user): array { + public function getUserGiven(User $user): array + { return DB::getInstance()->get('user_profile_wall_posts_reactions', ['user_id', $user->data()->id])->results(); } - public function validateReactable(int $reactable_id, User $user) { + public function validateReactable(int $reactable_id, User $user) + { // TODO check blocked? $result = DB::getInstance()->get('user_profile_wall_posts', ['id', $reactable_id]); @@ -39,9 +44,10 @@ public function validateReactable(int $reactable_id, User $user) { return false; } - public function hasReacted(User $user, Reaction $reaction, int $reactable_id) { + public function hasReacted(User $user, Reaction $reaction, int $reactable_id) + { $result = DB::getInstance()->get('user_profile_wall_posts_reactions', [ - ['post_id', $reactable_id], ['user_id', $user->data()->id], ['reaction_id', $reaction->id] + ['post_id', $reactable_id], ['user_id', $user->data()->id], ['reaction_id', $reaction->id], ]); if ($result->exists()) { @@ -51,7 +57,8 @@ public function hasReacted(User $user, Reaction $reaction, int $reactable_id) { return false; } - public function giveReaction(User $user, User $receiver, Reaction $reaction, int $reactable_id): void { + public function giveReaction(User $user, User $receiver, Reaction $reaction, int $reactable_id): void + { DB::getInstance()->insert('user_profile_wall_posts_reactions', [ 'post_id' => $reactable_id, 'user_id' => $user->data()->id, @@ -60,19 +67,23 @@ public function giveReaction(User $user, User $receiver, Reaction $reaction, int ]); } - public function deleteReaction(int $reactable_reaction_id): void { + public function deleteReaction(int $reactable_reaction_id): void + { DB::getInstance()->delete('user_profile_wall_posts_reactions', $reactable_reaction_id); } - public function getAllReactions(int $reactionable_id): array { + public function getAllReactions(int $reactionable_id): array + { return DB::getInstance()->get('user_profile_wall_posts_reactions', ['post_id', $reactionable_id])->results(); } - public function reactionUserIdColumn(): string { + public function reactionUserIdColumn(): string + { return 'user_id'; } - public function determineReceiver(object $reactable): User { + public function determineReceiver(object $reactable): User + { return new User(DB::getInstance()->get('user_profile_wall_posts', ['id', $reactable->id])->first()->author_id); } } diff --git a/core/classes/Misc/ReactionContext.php b/core/classes/Misc/ReactionContext.php index 465c141ed2..084c0e1564 100644 --- a/core/classes/Misc/ReactionContext.php +++ b/core/classes/Misc/ReactionContext.php @@ -7,23 +7,24 @@ * @version 2.2.0 * @license MIT */ -abstract class ReactionContext { - +abstract class ReactionContext +{ /** * @return string Name of the reaction context which should be used when calling the `/queries/reactions` endpoint as the `context` parameter. */ abstract public function name(): string; /** - * @param Language $language Language to get the friendly name in. - * @return string Friendly name of the reaction context. Used when displaying scores in the Reactions profile widget + * @param Language $language Language to get the friendly name in. + * @return string Friendly name of the reaction context. Used when displaying scores in the Reactions profile widget */ abstract public function friendlyName(Language $language): string; /** * @return bool Whether this reaction context is enabled. If false, the reaction context will not be available for use. */ - public function isEnabled(): bool { + public function isEnabled(): bool + { return true; } @@ -32,7 +33,7 @@ public function isEnabled(): bool { * This should return data from the contexts table which contains the reactionable ID, * the reaction ID, and the user ID of the user who gave the reaction. * - * @param User $user User to get the reactions for. + * @param User $user User to get the reactions for. * @return array Array of reactions that the user has received in this context. */ abstract public function getUserReceived(User $user): array; @@ -42,7 +43,7 @@ abstract public function getUserReceived(User $user): array; * This should return data from the contexts table which contains the reactionable ID, * the reaction ID, and the user ID of the user who gave the reaction. * - * @param User $user User to get the reactions for. + * @param User $user User to get the reactions for. * @return array Array of reactions that the user has given in this context. */ abstract public function getUserGiven(User $user): array; @@ -65,10 +66,10 @@ abstract public function hasReacted(User $user, Reaction $reaction, int $reactab /** * Record a reaction being given for a given reactable. * - * @param User $user User who is giving the reaction. - * @param User $receiver User who is receiving the reaction (generally the owner of the reactionable object). - * @param Reaction $reaction Reaction to give. - * @param int $reactable_id ID of the reactable that the user is reacting to. + * @param User $user User who is giving the reaction. + * @param User $receiver User who is receiving the reaction (generally the owner of the reactionable object). + * @param Reaction $reaction Reaction to give. + * @param int $reactable_id ID of the reactable that the user is reacting to. */ abstract public function giveReaction(User $user, User $receiver, Reaction $reaction, int $reactable_id): void; @@ -82,7 +83,7 @@ abstract public function deleteReaction(int $reactable_reaction_id): void; /** * Get all the reactions that have been given to the given reactionable. * - * @param int $reactionable_id ID of the reactionable to get the reactions for. + * @param int $reactionable_id ID of the reactionable to get the reactions for. * @return array Array of reactions that have been given to the given reactionable. */ abstract public function getAllReactions(int $reactionable_id): array; @@ -100,8 +101,8 @@ abstract public function reactionUserIdColumn(): string; * Determine which User owns the given reactable. * Used to give them a reaction point. * - * @param object $reactable Reactable object to get the receiver for. - * @return User User who owns the given reactable. + * @param object $reactable Reactable object to get the receiver for. + * @return User User who owns the given reactable. */ abstract public function determineReceiver(object $reactable): User; } diff --git a/core/classes/Misc/ReactionContextsManager.php b/core/classes/Misc/ReactionContextsManager.php index 8549451332..6e40776c49 100644 --- a/core/classes/Misc/ReactionContextsManager.php +++ b/core/classes/Misc/ReactionContextsManager.php @@ -8,9 +8,9 @@ * @license MIT * @see ReactionContext */ -class ReactionContextsManager extends Instanceable { - - /** @var ReactionContext[] */ +class ReactionContextsManager extends Instanceable +{ + /** @var ReactionContext[] */ private array $_contexts = []; /** @@ -18,17 +18,19 @@ class ReactionContextsManager extends Instanceable { * * @param ReactionContext $context Reaction context to register. */ - public function provideContext(ReactionContext $context): void { + public function provideContext(ReactionContext $context): void + { $this->_contexts[$context->name()] = $context; } /** * Get a reaction context by name. * - * @param string $name Name of reaction context to get. + * @param string $name Name of reaction context to get. * @return ReactionContext|null Reaction context with the given name, or throws error if it does not exist. */ - public function getContext(string $name): ?ReactionContext { + public function getContext(string $name): ?ReactionContext + { if (!isset($this->_contexts[$name])) { throw new InvalidArgumentException('Invalid reaction context name: ' . $name); } @@ -41,7 +43,8 @@ public function getContext(string $name): ?ReactionContext { * * @return ReactionContext[] All registered reaction contexts. */ - public function getContexts(): array { + public function getContexts(): array + { return $this->_contexts; } @@ -50,7 +53,8 @@ public function getContexts(): array { * * @return string[] All valid reaction context names. */ - public function validContextNames(): array { + public function validContextNames(): array + { return array_map(static function (ReactionContext $context) { return $context->name(); }, $this->enabledContexts()); @@ -59,10 +63,11 @@ public function validContextNames(): array { /** * Get all valid reaction context friendly names. * - * @param Language $language Language to translate friendly names in. + * @param Language $language Language to translate friendly names in. * @return string[] All valid reaction context friendly names. */ - public function validContextFriendlyNames(Language $language): array { + public function validContextFriendlyNames(Language $language): array + { return array_map(static function (ReactionContext $context) use ($language) { return $context->friendlyName($language); }, $this->enabledContexts()); @@ -73,7 +78,8 @@ public function validContextFriendlyNames(Language $language): array { * * @return ReactionContext[] All enabled reaction contexts. */ - private function enabledContexts(): array { + private function enabledContexts(): array + { return array_filter($this->_contexts, static function (ReactionContext $context) { return $context->isEnabled(); }); diff --git a/core/classes/Misc/Report.php b/core/classes/Misc/Report.php index 03087e6ab3..b592f29a53 100644 --- a/core/classes/Misc/Report.php +++ b/core/classes/Misc/Report.php @@ -1,26 +1,27 @@ insert('reports', array_merge($data, [ @@ -39,7 +40,7 @@ public static function create(Language $language, User $user_reporting, User $re $groups = '('; foreach ($moderator_groups as $group) { if (is_numeric($group->id)) { - $groups .= ((int)$group->id) . ','; + $groups .= ((int) $group->id) . ','; } } $groups = rtrim($groups, ',') . ')'; diff --git a/core/classes/Misc/Text.php b/core/classes/Misc/Text.php index 1a12bd6bc9..69fa1e8a35 100644 --- a/core/classes/Misc/Text.php +++ b/core/classes/Misc/Text.php @@ -11,8 +11,8 @@ * @version 2.0.0 * @license MIT */ -class Text { - +class Text +{ /** * Truncates text. * @@ -27,14 +27,15 @@ class Text { * @link http://book.cakephp.org/view/1469/Text#truncate-1625 * @link https://github.com/cakephp/cakephp/blob/master/LICENSE * - * @param string $text String to truncate. - * @param int $length Length of returned string, including ellipsis. - * @param array $options An array of html attributes and options. + * @param string $text String to truncate. + * @param int $length Length of returned string, including ellipsis. + * @param array $options An array of html attributes and options. * @return string Trimmed string. */ - public static function truncate(string $text, int $length = 750, array $options = []): string { + public static function truncate(string $text, int $length = 750, array $options = []): string + { $default = [ - 'ending' => '...', 'exact' => true, 'html' => false + 'ending' => '...', 'exact' => true, 'html' => false, ]; $options = array_merge($default, $options); extract($options); @@ -125,28 +126,30 @@ public static function truncate(string $text, int $length = 750, array $options * Wrap text in HTML `` tags. Used for when variables in translations are bolded, * since we want as little HTML in the translation strings as possible. * - * @param string $text Text to wrap + * @param string $text Text to wrap * @return string Text wrapped in `` tags */ - public static function bold(string $text): string { + public static function bold(string $text): string + { return '' . $text . ''; } /** * Replace emojis with their style equivalent. * - * @param string $text Text to parse - * @param string|null $force_style Style to apply to the emoji image, will use the site default if null - * @return string Text with emojis replaced with URLs to their Twemoji equivalent. + * @param string $text Text to parse + * @param string|null $force_style Style to apply to the emoji image, will use the site default if null + * @return string Text with emojis replaced with URLs to their Twemoji equivalent. */ - public static function renderEmojis(string $text, string $force_style = null): string { + public static function renderEmojis(string $text, string $force_style = null): string + { $style = $force_style ?? Settings::get('emoji_style', 'twemoji'); switch ($style) { case 'twemoji': return Twemoji::text($text)->toHtml(); case 'joypixels': // Jank workaround can be removed if/when https://github.com/joypixels/emoji-toolkit/issues/55 is implemented - return (new class extends Client { + return (new class() extends Client { public $emojiSize = '64'; public $ignoredRegexp = ''; })->toImage($text); @@ -157,10 +160,11 @@ public static function renderEmojis(string $text, string $force_style = null): s } /** - * @param string|null $content HTML content to use in Discord embed - * @return string HTML content with tags removed and newlines converted to Discord's linebreaks + * @param string|null $content HTML content to use in Discord embed + * @return string HTML content with tags removed and newlines converted to Discord's linebreaks */ - public static function embedSafe(?string $content): string { + public static function embedSafe(?string $content): string + { if ($content === null) { return ''; } diff --git a/core/classes/Misc/UpgradeScript.php b/core/classes/Misc/UpgradeScript.php index 94b6b83be3..a2c48d132c 100644 --- a/core/classes/Misc/UpgradeScript.php +++ b/core/classes/Misc/UpgradeScript.php @@ -7,23 +7,25 @@ * @version 2.0.0-pr13 * @license MIT */ -abstract class UpgradeScript { - +abstract class UpgradeScript +{ protected Cache $_cache; - public function __construct() { + public function __construct() + { $this->_cache = new Cache( ['name' => 'nameless', 'extension' => '.cache', 'path' => ROOT_PATH . '/cache/'] ); } /** - * Get instance of UpgradeScript for a specific NamelessMC version, null if it doesn't exist + * Get instance of UpgradeScript for a specific NamelessMC version, null if it doesn't exist. * - * @param string $current_version Current NamelessMC version (ie: `2.0.0-pr12`, `2.0.0`) + * @param string $current_version Current NamelessMC version (ie: `2.0.0-pr12`, `2.0.0`) * @return UpgradeScript|null Instance of UpgradeScript from file */ - public static function get(string $current_version): ?UpgradeScript { + public static function get(string $current_version): ?UpgradeScript + { $path = ROOT_PATH . '/core/includes/updates/' . str_replace('.', '', $current_version) . '.php'; if (!file_exists($path)) { @@ -34,7 +36,7 @@ public static function get(string $current_version): ?UpgradeScript { } /** - * Execute this UpgradeScript + * Execute this UpgradeScript. */ abstract public function run(): void; @@ -43,28 +45,31 @@ abstract public function run(): void; * * @param string $message Message to log */ - protected function log(string $message): void { + protected function log(string $message): void + { echo $message . '
    '; ErrorHandler::logWarning('UPGRADING EXCEPTION: ' . $message); } /** - * Run a single database query + * Run a single database query. * - * @param Closure $query Function which returns the query - * @return mixed The result of the closure, if any + * @param Closure $query Function which returns the query + * @return mixed The result of the closure, if any */ - protected function databaseQuery(Closure $query) { + protected function databaseQuery(Closure $query) + { return $this->databaseQueries([$query])[0]; } /** - * Run multiple queries + * Run multiple queries. * - * @param Closure[] $queries Array of queries to execute one after another - * @return array Results from queries in order + * @param Closure[] $queries Array of queries to execute one after another + * @return array Results from queries in order */ - protected function databaseQueries(array $queries): array { + protected function databaseQueries(array $queries): array + { $results = []; foreach ($queries as $query) { @@ -80,25 +85,24 @@ protected function databaseQueries(array $queries): array { } /** - * Delete one or more folders or files in a path + * Delete one or more folders or files in a path. * - * @param string $path Prefix path to append to each of the files in `$files` array - * @param array $files Name of folders/files in `$path` to delete. Use `*` for all folders/files - * @param bool $recursive Whether to recursively delete + * @param string $path Prefix path to append to each of the files in `$files` array + * @param array $files Name of folders/files in `$path` to delete. Use `*` for all folders/files + * @param bool $recursive Whether to recursively delete */ - protected function deleteFilesInPath(string $path, array $files, bool $recursive = false): void { + protected function deleteFilesInPath(string $path, array $files, bool $recursive = false): void + { if (in_array('*', $files)) { $files = scandir($path); } foreach ($files as $file) { - if ($file[0] == '.') { continue; } if (file_exists($newFile = implode(DIRECTORY_SEPARATOR, [$path, $file]))) { - if (is_dir($newFile)) { if ($recursive) { $this->deleteFilesInPath($newFile, ['*'], true); @@ -107,20 +111,19 @@ protected function deleteFilesInPath(string $path, array $files, bool $recursive } else { $this->deleteFiles($newFile); } - } else { $this->log("'$newFile' does not exist, cannot delete."); } - } } /** - * Delete a single folder or file + * Delete a single folder or file. * * @param string|array $paths Path to folder or file to delete */ - protected function deleteFiles($paths): void { + protected function deleteFiles($paths): void + { foreach ((array) $paths as $path) { $path = ROOT_PATH . '/' . $path; if (!file_exists($path)) { @@ -130,6 +133,7 @@ protected function deleteFiles($paths): void { if (!is_writable($path)) { $this->log("'$path' is not writable, cannot delete."); + return; } @@ -144,7 +148,8 @@ protected function deleteFiles($paths): void { /** * Execute any pending database migrations. */ - protected function runMigrations(): void { + protected function runMigrations(): void + { PhinxAdapter::migrate('Core'); } @@ -153,7 +158,8 @@ protected function runMigrations(): void { * * @param string $version Version to set */ - protected function setVersion(string $version): void { + protected function setVersion(string $version): void + { Settings::set('nameless_version', $version); Settings::set('version_update', null); } diff --git a/core/classes/Queue/Queue.php b/core/classes/Queue/Queue.php index 6f1865ca25..7ce721f4b0 100644 --- a/core/classes/Queue/Queue.php +++ b/core/classes/Queue/Queue.php @@ -1,6 +1,6 @@ getTask()) { return false; } @@ -25,7 +27,7 @@ public static function schedule(Task $task): bool { $db = DB::getInstance(); $db->query( - <<query( - << '?', $tasks)); + $in = implode(',', array_map(static fn () => '?', $tasks)); $db->query("UPDATE nl2_queue SET `status` = ? WHERE `id` IN ($in)", [Task::STATUS_IN_PROGRESS, ...array_keys($tasks)]); foreach ($tasks as $id => $task) { @@ -109,7 +112,7 @@ public static function process(Container $container): array { try { /** @var Task $instance */ - $instance = (new $task['task'])->fromId($id); + $instance = (new $task['task']())->fromId($id); $instance->setContainer($container); $status = $instance->run(); @@ -124,7 +127,6 @@ public static function process(Container $container): array { $fragmentNext = $instance->getFragmentNext(); $fragment = $fragmentNext ? ',`fragment_next` = ?' : ''; } - } catch (Exception $e) { $status = $attempts >= 3 ? Task::STATUS_FAILED : Task::STATUS_ERROR; $output = ['error' => "Unable to execute task {$task['name']}: {$e->getMessage()}"]; @@ -171,11 +173,12 @@ public static function process(Container $container): array { } /** - * Cancel a task by ID + * Cancel a task by ID. * * @param int $taskId */ - public static function cancelTaskById(int $taskId): void { + public static function cancelTaskById(int $taskId): void + { DB::getInstance()->update('queue', $taskId, [ 'status' => Task::STATUS_CANCELLED, ]); @@ -183,11 +186,12 @@ public static function cancelTaskById(int $taskId): void { } /** - * Requeue a task by ID + * Requeue a task by ID. * * @param int $taskId */ - public static function requeueTaskById(int $taskId): void { + public static function requeueTaskById(int $taskId): void + { DB::getInstance()->update('queue', $taskId, [ 'status' => Task::STATUS_READY, ]); diff --git a/core/classes/Queue/Task.php b/core/classes/Queue/Task.php index 1aa14a27c6..92dddd54f6 100644 --- a/core/classes/Queue/Task.php +++ b/core/classes/Queue/Task.php @@ -1,6 +1,6 @@ query('SELECT * FROM nl2_queue WHERE `id` = ?', [$id]); if ($task->count()) { @@ -163,16 +166,16 @@ public function fromId(int $id): ?Task { } /** - * Initialise new task - * @param int $moduleId Module ID to which this task belongs - * @param string $name Name of the task - * @param ?array $data Any data which needs passing into the task when it executes - * @param int $scheduledFor Unix timestamp representing the earliest time from which the task will be executed - * @param ?string $entity Optional entity the task is associated with - * @param ?int $entityId Optional entity ID the task is associated with - * @param bool $fragment Whether to fragment the task's execution or not (split up into multiple runs) - * @param ?int $fragmentTotal Total number of items which need processing if fragmenting - * @param ?int $userId Optional user ID which triggered this task's execution + * Initialise new task. + * @param int $moduleId Module ID to which this task belongs + * @param string $name Name of the task + * @param ?array $data Any data which needs passing into the task when it executes + * @param int $scheduledFor Unix timestamp representing the earliest time from which the task will be executed + * @param ?string $entity Optional entity the task is associated with + * @param ?int $entityId Optional entity ID the task is associated with + * @param bool $fragment Whether to fragment the task's execution or not (split up into multiple runs) + * @param ?int $fragmentTotal Total number of items which need processing if fragmenting + * @param ?int $userId Optional user ID which triggered this task's execution * * @return Task */ @@ -204,101 +207,115 @@ public function fromNew( /** * @return int|null */ - public function getId(): ?int { + public function getId(): ?int + { return $this->_id; } /** - * @param array $data + * @param array $data * @return void */ - public function setData(array $data = []) { + public function setData(array $data = []) + { $this->_data = $data; } /** * @return array */ - public function getData(): array { + public function getData(): array + { return $this->_data ?? []; } /** - * @param array $output + * @param array $output * @return void */ - public function setOutput(array $output = []) { + public function setOutput(array $output = []) + { $this->_output = $output; } /** - * @param Container $container + * @param Container $container * @return void */ - public function setContainer(Container $container) { + public function setContainer(Container $container) + { $this->_container = $container; } /** * @return array */ - public function getOutput(): array { + public function getOutput(): array + { return $this->_output ?? []; } /** * @return ?int */ - public function getAttempts(): ?int { + public function getAttempts(): ?int + { return $this->_attempts; } /** * @return ?string */ - public function getEntity(): ?string { + public function getEntity(): ?string + { return $this->_entity; } /** * @return ?int */ - public function getEntityId(): ?int { + public function getEntityId(): ?int + { return $this->_entityId; } /** * @return ?int */ - public function getExecutedAt(): ?int { + public function getExecutedAt(): ?int + { return $this->_executedAt; } /** * @return int */ - public function getModuleId(): int { + public function getModuleId(): int + { return $this->_moduleId; } /** * @return string */ - public function getTask(): string { + public function getTask(): string + { return $this->_task; } /** * @return string */ - public function getName(): string { + public function getName(): string + { return $this->_name; } /** * @return int */ - public function getScheduledFor(): int { + public function getScheduledFor(): int + { return $this->_scheduledFor; } @@ -306,49 +323,55 @@ public function getScheduledFor(): int { * Will this task be fragmented? * @return bool */ - public function getWillFragment(): bool { + public function getWillFragment(): bool + { return $this->_fragment; } /** * @return ?int */ - public function getFragmentTotal(): ?int { + public function getFragmentTotal(): ?int + { return $this->_fragmentTotal; } /** - * @param int $next Index to resume processing on next time the task is run + * @param int $next Index to resume processing on next time the task is run * @return void */ - public function setFragmentNext(int $next) { + public function setFragmentNext(int $next) + { $this->_fragmentNext = $next; } /** * @return ?int */ - public function getFragmentNext(): ?int { + public function getFragmentNext(): ?int + { return $this->_fragmentNext; } /** * @return string */ - public function getStatus(): string { + public function getStatus(): string + { return $this->_status; } /** * @return ?int */ - public function getUserId(): ?int { + public function getUserId(): ?int + { return $this->_userId; } /** - * Run the task + * Run the task. * @return string Status of task following execution */ - abstract function run(): string; + abstract public function run(): string; } diff --git a/core/classes/Templates/AssetResolver.php b/core/classes/Templates/AssetResolver.php index 5cea8f67b5..90d991523d 100644 --- a/core/classes/Templates/AssetResolver.php +++ b/core/classes/Templates/AssetResolver.php @@ -9,8 +9,8 @@ * @version 2.0.0-pr13 * @license MIT */ -class AssetResolver extends AssetTree { - +class AssetResolver extends AssetTree +{ /** * @var array Array of assets currently resolved. */ @@ -21,7 +21,8 @@ class AssetResolver extends AssetTree { * * @param string|array $assets The asset(s) to resolve and add. Must be a constant from the `AssetTree` class. */ - public function include($assets): void { + public function include($assets): void + { if (!is_array($assets)) { $assets = [$assets]; } @@ -39,11 +40,12 @@ public function include($assets): void { * * @return array> The resolved assets ready to be added to the template. */ - public function compile(): array { + public function compile(): array + { $css = []; $js = []; - $assets = Util::determineOrder(array_map(static function(string $key, array $value) { + $assets = Util::determineOrder(array_map(static function (string $key, array $value) { return [ 'name' => $key, 'after' => $value['depends'] ?? $value['after'] ?? [], @@ -62,12 +64,13 @@ public function compile(): array { * Generate URLs for the given asset, and add them to the CSS and JS URL arrays as needed. * This will also resolve and gather dependencies for the asset if applicable. * - * @param string $name The name of the asset. - * @param array $asset The asset to gather. - * @param array $css Array of CSS assets already resolved to add to. - * @param array $js Array of JS assets already resolved to add to. + * @param string $name The name of the asset. + * @param array $asset The asset to gather. + * @param array $css Array of CSS assets already resolved to add to. + * @param array $js Array of JS assets already resolved to add to. */ - private function gatherAsset(string $name, array $asset, array &$css, array &$js): void { + private function gatherAsset(string $name, array $asset, array &$css, array &$js): void + { // Load the dependencies first so that they're the first to be added to the HTML if (isset($asset['depends'])) { foreach ($asset['depends'] as $dependency) { @@ -111,11 +114,12 @@ private function gatherAsset(string $name, array $asset, array &$css, array &$js * Validate that an asset name is valid. * This checks that it exists in the asset tree, and that it has not already been resolved. * - * @param string $assetName The asset name to validate. - * @return bool False if the asset name is invalid, true otherwise. + * @param string $assetName The asset name to validate. * @throws InvalidArgumentException If the asset name is invalid or if it has already been resolved. + * @return bool False if the asset name is invalid, true otherwise. */ - private function validateAsset(string $assetName, bool $throw = true): bool { + private function validateAsset(string $assetName, bool $throw = true): bool + { if (!array_key_exists($assetName, parent::ASSET_TREE)) { if ($throw) { throw new InvalidArgumentException('Asset "' . $assetName . '" is not defined'); @@ -138,11 +142,12 @@ private function validateAsset(string $assetName, bool $throw = true): bool { /** * Build an HTML tag for the given asset. * - * @param string $file The file to build the path for. - * @param string $type The type of the file, either 'css' or 'js' + * @param string $file The file to build the path for. + * @param string $type The type of the file, either 'css' or 'js' * @return string Script or Link HTML tag with a URL to the asset. */ - private function buildPath(string $file, string $type): string { + private function buildPath(string $file, string $type): string + { $href = (defined('CONFIG_PATH') ? CONFIG_PATH : '') diff --git a/core/classes/Templates/AssetTree.php b/core/classes/Templates/AssetTree.php index a89b1c28ed..ed82ef3b91 100644 --- a/core/classes/Templates/AssetTree.php +++ b/core/classes/Templates/AssetTree.php @@ -10,8 +10,8 @@ * @version 2.0.0-pr13 * @license MIT */ -class AssetTree { - +class AssetTree +{ /** * @var string Font Awesome v6.1 (CSS) */ @@ -87,12 +87,12 @@ class AssetTree { /** * @var mixed Tree of all available assets, with their applicable CSS/JS files. - * In the case an asset depends on other assets within the tree, they are defined as "depends". + * In the case an asset depends on other assets within the tree, they are defined as "depends". */ protected const ASSET_TREE = [ self::FONT_AWESOME => [ 'css' => [ - 'vendor/@fortawesome/fontawesome-free/css/all.min.css' + 'vendor/@fortawesome/fontawesome-free/css/all.min.css', ], ], self::BOOTSTRAP => [ @@ -104,7 +104,7 @@ class AssetTree { ], 'after' => [ self::JQUERY_UI, - ] + ], ], self::BOOTSTRAP_COLORPICKER => [ 'css' => [ @@ -252,7 +252,7 @@ class AssetTree { ], 'after' => [ self::JQUERY, - ] + ], ], ]; } diff --git a/core/classes/Templates/TemplateBase.php b/core/classes/Templates/TemplateBase.php index 235b3cf856..1b4c004ddb 100644 --- a/core/classes/Templates/TemplateBase.php +++ b/core/classes/Templates/TemplateBase.php @@ -7,8 +7,8 @@ * @version 2.0.0-pr13 * @license MIT */ -abstract class TemplateBase { - +abstract class TemplateBase +{ /** * @var string The template name */ @@ -46,7 +46,8 @@ abstract class TemplateBase { */ protected array $_js = []; - public function __construct(string $name, string $version, string $nameless_version, string $author) { + public function __construct(string $name, string $version, string $nameless_version, string $author) + { $this->_name = $name; $this->_version = $version; $this->_nameless_version = $nameless_version; @@ -58,7 +59,8 @@ public function __construct(string $name, string $version, string $nameless_vers */ abstract public function onPageLoad(); - public function assets(): AssetResolver { + public function assets(): AssetResolver + { return $this->_assets_resolver ??= new AssetResolver(); } @@ -67,7 +69,8 @@ public function assets(): AssetResolver { * * @param array $files Files to be loaded. */ - public function addCSSFiles(array $files): void { + public function addCSSFiles(array $files): void + { if (count($files)) { foreach ($files as $href => $file) { $this->_css[] = ' @@ -87,7 +90,8 @@ public function addCSSFiles(array $files): void { * * @param string|null $style Styling to add. */ - public function addCSSStyle(string $style = null): void { + public function addCSSStyle(string $style = null): void + { if ($style) { $this->_css[] = ''; } @@ -98,7 +102,8 @@ public function addCSSStyle(string $style = null): void { * * @param array $files Files to be loaded. */ - public function addJSFiles(array $files): void { + public function addJSFiles(array $files): void + { if (count($files)) { foreach ($files as $href => $file) { $this->_js[] = ' @@ -118,7 +123,8 @@ public function addJSFiles(array $files): void { * * @param string|null $script */ - public function addJSScript(string $script = null): void { + public function addJSScript(string $script = null): void + { if ($script) { $this->_js[] = ''; } @@ -129,7 +135,8 @@ public function addJSScript(string $script = null): void { * * @return string Name of template. */ - public function getName(): string { + public function getName(): string + { return $this->_name; } @@ -138,7 +145,8 @@ public function getName(): string { * * @return string Version of template. */ - public function getVersion(): string { + public function getVersion(): string + { return $this->_version; } @@ -147,7 +155,8 @@ public function getVersion(): string { * * @return string NamelessMC version of template. */ - public function getNamelessVersion(): string { + public function getNamelessVersion(): string + { return $this->_nameless_version; } @@ -156,7 +165,8 @@ public function getNamelessVersion(): string { * * @return string Author name of template. */ - public function getAuthor(): string { + public function getAuthor(): string + { return $this->_author; } @@ -165,14 +175,16 @@ public function getAuthor(): string { * * @return string Settings URL of template. */ - public function getSettings(): string { + public function getSettings(): string + { return $this->_settings; } /** * Render this template with Smarty engine. */ - public function displayTemplate(string $template, Smarty $smarty): void { + public function displayTemplate(string $template, Smarty $smarty): void + { [$css, $js] = $this->assets()->compile(); // Put the assets at the start of the arrays, so they load first (SBAdmin requires JQuery first, etc.) @@ -181,14 +193,14 @@ public function displayTemplate(string $template, Smarty $smarty): void { $smarty->assign([ 'TEMPLATE_CSS' => $this->getCSS(), - 'TEMPLATE_JS' => $this->getJS() + 'TEMPLATE_JS' => $this->getJS(), ]); if (defined('PHPDEBUGBAR') && PHPDEBUGBAR) { $debugBar = DebugBarHelper::getInstance()->getDebugBar()->getJavascriptRenderer(); $smarty->assign([ 'DEBUGBAR_JS' => $debugBar->renderHead(), - 'DEBUGBAR_HTML' => $debugBar->render() + 'DEBUGBAR_HTML' => $debugBar->render(), ]); } @@ -200,7 +212,8 @@ public function displayTemplate(string $template, Smarty $smarty): void { * * @return array Array of strings of CSS. */ - public function getCSS(): array { + public function getCSS(): array + { return $this->_css; } @@ -209,14 +222,16 @@ public function getCSS(): array { * * @return array Array of strings of JS. */ - public function getJS(): array { + public function getJS(): array + { return $this->_js; } - public function getTemplate(string $template, Smarty $smarty): string { + public function getTemplate(string $template, Smarty $smarty): string + { $smarty->assign([ 'TEMPLATE_CSS' => $this->getCSS(), - 'TEMPLATE_JS' => $this->getJS() + 'TEMPLATE_JS' => $this->getJS(), ]); return $smarty->fetch($template); diff --git a/core/classes/Widgets/AbstractWidget.php b/core/classes/Widgets/AbstractWidget.php index 21dea1d9a5..9c963bab41 100644 --- a/core/classes/Widgets/AbstractWidget.php +++ b/core/classes/Widgets/AbstractWidget.php @@ -1,7 +1,7 @@ _name; } @@ -27,7 +28,8 @@ public function getName(): string { * * @return string Location of widget. */ - public function getLocation(): string { + public function getLocation(): string + { return $this->getData()->location; } @@ -36,7 +38,8 @@ public function getLocation(): string { * * @return string Widget settings URL. */ - public function getSettings(): ?string { + public function getSettings(): ?string + { return $this->_settings; } @@ -45,7 +48,8 @@ public function getSettings(): ?string { * * @return string Description of widget. */ - public function getDescription(): string { + public function getDescription(): string + { return $this->_description; } @@ -54,7 +58,8 @@ public function getDescription(): string { * * @return string Name of module. */ - public function getModule(): string { + public function getModule(): string + { return $this->_module; } @@ -63,7 +68,8 @@ public function getModule(): string { * * @return int Display order of widget. */ - public function getOrder(): int { + public function getOrder(): int + { return $this->getData()->order; } @@ -72,7 +78,8 @@ public function getOrder(): int { * * @return Smarty Instance in use. */ - public function getSmarty(): ?Smarty { + public function getSmarty(): ?Smarty + { return $this->_smarty; } @@ -85,7 +92,8 @@ public function getSmarty(): ?Smarty { * * @return string Content/HTML of this widget. */ - public function display(): string { + public function display(): string + { if (defined('COOKIE_CHECK') && !COOKIES_ALLOWED && $this->_requires_cookies) { return $this->_smarty->fetch('widgets/cookie_notice.tpl'); } @@ -103,7 +111,8 @@ abstract public function getPages(): array; /** * Clear the cache for this widget, should be called when any settings of it are changed. */ - final public function clearCache(): void { + final public function clearCache(): void + { $this->cache()->erase($this->getName()); } @@ -113,7 +122,8 @@ final public function clearCache(): void { * * @return WidgetData Widget data. */ - protected function getData(): WidgetData { + protected function getData(): WidgetData + { if (isset($this->_data)) { return $this->_data; } @@ -147,9 +157,10 @@ protected function getData(): WidgetData { return $this->_data = $data; } - private function cache(): Cache { + private function cache(): Cache + { $cache = $this->_cache ??= new Cache([ - 'name' => 'nameless', 'extension' => '.cache', 'path' => ROOT_PATH . '/cache/' + 'name' => 'nameless', 'extension' => '.cache', 'path' => ROOT_PATH . '/cache/', ]); $cache->setCache( diff --git a/core/classes/Widgets/ProfileWidgetBase.php b/core/classes/Widgets/ProfileWidgetBase.php index 36e1d1a6f3..32f58c2f35 100644 --- a/core/classes/Widgets/ProfileWidgetBase.php +++ b/core/classes/Widgets/ProfileWidgetBase.php @@ -1,10 +1,11 @@ getData()->pages; } } diff --git a/core/classes/Widgets/WidgetData.php b/core/classes/Widgets/WidgetData.php index fd49abf101..c08c6c3f4a 100644 --- a/core/classes/Widgets/WidgetData.php +++ b/core/classes/Widgets/WidgetData.php @@ -1,12 +1,13 @@ location = $data->location; $this->order = $data->order; $this->pages = is_array($data->pages) diff --git a/core/classes/Widgets/Widgets.php b/core/classes/Widgets/Widgets.php index 0e817f6d0b..b6c6965a15 100644 --- a/core/classes/Widgets/Widgets.php +++ b/core/classes/Widgets/Widgets.php @@ -1,14 +1,14 @@ _widgets[$widget->getName()] = $widget; } @@ -54,7 +55,8 @@ public function add(AbstractWidget $widget): void { * * @param AbstractWidget $widget Instance of widget to enable. */ - public function enable(AbstractWidget $widget): void { + public function enable(AbstractWidget $widget): void + { // Add widget to enabled widget list $this->_enabled[$widget->getName()] = true; $this->_cache->setCache($this->_name . '-widgets'); @@ -71,7 +73,8 @@ public function enable(AbstractWidget $widget): void { * * @param AbstractWidget $widget Instance of widget to disable. */ - public function disable(AbstractWidget $widget): void { + public function disable(AbstractWidget $widget): void + { unset($this->_enabled[$widget->getName()]); $this->_cache->setCache($this->_name . '-widgets'); $this->_cache->store('enabled', $this->_enabled); @@ -89,19 +92,21 @@ public function disable(AbstractWidget $widget): void { * * @return AbstractWidget|null Instance of widget with same name, null if it doesn't exist. */ - public function getWidget(string $name): ?AbstractWidget { + public function getWidget(string $name): ?AbstractWidget + { return $this->_widgets[$name] ?? null; } /** * Get code for all enabled widgets on the current page. * - * @param string $location Either `left` or `right`. + * @param string $location Either `left` or `right`. * @param User|null $profile_user User object of the profile page. * * @return array List of HTML to be displayed. */ - public function getWidgets(string $location, User $profile_user = null): array { + public function getWidgets(string $location, User $profile_user = null): array + { $ret = []; foreach ($this->getAll() as $item) { @@ -139,7 +144,7 @@ public function getWidgets(string $location, User $profile_user = null): array { $this->_smarty->assign([ 'WIDGET_ERROR_TITLE' => $this->_language->get('general', 'unable_to_load_widget'), 'WIDGET_ERROR_CONTENT' => $this->_language->get('general', 'problem_loading_widget', [ - 'widget' => Output::getClean($item->getName()) + 'widget' => Output::getClean($item->getName()), ]), 'WIDGET_ERROR_MESSAGE' => $e->getMessage(), 'WIDGET_NAME' => Output::getClean($item->getName()), @@ -156,7 +161,8 @@ public function getWidgets(string $location, User $profile_user = null): array { * * @return AbstractWidget[] List of widgets. */ - public function getAll(): iterable { + public function getAll(): iterable + { $widgets = $this->_widgets; uasort($widgets, static function (AbstractWidget $a, AbstractWidget $b) { @@ -173,7 +179,8 @@ public function getAll(): iterable { * * @return bool Whether this widget is enabled or not. */ - public function isEnabled(AbstractWidget $widget): bool { + public function isEnabled(AbstractWidget $widget): bool + { return array_key_exists($widget->getName(), $this->_enabled); } @@ -183,7 +190,8 @@ public function isEnabled(AbstractWidget $widget): bool { * * @return string Name of this instance. */ - public function getName(): string { + public function getName(): string + { return $this->_name; } } diff --git a/core/includes/image_upload.php b/core/includes/image_upload.php index 2fa6cb10f8..72304560db 100644 --- a/core/includes/image_upload.php +++ b/core/includes/image_upload.php @@ -138,7 +138,7 @@ $user->update([ 'has_avatar' => true, - 'avatar_updated' => date('U') + 'avatar_updated' => date('U'), ]); Session::flash('settings_success', $language->get('user', 'avatar_set_successfully')); @@ -147,7 +147,7 @@ if (Input::get('type') === 'profile_banner') { $user->update([ - 'banner' => Output::getClean($user->data()->id . '/' . $image->getName() . '.' . $image->getMime()) + 'banner' => Output::getClean($user->data()->id . '/' . $image->getName() . '.' . $image->getMime()), ]); Redirect::to(URL::build('/profile/' . urlencode($user->data()->username))); diff --git a/core/includes/maintenance.php b/core/includes/maintenance.php index 56d80c6717..4577acdf0c 100644 --- a/core/includes/maintenance.php +++ b/core/includes/maintenance.php @@ -19,7 +19,7 @@ $smarty->assign( [ 'LOGIN' => $language->get('general', 'sign_in'), - 'LOGIN_LINK' => URL::build('/login') + 'LOGIN_LINK' => URL::build('/login'), ] ); } @@ -29,7 +29,7 @@ [ 'MAINTENANCE_TITLE' => $language->get('errors', 'maintenance_title'), 'MAINTENANCE_MESSAGE' => Output::getPurified(Settings::get('maintenance_message', 'Maintenance mode is enabled.')), - 'RETRY' => $language->get('errors', 'maintenance_retry') + 'RETRY' => $language->get('errors', 'maintenance_retry'), ] ); diff --git a/core/includes/tfa_signin.php b/core/includes/tfa_signin.php index 80fc3a8b79..1215f47d9c 100644 --- a/core/includes/tfa_signin.php +++ b/core/includes/tfa_signin.php @@ -25,7 +25,7 @@ if (Session::exists('tfa_signin')) { $smarty->assign([ 'ERROR_TITLE' => $language->get('general', 'error'), - 'ERROR' => Session::flash('tfa_signin') + 'ERROR' => Session::flash('tfa_signin'), ]); } @@ -34,7 +34,7 @@ 'TWO_FACTOR_AUTH' => $language->get('user', 'two_factor_auth'), 'TFA_ENTER_CODE' => $language->get('user', 'tfa_enter_code'), 'TOKEN' => Token::get(), - 'SUBMIT' => $language->get('general', 'submit') + 'SUBMIT' => $language->get('general', 'submit'), ]); // Load modules + template diff --git a/core/includes/updates/210.php b/core/includes/updates/210.php index f7ea670b1b..3269acf2bc 100644 --- a/core/includes/updates/210.php +++ b/core/includes/updates/210.php @@ -1,6 +1,8 @@ runMigrations(); $this->setVersion('2.1.1'); diff --git a/core/includes/updates/211.php b/core/includes/updates/211.php index e176b1c176..fade2633a9 100644 --- a/core/includes/updates/211.php +++ b/core/includes/updates/211.php @@ -1,6 +1,8 @@ runMigrations(); $this->setVersion('2.1.2'); diff --git a/core/init.php b/core/init.php index b02d0778a1..bde3c923ca 100644 --- a/core/init.php +++ b/core/init.php @@ -34,7 +34,7 @@ ROOT_PATH . '/cache/sitemaps', ROOT_PATH . '/cache/templates_c', ROOT_PATH . '/uploads', - ROOT_PATH . '/core/config.php' + ROOT_PATH . '/core/config.php', ]; foreach ($writable_check_paths as $path) { @@ -60,6 +60,7 @@ if (isset($_GET['route']) && rtrim($_GET['route'], '/') == '/panel/upgrade') { $pages = new Pages(); $pages->add('Core', '/panel/upgrade', 'pages/panel/upgrade.php'); + return; } @@ -73,7 +74,7 @@ return new Cache([ 'name' => 'nameless', 'extension' => '.cache', - 'path' => ROOT_PATH . '/cache/' + 'path' => ROOT_PATH . '/cache/', ]); }); @@ -100,7 +101,7 @@ } else { Redirect::to('https://' . $host . $_SERVER['REQUEST_URI']); } - } else if (defined('FORCE_WWW') && !str_contains($host, 'www.')) { + } elseif (defined('FORCE_WWW') && !str_contains($host, 'www.')) { Redirect::to(HttpUtils::getProtocol() . '://www.' . $host . $_SERVER['REQUEST_URI']); } } @@ -200,7 +201,7 @@ define('DEFAULT_LANGUAGE', $default_language); - if (!$user->isLoggedIn() || !($user->data()->language_id)) { + if (!$user->isLoggedIn() || !$user->data()->language_id) { if (Settings::get('auto_language_detection') && (!Cookie::exists('auto_language') || Cookie::get('auto_language') === 'true')) { // Attempt to get the requested language from the browser if it exists $automatic_locale = Language::acceptFromHttp(HttpUtils::getHeader('Accept-Language') ?? ''); @@ -236,7 +237,7 @@ define('SITE_NAME', $sitename); // Template - if (!$user->isLoggedIn() || !($user->data()->theme_id)) { + if (!$user->isLoggedIn() || !$user->data()->theme_id) { // Default template for guests $cache->setCache('templatecache'); $template = $cache->retrieve('default'); @@ -313,7 +314,7 @@ 'explode', 'implode', 'strtolower', - 'strtoupper' + 'strtoupper', ]; $securityPolicy->php_functions = [ 'isset', @@ -326,7 +327,7 @@ 'nl2br', 'is_numeric', 'file_exists', - 'array_key_exists' + 'array_key_exists', ]; $securityPolicy->secure_dir = [ROOT_PATH . '/custom/templates', ROOT_PATH . '/custom/panel_templates']; $smarty->enableSecurity($securityPolicy); @@ -338,7 +339,7 @@ 'SITE_NAME' => Output::getClean(SITE_NAME), 'SITE_HOME' => URL::build('/'), 'USER_INFO_URL' => URL::build('/queries/user/', 'id='), - 'GUEST' => $language->get('user', 'guest') + 'GUEST' => $language->get('user', 'guest'), ]); $cache->setCache('backgroundcache'); if ($cache->isCached('og_image')) { @@ -422,7 +423,7 @@ $cache->setCache('modulescache'); if (!$cache->isCached('enabled_modules')) { $cache->store('enabled_modules', [ - ['name' => 'Core', 'priority' => 1] + ['name' => 'Core', 'priority' => 1], ]); $cache->store('module_core', true); } @@ -438,7 +439,7 @@ if (!isset($core_exists)) { $enabled_modules[] = [ 'name' => 'Core', - 'priority' => 1 + 'priority' => 1, ]; } @@ -470,16 +471,16 @@ if (!$user->isLoggedIn() || !$user->canViewStaffCP()) { // Maintenance mode if (isset($_GET['route']) && ( - rtrim($_GET['route'], '/') === '/login' - || rtrim($_GET['route'], '/') === '/forgot_password' - || str_contains($_GET['route'], '/api/') - || str_contains($_GET['route'], 'queries') - || str_contains($_GET['route'], 'oauth/') - )) { + rtrim($_GET['route'], '/') === '/login' + || rtrim($_GET['route'], '/') === '/forgot_password' + || str_contains($_GET['route'], '/api/') + || str_contains($_GET['route'], 'queries') + || str_contains($_GET['route'], 'oauth/') + )) { // Can continue as normal } else { require(ROOT_PATH . '/core/includes/maintenance.php'); - die(); + die; } } else { // Display notice to admin stating maintenance mode is enabled @@ -512,7 +513,7 @@ 'action' => $hook->action == 1 ? [WebHook::class, 'execute'] : [DiscordHook::class, 'execute'], - 'events' => json_decode($hook->events, true) + 'events' => json_decode($hook->events, true), ]; } $cache->store('hooks', $hook_array); @@ -548,11 +549,11 @@ if (filter_var($ip, FILTER_VALIDATE_IP)) { $user->update([ 'last_online' => date('U'), - 'lastip' => $ip + 'lastip' => $ip, ]); } else { $user->update([ - 'last_online' => date('U') + 'last_online' => date('U'), ]); } @@ -562,7 +563,7 @@ // Create the entry now DB::getInstance()->insert('users_ips', [ 'user_id' => $user->data()->id, - 'ip' => $ip + 'ip' => $ip, ]); } else { if (count($user_ip_logged) > 1) { @@ -579,7 +580,7 @@ // Not yet logged, do so now DB::getInstance()->insert('users_ips', [ 'user_id' => $user->data()->id, - 'ip' => $ip + 'ip' => $ip, ]); } } else { @@ -587,7 +588,7 @@ if ($user_ip_logged[0]->user_id != $user->data()->id) { DB::getInstance()->insert('users_ips', [ 'user_id' => $user->data()->id, - 'ip' => $ip + 'ip' => $ip, ]); } } @@ -615,7 +616,7 @@ foreach ($user->getIntegrations() as $integrationUser) { $user_integrations[$integrationUser->getIntegration()->getName()] = [ 'username' => Output::getClean($integrationUser->data()->username), - 'identifier' => Output::getClean($integrationUser->data()->identifier) + 'identifier' => Output::getClean($integrationUser->data()->identifier), ]; } @@ -628,14 +629,14 @@ 'username_style' => $user->getGroupStyle(), 'user_title' => Output::getClean($user->data()->user_title), 'avatar' => $user->getAvatar(), - 'integrations' => $user_integrations + 'integrations' => $user_integrations, ]); // Panel access? if ($user->canViewStaffCP()) { $smarty->assign([ 'PANEL_LINK' => URL::build('/panel'), - 'PANEL' => $language->get('moderator', 'staff_cp') + 'PANEL' => $language->get('moderator', 'staff_cp'), ]); } } else { diff --git a/core/installation/includes/functions.php b/core/installation/includes/functions.php index 2b515bf25c..53e74ae2dd 100644 --- a/core/installation/includes/functions.php +++ b/core/installation/includes/functions.php @@ -1,4 +1,5 @@ "; - } -function create_field($type, $label, $name, $id, $value = '', $options = [], $fallback = false) { - +function create_field($type, $label, $name, $id, $value = '', $options = [], $fallback = false) +{ if ($type == 'select') { - $options_markup = ''; foreach ($options as $option_value => $option_label) { $selected = ($value == $option_value ? ' selected' : ($fallback ? ($value == $option_label ? ' selected' : '') : '')); @@ -51,22 +50,18 @@ function create_field($type, $label, $name, $id, $value = '', $options = [], $fa "; - } else { - echo "
    "; - } - } -function validate_requirement($text, $condition) { - +function validate_requirement($text, $condition) +{ if ($condition == true) { echo "
    @@ -90,5 +85,4 @@ function validate_requirement($text, $condition) { $_SESSION['requirements_validated'] = $condition; } } - } diff --git a/core/installation/steps/ajax_initialise.php b/core/installation/steps/ajax_initialise.php index ef3a637e77..88a4cdb039 100644 --- a/core/installation/steps/ajax_initialise.php +++ b/core/installation/steps/ajax_initialise.php @@ -1,4 +1,5 @@ addForeignKey('user_id', 'nl2_users', 'id', ['delete' => 'CASCADE', 'update' => 'CASCADE']) - ->addForeignKey('user_blocked_id', 'nl2_users', 'id', ['delete' => 'CASCADE', 'update' => 'CASCADE']);; + ->addForeignKey('user_blocked_id', 'nl2_users', 'id', ['delete' => 'CASCADE', 'update' => 'CASCADE']); $table ->addIndex(['user_id', 'user_blocked_id'], ['unique' => true]); diff --git a/core/migrations/20220518025652_create_groups_table.php b/core/migrations/20220518025652_create_groups_table.php index 7a4f22595f..b9703be56f 100644 --- a/core/migrations/20220518025652_create_groups_table.php +++ b/core/migrations/20220518025652_create_groups_table.php @@ -1,4 +1,5 @@ addColumn('expire', 'integer', ['length' => 11, 'default' => 0]); $table - ->addForeignKey('user_id', 'nl2_users', 'id', ['delete'=> 'CASCADE', 'update'=> 'CASCADE',]) - ->addForeignKey('group_id', 'nl2_groups', 'id', ['delete'=> 'CASCADE', 'update'=> 'CASCADE',]); + ->addForeignKey('user_id', 'nl2_users', 'id', ['delete' => 'CASCADE', 'update' => 'CASCADE']) + ->addForeignKey('group_id', 'nl2_groups', 'id', ['delete' => 'CASCADE', 'update' => 'CASCADE']); $table ->addIndex(['user_id', 'group_id'], ['unique' => true]); diff --git a/core/migrations/20220518031216_create_alerts_table.php b/core/migrations/20220518031216_create_alerts_table.php index 08020c9b06..60e366998a 100644 --- a/core/migrations/20220518031216_create_alerts_table.php +++ b/core/migrations/20220518031216_create_alerts_table.php @@ -1,4 +1,5 @@ table('nl2_settings'); $table->addColumn('module', 'string', ['length' => 32, 'null' => true, 'default' => null]); $table->removeIndex(['name']); $table->addIndex(['name', 'module'], ['unique' => true]); $table->update(); } - } diff --git a/core/migrations/20220620190645_move_email_settings_to_config.php b/core/migrations/20220620190645_move_email_settings_to_config.php index 09d6b21ff9..dfa6dafefc 100644 --- a/core/migrations/20220620190645_move_email_settings_to_config.php +++ b/core/migrations/20220620190645_move_email_settings_to_config.php @@ -1,11 +1,13 @@ assign([ - 'CC_NAV_LINKS' => $cc_nav->returnNav('top') -]); \ No newline at end of file + 'CC_NAV_LINKS' => $cc_nav->returnNav('top'), +]); diff --git a/core/templates/footer.php b/core/templates/footer.php index 966c51fc74..a3f6a57b3e 100644 --- a/core/templates/footer.php +++ b/core/templates/footer.php @@ -20,7 +20,7 @@ 'short' => 'fb', 'long' => 'facebook', 'link' => Output::getClean($social_media), - 'text' => 'Facebook' + 'text' => 'Facebook', ]; } @@ -31,7 +31,7 @@ 'short' => 'tw', 'long' => 'twitter', 'link' => Output::getClean($social_media), - 'text' => 'Twitter' + 'text' => 'Twitter', ]; } @@ -42,7 +42,7 @@ 'short' => 'gp', 'long' => 'youtube', 'link' => Output::getClean($social_media), - 'text' => 'YouTube' + 'text' => 'YouTube', ]; } @@ -51,7 +51,7 @@ $smarty->assign([ 'SOCIAL_MEDIA_ICONS' => $social_media_icons, 'PAGE_LOAD_TIME' => Settings::get('page_loading'), - 'FOOTER_NAVIGATION' => $navigation->returnNav('footer') + 'FOOTER_NAVIGATION' => $navigation->returnNav('footer'), ]); // Terms diff --git a/core/templates/frontend_init.php b/core/templates/frontend_init.php index 9a0d438f2f..ba0fd49864 100644 --- a/core/templates/frontend_init.php +++ b/core/templates/frontend_init.php @@ -25,11 +25,9 @@ if (defined('CONFIG_PATH')) { $_SESSION['last_page'] = substr($_SESSION['last_page'], strlen(CONFIG_PATH)); } - } else { $_SESSION['last_page'] = URL::build($_GET['route'] ?? '/'); } - } // Check if any integrations is required before user can continue @@ -75,7 +73,7 @@ 'GLOBAL_WARNING_TITLE' => $language->get('user', 'you_have_received_a_warning'), 'GLOBAL_WARNING_REASON' => Output::getClean($warning->reason), 'GLOBAL_WARNING_ACKNOWLEDGE' => $language->get('user', 'acknowledge'), - 'GLOBAL_WARNING_ACKNOWLEDGE_LINK' => URL::build('/user/acknowledge/' . urlencode($warning->id)) + 'GLOBAL_WARNING_ACKNOWLEDGE_LINK' => URL::build('/user/acknowledge/' . urlencode($warning->id)), ]); break; } @@ -127,7 +125,7 @@ } else { $smarty->assign([ 'PAGE_DESCRIPTION' => str_replace('{site}', Output::getClean(SITE_NAME), Output::getPurified(PAGE_DESCRIPTION)), - 'PAGE_KEYWORDS' => (defined('PAGE_KEYWORDS') ? Output::getPurified(PAGE_KEYWORDS) : '') + 'PAGE_KEYWORDS' => (defined('PAGE_KEYWORDS') ? Output::getPurified(PAGE_KEYWORDS) : ''), ]); } @@ -165,5 +163,5 @@ 'ENABLED' => $language->get('user', 'enabled'), 'DISABLED' => $language->get('user', 'disabled'), 'DARK_LIGHT_MODE_ACTION' => URL::build('/queries/dark_light_mode'), - 'DARK_LIGHT_MODE_TOKEN' => $user->isLoggedIn() ? Token::get() : null + 'DARK_LIGHT_MODE_TOKEN' => $user->isLoggedIn() ? Token::get() : null, ]); diff --git a/core/templates/navbar.php b/core/templates/navbar.php index 694a2b9a8d..5051c3c744 100644 --- a/core/templates/navbar.php +++ b/core/templates/navbar.php @@ -20,7 +20,7 @@ $user_area['usercp'] = [ 'target' => '', 'link' => URL::build('/user'), - 'title' => $language->get('user', 'user_cp') + 'title' => $language->get('user', 'user_cp'), ]; if (defined('PAGE') && PAGE == 'usercp') { $user_area['usercp']['active'] = true; @@ -34,35 +34,35 @@ 'profile' => [ 'link' => $user->getProfileURL(), 'target' => '', - 'title' => $language->get('user', 'profile') + 'title' => $language->get('user', 'profile'), ], 'separator1' => [ - 'separator' => true + 'separator' => true, ], 'user' => [ 'link' => URL::build('/user'), 'target' => '', - 'title' => $language->get('user', 'user_cp') - ] - ] + 'title' => $language->get('user', 'user_cp'), + ], + ], ]; if ($user->canViewStaffCP()) { $user_area_left['account']['items']['panel'] = [ 'link' => URL::build('/panel'), 'target' => '', - 'title' => $language->get('moderator', 'staff_cp') + 'title' => $language->get('moderator', 'staff_cp'), ]; } $user_area_left['account']['items']['separator2'] = [ - 'separator' => true + 'separator' => true, ]; $user_area_left['account']['items']['logout'] = [ 'link' => URL::build('/logout'), 'target' => '', - 'title' => $language->get('general', 'log_out') + 'title' => $language->get('general', 'log_out'), ]; /* @@ -128,7 +128,7 @@ 'target' => '', ], 'separator_1' => [ - 'separator' => true + 'separator' => true, ], 'logout' => [ 'title' => $language->get('general', 'log_out'), @@ -147,14 +147,14 @@ 'login' => [ 'link' => URL::build('/login'), 'target' => '', - 'title' => $language->get('general', 'sign_in') + 'title' => $language->get('general', 'sign_in'), ], 'register' => [ 'link' => URL::build('/register'), 'target' => '', - 'title' => $language->get('general', 'register') - ] - ] + 'title' => $language->get('general', 'register'), + ], + ], ]; $user_section = [ @@ -171,7 +171,7 @@ 'link' => URL::build('/register'), 'meta' => '', 'target' => '', - ] + ], ]; } @@ -189,7 +189,7 @@ !$user->isLoggedIn() ? [0] : $user->getAllGroupIds() ), 'INTERNET_EXPLORER_HEADER' => $language->get('general', 'internet_explorer_header'), - 'INTERNET_EXPLORER_INFO' => $language->get('general', 'internet_explorer_info') + 'INTERNET_EXPLORER_INFO' => $language->get('general', 'internet_explorer_info'), ]); if ($user->isLoggedIn()) { diff --git a/core/templates/panel_navbar.php b/core/templates/panel_navbar.php index 35cd43a792..960eaac869 100644 --- a/core/templates/panel_navbar.php +++ b/core/templates/panel_navbar.php @@ -20,5 +20,5 @@ 'SOURCE' => $language->get('admin', 'source'), 'NOTICES' => Core_Module::getNotices(), 'NO_NOTICES' => $language->get('admin', 'no_notices'), - 'MODE_TOGGLE' => $language->get('admin', 'mode_toggle') + 'MODE_TOGGLE' => $language->get('admin', 'mode_toggle'), ]); diff --git a/custom/panel_templates/Default/template.php b/custom/panel_templates/Default/template.php index c558b3c9da..aef8e86c10 100644 --- a/custom/panel_templates/Default/template.php +++ b/custom/panel_templates/Default/template.php @@ -14,12 +14,13 @@ // Always have the following if statement around your class if (!class_exists('Default_Panel_Template')) { - class Default_Panel_Template extends TemplateBase { - + class Default_Panel_Template extends TemplateBase + { private Language $_language; // Constructor - set template name, version, Nameless version and author here - public function __construct(Smarty $smarty, Language $language) { + public function __construct(Smarty $smarty, Language $language) + { $this->_language = $language; parent::__construct( @@ -136,7 +137,8 @@ public function __construct(Smarty $smarty, Language $language) { $smarty->assign('NAMELESS_LOGO', (defined('CONFIG_PATH') ? CONFIG_PATH : '') . '/core/assets/img/namelessmc_logo.png'); } - public function onPageLoad() { + public function onPageLoad() + { $page_load = microtime(true) - PAGE_START_TIME; define('PAGE_LOAD_TIME', $this->_language->get('general', 'page_loaded_in', ['time' => round($page_load, 3)])); @@ -152,7 +154,7 @@ public function onPageLoad() { case 'api': $this->assets()->include([ - AssetTree::DATATABLES + AssetTree::DATATABLES, ]); $this->addJSScript(' @@ -342,14 +344,12 @@ public function onPageLoad() { }); }); '); - } break; case 'minecraft': if (!defined('MINECRAFT_PAGE')) { - $this->addJSScript(' if ($(\'.js-check-change\').length) { var changeCheckbox = document.querySelector(\'.js-check-change\'); @@ -369,9 +369,7 @@ public function onPageLoad() { }; } '); - - } else if (MINECRAFT_PAGE == 'authme') { - + } elseif (MINECRAFT_PAGE == 'authme') { $this->addJSScript(' if ($(\'.js-check-change\').length) { var changeCheckbox = document.querySelector(\'.js-check-change\'); @@ -381,12 +379,11 @@ public function onPageLoad() { }; } '); - - } else if (MINECRAFT_PAGE == 'servers') { + } elseif (MINECRAFT_PAGE == 'servers') { $this->assets()->include([ AssetTree::JQUERY_UI, ]); - } else if (MINECRAFT_PAGE == 'query_errors') { + } elseif (MINECRAFT_PAGE == 'query_errors') { $this->addCSSStyle(' .error_log { width: 100%; @@ -401,8 +398,7 @@ public function onPageLoad() { background-color: #eceeef; } '); - - } else if (MINECRAFT_PAGE == 'server_banners') { + } elseif (MINECRAFT_PAGE == 'server_banners') { if (isset($_GET['edit'])) { $this->assets()->include([ AssetTree::IMAGE_PICKER, @@ -498,7 +494,7 @@ public function onPageLoad() { case 'forums': $this->assets()->include([ AssetTree::TINYMCE, - AssetTree::JQUERY_UI + AssetTree::JQUERY_UI, ]); if (isset($_GET['forum'])) { diff --git a/custom/templates/DefaultRevamp/template.php b/custom/templates/DefaultRevamp/template.php index 3a1b0fb768..9f4f6f1e66 100755 --- a/custom/templates/DefaultRevamp/template.php +++ b/custom/templates/DefaultRevamp/template.php @@ -9,8 +9,8 @@ * DefaultRevamp Template */ -class DefaultRevamp_Template extends TemplateBase { - +class DefaultRevamp_Template extends TemplateBase +{ private array $_template; /** @var Language */ @@ -22,7 +22,8 @@ class DefaultRevamp_Template extends TemplateBase { /** @var Pages */ private Pages $_pages; - public function __construct($cache, $smarty, $language, $user, $pages) { + public function __construct($cache, $smarty, $language, $user, $pages) + { $template = [ 'name' => 'DefaultRevamp', 'version' => '2.1.2', @@ -66,7 +67,7 @@ public function __construct($cache, $smarty, $language, $user, $pages) { $smarty->assign([ 'DEFAULT_REVAMP_DARK_MODE' => $smartyDarkMode, - 'DEFAULT_REVAMP_NAVBAR_EXTRA_CLASSES' => $smartyNavbarColour + 'DEFAULT_REVAMP_NAVBAR_EXTRA_CLASSES' => $smartyNavbarColour, ]); $this->_template = $template; @@ -75,12 +76,13 @@ public function __construct($cache, $smarty, $language, $user, $pages) { $this->_pages = $pages; } - public function onPageLoad() { + public function onPageLoad() + { $page_load = microtime(true) - PAGE_START_TIME; define('PAGE_LOAD_TIME', $this->_language->get('general', 'page_loaded_in', ['time' => round($page_load, 3)])); $this->addCSSFiles([ - $this->_template['path'] . 'css/custom.css?v=211' => [] + $this->_template['path'] . 'css/custom.css?v=211' => [], ]); $route = (isset($_GET['route']) ? rtrim($_GET['route'], '/') : '/'); diff --git a/custom/templates/DefaultRevamp/template_settings/settings.php b/custom/templates/DefaultRevamp/template_settings/settings.php index 10a3d4d639..3a72f7b234 100644 --- a/custom/templates/DefaultRevamp/template_settings/settings.php +++ b/custom/templates/DefaultRevamp/template_settings/settings.php @@ -49,67 +49,67 @@ [ 'value' => 'white', 'name' => $language->get('general', 'default'), - 'selected' => ($navbarColour == 'white') + 'selected' => ($navbarColour == 'white'), ], [ 'value' => 'red', 'name' => $language->get('general', 'red'), - 'selected' => ($navbarColour == 'red') + 'selected' => ($navbarColour == 'red'), ], [ 'value' => 'orange', 'name' => $language->get('general', 'orange'), - 'selected' => ($navbarColour == 'orange') + 'selected' => ($navbarColour == 'orange'), ], [ 'value' => 'yellow', 'name' => $language->get('general', 'yellow'), - 'selected' => ($navbarColour == 'yellow') + 'selected' => ($navbarColour == 'yellow'), ], [ 'value' => 'olive', 'name' => $language->get('general', 'olive'), - 'selected' => ($navbarColour == 'olive') + 'selected' => ($navbarColour == 'olive'), ], [ 'value' => 'green', 'name' => $language->get('general', 'green'), - 'selected' => ($navbarColour == 'green') + 'selected' => ($navbarColour == 'green'), ], [ 'value' => 'teal', 'name' => $language->get('general', 'teal'), - 'selected' => ($navbarColour == 'teal') + 'selected' => ($navbarColour == 'teal'), ], [ 'value' => 'blue', 'name' => $language->get('general', 'blue'), - 'selected' => ($navbarColour == 'blue') + 'selected' => ($navbarColour == 'blue'), ], [ 'value' => 'violet', 'name' => $language->get('general', 'violet'), - 'selected' => ($navbarColour == 'violet') + 'selected' => ($navbarColour == 'violet'), ], [ 'value' => 'purple', 'name' => $language->get('general', 'purple'), - 'selected' => ($navbarColour == 'purple') + 'selected' => ($navbarColour == 'purple'), ], [ 'value' => 'pink', 'name' => $language->get('general', 'pink'), - 'selected' => ($navbarColour == 'pink') + 'selected' => ($navbarColour == 'pink'), ], [ 'value' => 'brown', 'name' => $language->get('general', 'brown'), - 'selected' => ($navbarColour == 'brown') + 'selected' => ($navbarColour == 'brown'), ], [ 'value' => 'grey', 'name' => $language->get('general', 'grey'), - 'selected' => ($navbarColour == 'grey') + 'selected' => ($navbarColour == 'grey'), ], ]; @@ -128,5 +128,5 @@ 'NAVBAR_COLOUR' => $language->get('admin', 'navbar_colour'), 'NAVBAR_COLOURS' => $nav_colours, 'HOME_CUSTOM_CONTENT' => $language->get('admin', 'home_custom_content'), - 'SETTINGS_TEMPLATE' => ROOT_PATH . '/custom/templates/DefaultRevamp/template_settings/settings.tpl' + 'SETTINGS_TEMPLATE' => ROOT_PATH . '/custom/templates/DefaultRevamp/template_settings/settings.tpl', ]); diff --git a/dev/phpcs.xml b/dev/phpcs.xml deleted file mode 100644 index 1b8d367cef..0000000000 --- a/dev/phpcs.xml +++ /dev/null @@ -1,76 +0,0 @@ - - - A custom ruleset for the Kirki project based on the WordPress Coding Standards and PHPCompatibility. - - - - - - - - - - - ../ - - vendor/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/scripts/cli_install.php b/dev/scripts/cli_install.php index c3eed231bd..8bc5654422 100644 --- a/dev/scripts/cli_install.php +++ b/dev/scripts/cli_install.php @@ -5,22 +5,23 @@ * this script was made with the primary goal of making the install process automatic for hosting providers + our API test suite. */ -function getEnvVar(string $name, string $fallback = null, array $valid_values = null) { +function getEnvVar(string $name, string $fallback = null, array $valid_values = null) +{ $value = getenv($name); $required = $fallback === null; if ($value === false && $required) { - print("⚠️ Required environment variable '$name' is not set!" . PHP_EOL); + echo "⚠️ Required environment variable '$name' is not set!" . PHP_EOL; exit(1); } if (!$value && $fallback !== null) { $value = $fallback; - print("ℹ️ Environment variable '$name' is not set, using fallback '$fallback'" . PHP_EOL); + echo "ℹ️ Environment variable '$name' is not set, using fallback '$fallback'" . PHP_EOL; } if ($valid_values != null && !in_array($value, $valid_values)) { - print("⚠️ Environment variable '$name' has invalid value"); + echo "⚠️ Environment variable '$name' has invalid value"; exit(1); } @@ -32,26 +33,26 @@ function getEnvVar(string $name, string $fallback = null, array $valid_values = } if (!isset($argv[1]) || $argv[1] !== '--iSwearIKnowWhatImDoing') { - print("🚫 You don't know what you're doing." . PHP_EOL); + echo "🚫 You don't know what you're doing." . PHP_EOL; exit(1); } -print(PHP_EOL); +echo PHP_EOL; $reinstall = false; if (isset($argv[2]) && $argv[2] == '--reinstall') { $reinstall = true; - print('🧨 Reinstall mode enabled! ' . PHP_EOL . PHP_EOL); + echo '🧨 Reinstall mode enabled! ' . PHP_EOL . PHP_EOL; } if (!file_exists('./vendor/autoload.php')) { - print('⚠️ You need to run "composer install" first!' . PHP_EOL); + echo '⚠️ You need to run "composer install" first!' . PHP_EOL; exit(1); } if (!$reinstall && file_exists('./core/config.php')) { - print('⚠️ NamelessMC is already installed! ' . PHP_EOL); - print("🧨 If you want to reinstall, run this script with the '--reinstall' flag." . PHP_EOL); + echo '⚠️ NamelessMC is already installed! ' . PHP_EOL; + echo "🧨 If you want to reinstall, run this script with the '--reinstall' flag." . PHP_EOL; exit(1); } @@ -62,11 +63,11 @@ function getEnvVar(string $name, string $fallback = null, array $valid_values = $start = microtime(true); -print('🗑 Deleting cache directories...' . PHP_EOL); +echo '🗑 Deleting cache directories...' . PHP_EOL; // clear the cache directories $folders = [ './cache', - './cache/templates_c' + './cache/templates_c', ]; $whitelist = [ '0_DO_NOT_DELETE.txt', @@ -79,7 +80,7 @@ function getEnvVar(string $name, string $fallback = null, array $valid_values = if (!in_array(basename($file), $whitelist)) { if (is_file($file)) { unlink($file); - } else if (is_dir($file)) { + } elseif (is_dir($file)) { rmdir($file); } } @@ -88,7 +89,7 @@ function getEnvVar(string $name, string $fallback = null, array $valid_values = } if ($reinstall) { - print('🗑 Deleting old config.php file...' . PHP_EOL); + echo '🗑 Deleting old config.php file...' . PHP_EOL; // delete the core/config.php file if (is_file('./core/config.php')) { unlink('./core/config.php'); @@ -97,10 +98,10 @@ function getEnvVar(string $name, string $fallback = null, array $valid_values = const ROOT_PATH = __DIR__ . '/../..'; -print('♻️ Registering autoloader...' . PHP_EOL); +echo '♻️ Registering autoloader...' . PHP_EOL; require './vendor/autoload.php'; -print('✍️ Creating new config.php file...' . PHP_EOL); +echo '✍️ Creating new config.php file...' . PHP_EOL; $conf = [ 'mysql' => [ 'host' => getEnvVar('NAMELESS_DATABASE_ADDRESS', '127.0.0.1'), @@ -137,7 +138,7 @@ function getEnvVar(string $name, string $fallback = null, array $valid_values = Config::write($conf); if ($reinstall) { - print('🗑️ Deleting old database...' . PHP_EOL); + echo '🗑️ Deleting old database...' . PHP_EOL; $instance = DB::getCustomInstance( $conf['mysql']['host'], $conf['mysql']['db'], @@ -146,22 +147,22 @@ function getEnvVar(string $name, string $fallback = null, array $valid_values = $conf['mysql']['port'] ); $instance->query('DROP DATABASE IF EXISTS `' . $conf['mysql']['db'] . '`'); - print('✍️ Creating new database...' . PHP_EOL); + echo '✍️ Creating new database...' . PHP_EOL; $instance->query('CREATE DATABASE `' . $conf['mysql']['db'] . '`'); } -print('✍️ Creating tables...' . PHP_EOL); +echo '✍️ Creating tables...' . PHP_EOL; $message = PhinxAdapter::migrate('Core'); if (!str_contains($message, 'All Done')) { - print($message); + echo $message; exit(1); } Session::put('default_language', getEnvVar('NAMELESS_DEFAULT_LANGUAGE', 'en_UK')); -print('✍️ Inserting default data to database...' . PHP_EOL); +echo '✍️ Inserting default data to database...' . PHP_EOL; $_SESSION['install_timezone'] = in_array($timezone = getEnvVar('NAMELESS_TIMEZONE', 'Europe/London'), DateTimeZone::listIdentifiers()) ? $timezone @@ -174,7 +175,7 @@ function getEnvVar(string $name, string $fallback = null, array $valid_values = Settings::set('outgoing_email', getEnvVar('NAMELESS_SITE_OUTGOING_EMAIL')); Settings::set('email_verification', getEnvVar('NAMELESS_EMAIL_VERIFICATION', '1', ['0', '1'])); -print('👮 Creating admin account...' . PHP_EOL); +echo '👮 Creating admin account...' . PHP_EOL; $username = getEnvVar('NAMELESS_ADMIN_USERNAME', 'admin'); $password = getEnvVar('NAMELESS_ADMIN_PASSWORD', 'password'); @@ -223,10 +224,10 @@ function getEnvVar(string $name, string $fallback = null, array $valid_values = Config::set('core.installed', true); -print(PHP_EOL . '✅ Installation complete! (Took ' . round(microtime(true) - $start, 2) . ' seconds)' . PHP_EOL); -print(PHP_EOL . '🖥 URL: http://' . $conf['core']['hostname'] . $conf['core']['path']); -print(PHP_EOL . '🔑 Admin username: ' . $username); -print(PHP_EOL . '🔑 Admin email: ' . $email); -print(PHP_EOL . '🔑 Admin password: ' . $password); -print(PHP_EOL); +echo PHP_EOL . '✅ Installation complete! (Took ' . round(microtime(true) - $start, 2) . ' seconds)' . PHP_EOL; +echo PHP_EOL . '🖥 URL: http://' . $conf['core']['hostname'] . $conf['core']['path']; +echo PHP_EOL . '🔑 Admin username: ' . $username; +echo PHP_EOL . '🔑 Admin email: ' . $email; +echo PHP_EOL . '🔑 Admin password: ' . $password; +echo PHP_EOL; exit(0); diff --git a/dev/scripts/language_convert.php b/dev/scripts/language_convert.php index e39ac47d29..e0e608b55f 100644 --- a/dev/scripts/language_convert.php +++ b/dev/scripts/language_convert.php @@ -1,10 +1,11 @@ --out ' . PHP_EOL); + echo 'Usage: php language_convert.php --in --out ' . PHP_EOL; exit(1); } @@ -13,13 +14,13 @@ $in = $argv[2]; if (!is_dir($in)) { - print('⚠️ Input directory does not exist: ' . $in . PHP_EOL); + echo '⚠️ Input directory does not exist: ' . $in . PHP_EOL; exit(1); } - print('📂 Input folder set to: ' . $in . PHP_EOL); + echo '📂 Input folder set to: ' . $in . PHP_EOL; } else { - print('🚫 Please specify an input folder with --in ' . PHP_EOL); + echo '🚫 Please specify an input folder with --in ' . PHP_EOL; exit(1); } @@ -28,17 +29,17 @@ $out = $argv[4]; if (!is_dir($out)) { - print('⚠️ Output directory does not exist: ' . $out . PHP_EOL); + echo '⚠️ Output directory does not exist: ' . $out . PHP_EOL; exit(1); } - print('📂 Output folder set to: ' . $out . PHP_EOL); + echo '📂 Output folder set to: ' . $out . PHP_EOL; } else { - print('🚫 Please specify an output folder with --out ' . PHP_EOL); + echo '🚫 Please specify an output folder with --out ' . PHP_EOL; exit(1); } -print PHP_EOL; +echo PHP_EOL; $files = scandir($in); $parts = explode('/', $in); @@ -66,8 +67,8 @@ $json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); file_put_contents($out . '/' . $output_file_name . '.json', $json); -print '☑️ Converted files in: ' . $in . ' to ' . $out . '/' . $output_file_name . '.json' . PHP_EOL; +echo '☑️ Converted files in: ' . $in . ' to ' . $out . '/' . $output_file_name . '.json' . PHP_EOL; -print PHP_EOL; +echo PHP_EOL; -print '🎉 Done!' . PHP_EOL; +echo '🎉 Done!' . PHP_EOL; diff --git a/dev/scripts/seeder/ForumCategorySeeder.php b/dev/scripts/seeder/ForumCategorySeeder.php index cc4209a9db..6c9e6db915 100644 --- a/dev/scripts/seeder/ForumCategorySeeder.php +++ b/dev/scripts/seeder/ForumCategorySeeder.php @@ -1,12 +1,13 @@ times(FORUM_CATEGORY_COUNT, static function () use ($db, $faker, &$order) { $db->insert('forums', [ diff --git a/dev/scripts/seeder/ForumPostSeeder.php b/dev/scripts/seeder/ForumPostSeeder.php index 57c6dbdfb7..78f2acc5b9 100644 --- a/dev/scripts/seeder/ForumPostSeeder.php +++ b/dev/scripts/seeder/ForumPostSeeder.php @@ -1,13 +1,14 @@ get('topics', ['id', '<>', '0'])->results(); $users = $db->get('users', ['id', '<>', '0'])->results(); diff --git a/dev/scripts/seeder/ForumSubforumSeeder.php b/dev/scripts/seeder/ForumSubforumSeeder.php index 3a0b85ca9d..cc63e1aa0d 100644 --- a/dev/scripts/seeder/ForumSubforumSeeder.php +++ b/dev/scripts/seeder/ForumSubforumSeeder.php @@ -1,7 +1,7 @@ get('forums', ['forum_type', 'category'])->results(); foreach ($categories as $category) { diff --git a/dev/scripts/seeder/ForumTopicSeeder.php b/dev/scripts/seeder/ForumTopicSeeder.php index 0a813749fc..e295ec89aa 100644 --- a/dev/scripts/seeder/ForumTopicSeeder.php +++ b/dev/scripts/seeder/ForumTopicSeeder.php @@ -1,12 +1,13 @@ get('forums', ['id', '<>', 0])->results(); $users = $db->get('users', ['id', '<>', 0])->results(); diff --git a/dev/scripts/seeder/MinecraftPlaceholderDataSeeder.php b/dev/scripts/seeder/MinecraftPlaceholderDataSeeder.php index 780e3ae131..ab8b433300 100644 --- a/dev/scripts/seeder/MinecraftPlaceholderDataSeeder.php +++ b/dev/scripts/seeder/MinecraftPlaceholderDataSeeder.php @@ -1,18 +1,19 @@ get('placeholders_settings', ['server_id', '<>', 0])->results(); $users = $db->get('users', ['id', '<>', 0])->results(); $saved = []; $user_uuids = []; - $this->times(1000, function() use ($db, $faker, $placeholders, $users, &$saved, &$user_uuids) { + $this->times(1000, function () use ($db, $faker, $placeholders, $users, &$saved, &$user_uuids) { $placeholder = $faker->randomElement($placeholders); $user = $faker->randomElement($users); diff --git a/dev/scripts/seeder/MinecraftPlaceholderSeeder.php b/dev/scripts/seeder/MinecraftPlaceholderSeeder.php index 49f26bbc4f..db8eaa8701 100644 --- a/dev/scripts/seeder/MinecraftPlaceholderSeeder.php +++ b/dev/scripts/seeder/MinecraftPlaceholderSeeder.php @@ -1,25 +1,26 @@ query('UPDATE nl2_settings SET value = ? WHERE name = ?', [ 1, 'placeholders', ]); $servers = $db->get('mc_servers', ['id', '<>', 0])->results(); - $this->times(5, function() use ($db, $faker, $servers) { + $this->times(5, function () use ($db, $faker, $servers) { $name = str_replace(' ', '_', $faker->words(2, true)); if ($faker->boolean) { $friendly_name = $name; /** @phpstan-ignore-next-line Bad */ - } else if ($faker->boolean) { + } elseif ($faker->boolean) { $friendly_name = str_replace('_', ' ', $name); } else { $friendly_name = $faker->words(2, true); diff --git a/dev/scripts/seeder/MinecraftServerSeeder.php b/dev/scripts/seeder/MinecraftServerSeeder.php index 2efa207198..7db1664729 100644 --- a/dev/scripts/seeder/MinecraftServerSeeder.php +++ b/dev/scripts/seeder/MinecraftServerSeeder.php @@ -1,7 +1,7 @@ randomElement([1, 2, 3, 4, 5]); $id = 1; diff --git a/dev/scripts/seeder/ProfileFieldsDataSeeder.php b/dev/scripts/seeder/ProfileFieldsDataSeeder.php index fdc8da8951..7009c1752b 100644 --- a/dev/scripts/seeder/ProfileFieldsDataSeeder.php +++ b/dev/scripts/seeder/ProfileFieldsDataSeeder.php @@ -1,12 +1,13 @@ get('profile_fields', ['id', '<>', 0])->results(); foreach ($db->get('users', ['id', '<>', '0'])->results() as $user) { diff --git a/dev/scripts/seeder/ProfileFieldsSeeder.php b/dev/scripts/seeder/ProfileFieldsSeeder.php index 60d47e402d..2528f6f203 100644 --- a/dev/scripts/seeder/ProfileFieldsSeeder.php +++ b/dev/scripts/seeder/ProfileFieldsSeeder.php @@ -1,12 +1,13 @@ times(PROFILE_FIELDS_COUNT, function () use ($db, $faker) { $db->insert('profile_fields', [ 'name' => $faker->unique()->word, diff --git a/dev/scripts/seeder/Seeder.php b/dev/scripts/seeder/Seeder.php index 44c9c22c3c..6fa4ac2685 100644 --- a/dev/scripts/seeder/Seeder.php +++ b/dev/scripts/seeder/Seeder.php @@ -1,36 +1,42 @@ run($db, $faker); - print '🌲 ' . get_class($this) . ' complete! (' . round((microtime(true) - $start), 2) . 's)' . PHP_EOL; + echo '🌲 ' . get_class($this) . ' complete! (' . round(microtime(true) - $start, 2) . 's)' . PHP_EOL; } abstract protected function run(DB $db, \Faker\Generator $faker): void; - protected function times(int $count, Closure $factory): void { + protected function times(int $count, Closure $factory): void + { for ($i = 0; $i < $count; $i++) { $factory(); } } - protected function since(int $past, \Faker\Generator $faker): DateTime { + protected function since(int $past, \Faker\Generator $faker): DateTime + { // convert the epoch time to a DateTime object $date = new DateTime(); $date->setTimestamp($past); - return $date->modify('+' . + return $date->modify( + '+' . $faker->numberBetween(1, 10) . ' ' . $faker->randomElement(['days', 'months']) - )->modify('+' . + )->modify( + '+' . $faker->numberBetween(1, 24) . ' ' . $faker->randomElement(['hours', 'minutes']) - )->modify('+' . + )->modify( + '+' . $faker->numberBetween(1, 60) . ' ' . $faker->randomElement(['seconds']) ); } diff --git a/dev/scripts/seeder/UserProfilePostSeeder.php b/dev/scripts/seeder/UserProfilePostSeeder.php index f776f787ae..77b6c49f03 100644 --- a/dev/scripts/seeder/UserProfilePostSeeder.php +++ b/dev/scripts/seeder/UserProfilePostSeeder.php @@ -1,14 +1,15 @@ get('users', ['id', '<>', 0])->results(); $this->times(PROFILE_POST_COUNT, function () use ($db, $faker, $users) { diff --git a/dev/scripts/seeder/UserSeeder.php b/dev/scripts/seeder/UserSeeder.php index 701a245cfa..b508450910 100644 --- a/dev/scripts/seeder/UserSeeder.php +++ b/dev/scripts/seeder/UserSeeder.php @@ -1,14 +1,15 @@ 13]); $db->insert('users', [ @@ -32,14 +33,15 @@ public function run(DB $db, \Faker\Generator $faker): void { 0, ]); $db->query( - 'INSERT INTO nl2_users_integrations (user_id, integration_id, identifier, username, verified, date, code) VALUES (?, ?, ?, ?, ?, ?, ?)', [ + 'INSERT INTO nl2_users_integrations (user_id, integration_id, identifier, username, verified, date, code) VALUES (?, ?, ?, ?, ?, ?, ?)', + [ $user_id, 1, str_replace('-', '', $faker->unique()->uuid), 'admin', 1, date('U'), - null + null, ] ); @@ -98,14 +100,15 @@ public function run(DB $db, \Faker\Generator $faker): void { } $db->query( - 'INSERT INTO nl2_users_integrations (user_id, integration_id, identifier, username, verified, date, code) VALUES (?, ?, ?, ?, ?, ?, ?)', [ + 'INSERT INTO nl2_users_integrations (user_id, integration_id, identifier, username, verified, date, code) VALUES (?, ?, ?, ?, ?, ?, ?)', + [ $user_id, 1, str_replace('-', '', $faker->unique()->uuid), $username, 1, date('U'), - null + null, ] ); }); diff --git a/dev/scripts/seeder/db_seeder.php b/dev/scripts/seeder/db_seeder.php index 37b7af264c..d10d868b33 100644 --- a/dev/scripts/seeder/db_seeder.php +++ b/dev/scripts/seeder/db_seeder.php @@ -1,4 +1,5 @@ get('users', ['id', '>', 0])->count() > 0) { - print '🛑 Database is not empty and wipe mode is not enabled!' . PHP_EOL; + echo '🛑 Database is not empty and wipe mode is not enabled!' . PHP_EOL; exit(1); } @@ -63,16 +65,16 @@ $db->query("TRUNCATE {$table}"); } } - print '🧨 Deleted existing data!' . PHP_EOL; + echo '🧨 Deleted existing data!' . PHP_EOL; } -print PHP_EOL; +echo PHP_EOL; $start = microtime(true); foreach ($seeders as $seeder) { $seeder->seed($db, $faker); } -print PHP_EOL; +echo PHP_EOL; -print '🪄 Seeding complete! (' . round((microtime(true) - $start), 2) . 's)' . PHP_EOL; +echo '🪄 Seeding complete! (' . round(microtime(true) - $start, 2) . 's)' . PHP_EOL; diff --git a/dev/scripts/verify_checksums.php b/dev/scripts/verify_checksums.php index 066a629f0f..6af15e8d61 100644 --- a/dev/scripts/verify_checksums.php +++ b/dev/scripts/verify_checksums.php @@ -11,6 +11,7 @@ if (count($errors) === 0) { echo "No errors found!\n"; + return; } diff --git a/index.php b/index.php index 06d7af5f23..f3dbbea1db 100644 --- a/index.php +++ b/index.php @@ -49,7 +49,7 @@ if (isset($_GET['route']) && $_GET['route'] == '/rewrite_test') { require_once('rewrite_test.php'); - die(); + die; } if (!Config::exists() || Config::get('core.installed') !== true) { @@ -85,14 +85,14 @@ // Get page to load from URL if (!isset($_GET['route']) || $_GET['route'] == '/') { - if (((!isset($_GET['route']) || ($_GET['route'] != '/')) && count($directories) > 1)) { + if ((!isset($_GET['route']) || ($_GET['route'] != '/')) && count($directories) > 1) { require(ROOT_PATH . '/404.php'); } else { // Homepage $pages->setActivePage($pages->getPageByURL('/')); require(ROOT_PATH . '/modules/Core/pages/index.php'); } - die(); + die; } $route = rtrim(strtok($_GET['route'], '?'), '/'); @@ -103,21 +103,20 @@ $pages->setActivePage($all_pages[$route]); if (isset($all_pages[$route]['custom'])) { require(implode(DIRECTORY_SEPARATOR, [ROOT_PATH, 'modules', 'Core', 'pages', 'custom.php'])); - die(); + die; } $path = implode(DIRECTORY_SEPARATOR, [ROOT_PATH, 'modules', $all_pages[$route]['module'], $all_pages[$route]['file']]); if (file_exists($path)) { require($path); - die(); + die; } } else { // Use recursion to check - might have URL parameters in path $path_array = explode('/', $route); for ($i = count($path_array) - 2; $i > 0; $i--) { - $new_path = '/'; for ($n = 1; $n <= $i; $n++) { $new_path .= $path_array[$n] . '/'; @@ -131,7 +130,7 @@ if (file_exists($path)) { $pages->setActivePage($all_pages[$new_path]); require($path); - die(); + die; } } } diff --git a/install.php b/install.php index 70ac94b748..6c0b133172 100644 --- a/install.php +++ b/install.php @@ -52,6 +52,7 @@ if (Config::exists() && Config::get('core.installed') === true) { require(ROOT_PATH . '/core/installation/already_installed.php'); + return; }