diff --git a/src/private/php/AdminStatus.php b/src/private/php/AdminStatus.php index 92d6ee0..5580e9f 100644 --- a/src/private/php/AdminStatus.php +++ b/src/private/php/AdminStatus.php @@ -15,16 +15,16 @@ class AdminStatus { private $cache; - const STATUS_STYLE_GROUPED = 1; - const STATUS_STYLE_GROUPED_HIDE_EMPTY_GROUPS = 2; - const STATUS_STYLE_LIST = 3; - const STATUS_STYLE_LIST_ONLINE_FIRST = 4; + public const STATUS_STYLE_GROUPED = 1; + public const STATUS_STYLE_GROUPED_HIDE_EMPTY_GROUPS = 2; + public const STATUS_STYLE_LIST = 3; + public const STATUS_STYLE_LIST_ONLINE_FIRST = 4; public function __construct() { $this->cache = new PhpFileCache(__CACHE_DIR, "adminstatus"); } - public function getCachedAdminClients(array $adminGroups) { + public function getCachedAdminClients(array $adminGroups): ?array { return $this->cache->refreshIfExpired("adminstatus", function () use ($adminGroups) { if(TeamSpeakUtils::i()->checkTSConnection()) { try { @@ -44,7 +44,7 @@ class AdminStatus { }, Config::get("cache_adminstatus")); } - public function getStatus(array $adminGroups, $format, $hideOffline = false, array $ignoredUsersDbids = []) { + public function getStatus(array $adminGroups, $format, bool $hideOffline = false, array $ignoredUsersDbids = []) { if ($format !== self::STATUS_STYLE_GROUPED && $format !== self::STATUS_STYLE_GROUPED_HIDE_EMPTY_GROUPS && $format !== self::STATUS_STYLE_LIST diff --git a/src/private/php/Assigner.php b/src/private/php/Assigner.php index 85236fc..6d28ee6 100644 --- a/src/private/php/Assigner.php +++ b/src/private/php/Assigner.php @@ -6,11 +6,11 @@ use Wruczek\TSWebsite\Utils\TeamSpeakUtils; class Assigner { - public static function getAssignerConfig() { + public static function getAssignerConfig(): array { return Config::get("assignerconfig"); } - public static function getAssignerArray() { + public static function getAssignerArray(): array { $assignerConfig = self::getAssignerConfig(); if (empty($assignerConfig)) { @@ -46,7 +46,7 @@ class Assigner { return $assignerConfig; } - public static function isAssignable($sgid) { + public static function isAssignable(int $sgid): bool { foreach (self::getAssignerConfig() as $category) { if (in_array($sgid, $category["groups"], true)) { return true; @@ -69,7 +69,7 @@ class Assigner { * @throws UserNotAuthenticatedException * @throws \TeamSpeak3_Exception */ - public static function changeGroups($newGroups) { + public static function changeGroups(array $newGroups): int { $assignerConfig = self::getAssignerConfig(); if (empty($assignerConfig)) { @@ -85,9 +85,9 @@ class Assigner { foreach ($config["groups"] as $group) { // true if the $group is currently assigned to the user - $isAssigned = in_array($group, $userGroups); + $isAssigned = in_array($group, $userGroups, true); // true if the user wants to be added to $group - $wantToAssign = in_array($group, $newGroups); + $wantToAssign = in_array($group, $newGroups, true); // if the group is already assigned, or is to be assigned, // check for the max group limit in this category: @@ -133,11 +133,11 @@ class Assigner { return 0; } - public static function getRequiredSgids() { + public static function getRequiredSgids(): array { return Config::get("assigner_required_sgids"); } - public static function canUseAssigner() { + public static function canUseAssigner(): bool { // if there are no required sgids, the user can use assigner and // we can skip the other, more expensive checks that will require // fetching user groups from TS3 @@ -149,7 +149,7 @@ class Assigner { return self::canUseAssignerSgArray($userGroups); } - public static function canUseAssignerSgArray(array $serverGroups) { + public static function canUseAssignerSgArray(array $serverGroups): bool { // user needs to be in at least one of those groups to be able // to use group assigner $requiredSgid = self::getRequiredSgids(); diff --git a/src/private/php/Auth.php b/src/private/php/Auth.php index 8df7f9e..20eb898 100644 --- a/src/private/php/Auth.php +++ b/src/private/php/Auth.php @@ -10,26 +10,26 @@ use Wruczek\TSWebsite\Utils\Utils; class Auth { public static function isLoggedIn() { - return !empty(self::getCldbid()) && !empty(self::getUid()); + return self::getCldbid() !== null && self::getUid() !== null; } - public static function getUid() { + public static function getUid(): ?string { return @$_SESSION["tsuser"]["uid"]; } - public static function getCldbid() { + public static function getCldbid(): ?int { return @$_SESSION["tsuser"]["cldbid"]; } - public static function getNickname() { + public static function getNickname(): ?string { return @$_SESSION["tsuser"]["nickname"]; } - public static function logout() { + public static function logout(): void { unset($_SESSION["tsuser"]); } - public static function getTsUsersByIp($ip = null) { + public static function getTsUsersByIp(string $ip = null): ?array { if ($ip === null) { $ip = Utils::getClientIp(); } @@ -62,7 +62,7 @@ class Auth { * @param $ip string optional, defaults to Utils::getClientIp * @return bool true if the cldbid have the same IP address as $ip */ - public static function checkClientIp($cldbid, $ip = null) { + public static function checkClientIp(int $cldbid, string $ip = null): bool { if ($ip === null) { $ip = Utils::getClientIp(); } @@ -84,7 +84,7 @@ class Auth { * client cannot be found and false when other error occurs. * @throws \TeamSpeak3_Adapter_ServerQuery_Exception */ - public static function generateConfirmationCode($cldbid, $poke = null) { + public static function generateConfirmationCode(int $cldbid, ?bool $poke = null) { if ($poke === null) { $poke = (bool) Config::get("loginpokeclient"); } @@ -123,7 +123,7 @@ class Auth { * @param $cldbid int * @return string|null Confirmation code, null if not found */ - public static function getConfirmationCode($cldbid) { + public static function getConfirmationCode(int $cldbid): ?string { return (new PhpFileCache(__CACHE_DIR, "confirmationcodes"))->retrieve("c_$cldbid"); } @@ -132,7 +132,7 @@ class Auth { * @param $cldbid int * @param $code string */ - public static function saveConfirmationCode($cldbid, $code) { + public static function saveConfirmationCode(int $cldbid, string $code): void { (new PhpFileCache(__CACHE_DIR, "confirmationcodes"))->store("c_$cldbid", $code, (int) Config::get("cache_logincode")); } @@ -140,7 +140,7 @@ class Auth { * Deletes confirmation code for the user * @param $cldbid int */ - public static function deleteConfirmationCode($cldbid) { + public static function deleteConfirmationCode(int $cldbid): void { (new PhpFileCache(__CACHE_DIR, "confirmationcodes"))->eraseKey("c_$cldbid"); } @@ -150,7 +150,7 @@ class Auth { * @param $userCode * @return bool true if authentication was successful */ - public static function checkCodeAndLogin($cldbid, $userCode) { + public static function checkCodeAndLogin(int $cldbid, string $userCode): bool { if (!is_int($cldbid)) { throw new \InvalidArgumentException("cldbid must be an int"); } @@ -176,7 +176,7 @@ class Auth { * @param $userCode string * @return bool */ - public static function checkConfirmationCode($cldbid, $userCode) { + public static function checkConfirmationCode(int $cldbid, string $userCode): bool { $knownCode = self::getConfirmationCode($cldbid); if ($knownCode === null) { @@ -191,7 +191,7 @@ class Auth { * @param $cldbid int * @return bool true on success, false otherwise */ - public static function loginUser($cldbid) { + public static function loginUser(int $cldbid): bool { $clientList = CacheManager::i()->getClientList(); foreach ($clientList as $client) { @@ -206,18 +206,18 @@ class Auth { return false; } - public static function invalidateUserGroupCache() { + public static function invalidateUserGroupCache(): void { unset($_SESSION["tsuser"]["servergroups"]); } /** * Returns an array containing cached array with group IDs of the user * @param $cacheTime int for how long we should cache the IDs? - * @return array array with server group IDs of the user + * @return array array with server group IDs of the user as ints * @throws UserNotAuthenticatedException if user is not logged in * @throws \TeamSpeak3_Exception when we cannot get data from the TS server */ - public static function getUserServerGroupIds($cacheTime = 60) { + public static function getUserServerGroupIds(int $cacheTime = 60): array { if (!self::isLoggedIn()) { throw new UserNotAuthenticatedException("User is not authenticated"); } @@ -273,17 +273,15 @@ class Auth { * @throws UserNotAuthenticatedException if user is not logged in * @throws \TeamSpeak3_Exception when we cannot get data from the TS server */ - public static function getUserServerGroups($cacheTime = 60) { + public static function getUserServerGroups(int $cacheTime = 60): array { $serverGroupIds = self::getUserServerGroupIds($cacheTime); $serverGroups = CacheManager::i()->getServerGroupList(); - $resut = array_filter($serverGroups, function ($serverGroup) use ($serverGroupIds) { + return array_filter($serverGroups, function (array $serverGroup) use ($serverGroupIds) { // If the group id is inside $serverGroupIds, // keep that group. Otherwise filter it out. - return in_array($serverGroup["sgid"], $serverGroupIds); + return in_array($serverGroup["sgid"], $serverGroupIds, true); }); - - return $resut; } } diff --git a/src/private/php/CacheManager.php b/src/private/php/CacheManager.php index fa5b9b4..41686d4 100644 --- a/src/private/php/CacheManager.php +++ b/src/private/php/CacheManager.php @@ -7,6 +7,7 @@ use Wruczek\TSWebsite\Utils\SingletonTait; use Wruczek\TSWebsite\Utils\TeamSpeakUtils; class CacheManager { + use SingletonTait; private $cache; @@ -22,11 +23,7 @@ class CacheManager { $this->cache = new PhpFileCache(__CACHE_DIR, "cachemanager"); } - private function tsNodeObjectToArray(array $object, $extendInfo = false) { - if (!is_array($object)) { - throw new \Exception("object must be a array filled with TeamSpeak3_Node_Abstract objects"); - } - + private function tsNodeObjectToArray(array $object, bool $extendInfo = false): array { $data = []; foreach ($object as $obj) { @@ -36,7 +33,7 @@ class CacheManager { return $data; } - public function getServerInfo($meta = false) { + public function getServerInfo(bool $meta = false) { if ($this->serverInfo) { return $this->serverInfo; } @@ -49,15 +46,16 @@ class CacheManager { TeamSpeakUtils::i()->addExceptionToExceptionsList($e); } } + return null; }, Config::get("cache_serverinfo"), $meta); } - public function clearServerInfo() { + public function clearServerInfo(): void { $this->cache->eraseKey("serverinfo"); } - public function getBanList($meta = false) { + public function getBanList(bool $meta = false) { if ($this->banList) { return $this->banList; } @@ -74,15 +72,16 @@ class CacheManager { TeamSpeakUtils::i()->addExceptionToExceptionsList($e); } } + return null; }, Config::get("cache_banlist"), $meta); } - public function clearBanList() { + public function clearBanList(): void { $this->cache->eraseKey("banlist"); } - public function getClientList($meta = false) { + public function getClientList(bool $meta = false) { if ($this->clientList) { return $this->clientList; } @@ -95,15 +94,16 @@ class CacheManager { TeamSpeakUtils::i()->addExceptionToExceptionsList($e); } } + return null; }, Config::get("cache_clientlist"), $meta); // Lower cache time because of login system } - public function clearClientList() { + public function clearClientList(): void { $this->cache->eraseKey("clientlist"); } - public function getClient($cldbid) { + public function getClient(int $cldbid) { $clients = $this->getClientList(); if ($clients === null) { @@ -119,7 +119,7 @@ class CacheManager { return null; } - public function getChannelList($meta = false) { + public function getChannelList(bool $meta = false) { if ($this->channelList) { return $this->channelList; } @@ -132,15 +132,16 @@ class CacheManager { TeamSpeakUtils::i()->addExceptionToExceptionsList($e); } } + return null; }, Config::get("cache_channelist"), $meta); } - public function clearChannelList() { + public function clearChannelList(): void { $this->cache->eraseKey("channellist"); } - public function getServerGroupList($meta = false) { + public function getServerGroupList(bool $meta = false) { if ($this->serverGroupList) { return $this->serverGroupList; } @@ -153,15 +154,16 @@ class CacheManager { TeamSpeakUtils::i()->addExceptionToExceptionsList($e); } } + return null; }, Config::get("cache_servergroups"), $meta); } - public function clearServerGroupList() { + public function clearServerGroupList(): void { $this->cache->eraseKey("servergrouplist"); } - public function getChannelGroupList($meta = false) { + public function getChannelGroupList(bool $meta = false) { if ($this->channelGroupList) { return $this->channelGroupList; } @@ -174,11 +176,12 @@ class CacheManager { TeamSpeakUtils::i()->addExceptionToExceptionsList($e); } } + return null; }, Config::get("cache_channelgroups"), $meta); } - public function clearChannelGroupList() { + public function clearChannelGroupList(): void { $this->cache->eraseKey("channelgrouplist"); } } diff --git a/src/private/php/News/DefaultNewsStore.php b/src/private/php/News/DefaultNewsStore.php index 9272309..1b314a7 100644 --- a/src/private/php/News/DefaultNewsStore.php +++ b/src/private/php/News/DefaultNewsStore.php @@ -2,8 +2,6 @@ namespace Wruczek\TSWebsite\News; -use function mb_substr; -use function time; use Wruczek\TSWebsite\Utils\DatabaseUtils; /** @@ -20,15 +18,7 @@ class DefaultNewsStore implements INewsStore { $this->db = DatabaseUtils::i()->getDb(); } - public function getNewsList($limit, $offset = null) { - if ($limit !== null && !\is_int($limit)) { - throw new \InvalidArgumentException("limit must be an integer"); - } - - if ($offset !== null && !\is_int($offset)) { - throw new \InvalidArgumentException("offset must be an integer"); - } - + public function getNewsList(int $limit, int $offset = null): array { $options = []; // Medoo: [$offset, $limit] // If we have both limit and offset @@ -64,17 +54,17 @@ class DefaultNewsStore implements INewsStore { return $newsList; } - public function getNews($newsId) { + public function getNews(int $newsId): ?array { return $this->db->get($this->newsTable, "*", [ "newsId" => $newsId, ]); } - public function getNewsCount() { + public function getNewsCount(): int { return $this->db->count($this->newsTable); } - public function addNews($title, $content, $addDate = null, $editDate = null) { + public function addNews(string $title, string $content, ?int $addDate = null, ?int $editDate = null): int { if ($addDate === null) { $addDate = time(); } @@ -89,7 +79,7 @@ class DefaultNewsStore implements INewsStore { return $this->db->id(); } - public function editNews($newsId, $title = null, $content = null, $addDate = null, $editDate = null) { + public function editNews(int $newsId, string $title = null, string $content = null, ?int $addDate = null, ?int $editDate = null): bool { $data = []; if ($title !== null) $data["title"] = $title; diff --git a/src/private/php/News/INewsStore.php b/src/private/php/News/INewsStore.php index 0da7e98..6382556 100644 --- a/src/private/php/News/INewsStore.php +++ b/src/private/php/News/INewsStore.php @@ -24,20 +24,20 @@ interface INewsStore { * @return array array with the news * @throws \Exception when we cannot get the news */ - public function getNewsList($limit, $offset = null); + public function getNewsList(int $limit, int $offset = null): array; /** * Returns full information about this particular news * @param int $newsId * @return array|null array with the news details or null if news was not found */ - public function getNews($newsId); + public function getNews(int $newsId): ?array; /** * Returns a number of news in the database * @return int */ - public function getNewsCount(); + public function getNewsCount(): int; /** * Adds a new news and return its new id @@ -47,7 +47,7 @@ interface INewsStore { * @param null|int $editDate * @return int newsId of the inserted news */ - public function addNews($title, $content, $addDate = null, $editDate = null); + public function addNews(string $title, string $content, ?int $addDate = null, ?int $editDate = null): int; /** * Edit the news selected by $newsId. All parameters are optional, and only the provided ones will be changed @@ -56,7 +56,8 @@ interface INewsStore { * @param string|null $content * @param int|null $addDate * @param int|null $editDate + * @return bool true on success */ - public function editNews($newsId, $title = null, $content = null, $addDate = null, $editDate = null); + public function editNews(int $newsId, string $title = null, string $content = null, ?int $addDate = null, ?int $editDate = null): bool; } diff --git a/src/private/php/ServerIconCache.php b/src/private/php/ServerIconCache.php index 141bf7d..9147df0 100644 --- a/src/private/php/ServerIconCache.php +++ b/src/private/php/ServerIconCache.php @@ -9,20 +9,32 @@ class ServerIconCache { private static $iconsCacheDir = __CACHE_DIR . "/servericons"; - public static function getIconBytes($iconId) { + /** + * Returns contents of an icon + * @param string|int $iconId icon id + * @return string|null returns contents as string or null if not found + * @throws \Exception + */ + public static function getIconBytes($iconId): ?string { if (!is_numeric($iconId)) { throw new \Exception("iconid need to be an int or numeric string"); } $file = @file_get_contents(self::$iconsCacheDir . "/" . $iconId); - return $file === false ? null : $file; // return null on error + + // return null on error + if ($file === false) { + return null; + } + + return $file; } - public static function hasIcon($iconId) { + public static function hasIcon($iconId): bool { return self::getIconBytes($iconId) !== null; } - public static function syncIcons() { + public static function syncIcons(): void { if (!file_exists(self::$iconsCacheDir) && !mkdir(self::$iconsCacheDir)) { throw new \Exception("Cannot create icons cache directory at " . self::$iconsCacheDir); } @@ -36,7 +48,7 @@ class ServerIconCache { } try { - $iconData = self::downloadIcon($iconId); + $iconData = (string) self::downloadIcon($iconId); } catch (\Exception $e) { trigger_error("Cannot download icon $iconId"); continue; @@ -50,7 +62,7 @@ class ServerIconCache { } } - public static function syncIfNeeded() { + public static function syncIfNeeded(): void { (new PhpFileCache(__CACHE_DIR))->refreshIfExpired("lasticonsync", function () { // Do not sync icons if we cannot connect the the TS server if (!TeamSpeakUtils::i()->checkTSConnection()) { @@ -62,11 +74,11 @@ class ServerIconCache { }, Config::get("cache_servericons", 300)); } - public static function isLocal($iconId) { + public static function isLocal(int $iconId): bool { return $iconId > 0 && $iconId < 1000; } - public static function iconIdFromName($iconName) { + public static function iconIdFromName(string $iconName): string { return substr($iconName, 5); } @@ -78,7 +90,7 @@ class ServerIconCache { * @param $iconId int * @return int */ - public static function unsignIcon($iconId) { + public static function unsignIcon(int $iconId): int { if (!is_int($iconId)) { throw new \InvalidArgumentException("iconId must be an integer"); } @@ -86,11 +98,11 @@ class ServerIconCache { return ($iconId < 0) ? (2 ** 32) - ($iconId * -1) : $iconId; } - public static function downloadIcon($iconId) { + public static function downloadIcon($iconId): \TeamSpeak3_Helper_String { return TeamSpeakUtils::i()->ftDownloadFile("/icon_$iconId"); } - public static function ftDownloadIconList() { + public static function ftDownloadIconList(): array { try { return TeamSpeakUtils::i()->getTSNodeServer()->channelFileList(0, "", "/icons/"); } catch (\TeamSpeak3_Adapter_ServerQuery_Exception $e) { diff --git a/src/private/php/Utils/ApiUtils.php b/src/private/php/Utils/ApiUtils.php index f20b68b..f15d7e9 100644 --- a/src/private/php/Utils/ApiUtils.php +++ b/src/private/php/Utils/ApiUtils.php @@ -2,7 +2,6 @@ namespace Wruczek\TSWebsite\Utils; -use function is_array; use Wruczek\TSWebsite\Auth; class ApiUtils { @@ -10,7 +9,7 @@ class ApiUtils { /** * Checks if the user is logged in, and if not outputs a JSON error and terminates the script */ - public static function checkAuth() { + public static function checkAuth(): void { if (!Auth::isLoggedIn()) { self::jsonError("You must be logged in to perform this action", "NOT_AUTHENTICATED", 401); exit; @@ -20,14 +19,14 @@ class ApiUtils { /** * Calls jsonResponse with true as success parameter */ - public static function jsonSuccess($data = null, $code = null, $statusCode = null) { + public static function jsonSuccess($data = null, $code = null, ?int $statusCode = null): void { self::jsonResponse(true, $data, $code, $statusCode); } /** * Calls jsonResponse with false as success parameter */ - public static function jsonError($data = null, $code = null, $statusCode = null) { + public static function jsonError($data = null, $code = null, ?int $statusCode = null): void { self::jsonResponse(false, $data, $code, $statusCode); } @@ -42,11 +41,7 @@ class ApiUtils { * @param $code int|string error code * @param $statusCode int Status code to return. null to not change */ - public static function jsonResponse($success, $data = null, $code = null, $statusCode = null) { - if (!is_bool($success)) { - throw new \InvalidArgumentException("success must be a boolean"); - } - + public static function jsonResponse(bool $success, $data = null, $code = null, ?int $statusCode = null): void { $json = ["success" => $success]; if ($code !== null) { @@ -68,16 +63,16 @@ class ApiUtils { self::outputJson($json); } - public static function outputJson($array) { + public static function outputJson(array $array): void { @header("Content-Type: application/json"); echo json_encode($array); } - public static function getPostParam($key) { + public static function getPostParam(string $key) { return self::getParam($_POST, $key); } - public static function getGetParam($key) { + public static function getGetParam(string $key) { return self::getParam($_GET, $key); } @@ -87,9 +82,9 @@ class ApiUtils { * @param $array array * @param $key string * @param $canBeArray bool whenever the data can be an array - * @return mixed + * @return string|array */ - public static function getParam($array, $key, $canBeArray = false) { + public static function getParam(array $array, string $key, bool $canBeArray = false) { if (!isset($array[$key])) { self::jsonError("Parameter $key is not provided", 400); exit; @@ -97,7 +92,7 @@ class ApiUtils { $data = $array[$key]; - if (is_array($data) && !$canBeArray) { + if (!$canBeArray && is_array($data)) { self::jsonError("Parameter $key cannot be an array", 400); exit; } diff --git a/src/private/php/Utils/DatabaseUtils.php b/src/private/php/Utils/DatabaseUtils.php index 98d7b97..662ecdb 100644 --- a/src/private/php/Utils/DatabaseUtils.php +++ b/src/private/php/Utils/DatabaseUtils.php @@ -1,6 +1,7 @@ translate("DATE_FORMAT"); } catch (\Exception $e) { @@ -24,7 +24,7 @@ class DateUtils { * be retrieved, default value is returned * @return string time format */ - public static function getTimeFormat() { + public static function getTimeFormat(): string { try { return LanguageUtils::i()->translate("TIME_FORMAT"); } catch (\Exception $e) { @@ -34,29 +34,29 @@ class DateUtils { /** * Returns timestamp formatted to string with format from getDateFormat() - * @param $timestamp + * @param int $timestamp * @return false|string */ - public static function formatDate($timestamp) { + public static function formatDate(int $timestamp) { return date(self::getDateFormat(), $timestamp); } /** * Returns timestamp formatted to string with format from getTimeFormat() - * @param $timestamp + * @param int $timestamp * @return false|string */ - public static function foramtTime($timestamp) { + public static function foramtTime(int $timestamp) { return date(self::getTimeFormat(), $timestamp); } /** * Returns timestamp formatted with formatToDate() and formatToTime() - * @param $timestamp + * @param int $timestamp * @param string $additional additional date format * @return false|string */ - public static function formatDatetime($timestamp, $additional = "") { + public static function formatDatetime(int $timestamp, string $additional = "") { return date(trim(self::getDateFormat() . ", " . self::getTimeFormat() . " " . $additional), $timestamp); } diff --git a/src/private/php/Utils/Language/Language.php b/src/private/php/Utils/Language/Language.php index b2a76d3..ed7b815 100644 --- a/src/private/php/Utils/Language/Language.php +++ b/src/private/php/Utils/Language/Language.php @@ -19,7 +19,7 @@ class Language { * @param $isDefault * @param $languageItems */ - public function __construct($languageId, $languageNameEnglish, $languageNameNative, $languageCode, $isDefault, $languageItems) { + public function __construct(int $languageId, string $languageNameEnglish, string $languageNameNative, string $languageCode, bool $isDefault, array $languageItems) { $this->languageId = $languageId; $this->languageNameEnglish = $languageNameEnglish; $this->languageNameNative = $languageNameNative; @@ -32,7 +32,7 @@ class Language { * Returns language ID * @return int language ID */ - public function getLanguageId() { + public function getLanguageId(): int { return $this->languageId; } @@ -40,7 +40,7 @@ class Language { * Returns language name in English * @return string language name in English */ - public function getLanguageNameEnglish() { + public function getLanguageNameEnglish(): string { return $this->languageNameEnglish; } @@ -48,7 +48,7 @@ class Language { * Returns language name in its native form * @return string language name in its native form */ - public function getLanguageNameNative() { + public function getLanguageNameNative(): string { return $this->languageNameNative; } @@ -56,7 +56,7 @@ class Language { * Returns language code * @return string language code */ - public function getLanguageCode() { + public function getLanguageCode(): string { return $this->languageCode; } @@ -64,7 +64,7 @@ class Language { * Returns true when this language is set as default site language * @return boolean true when default, false otherwise */ - public function isDefault() { + public function isDefault(): bool { return $this->isDefault; } @@ -72,7 +72,7 @@ class Language { * Sets this language as default language of the site * @return boolean true on success, false otherwise */ - public function setAsDefaultLanguage() { + public function setAsDefaultLanguage(): bool { return LanguageUtils::i()->setDefaultLanguage($this); } @@ -80,7 +80,7 @@ class Language { * Returns simple array with identifier -> value mapping, created from getLanguageItems() * @return array */ - public function getSimpleItemsArray() { + public function getSimpleItemsArray(): array { $ret = []; foreach ($this->getLanguageItems() as $item) { @@ -93,13 +93,15 @@ class Language { /** * Returns language item * @param $identifier string identifier - * @return LanguageItem LanguageItem if found, null otherwise + * @return LanguageItem|null LanguageItem if found, null otherwise */ - public function getLanguageItem($identifier) { + public function getLanguageItem($identifier): ?LanguageItem { foreach ($this->getLanguageItems() as $item) { - if(strcasecmp($item->getIdentifier(), $identifier) === 0) + if(strcasecmp($item->getIdentifier(), $identifier) === 0) { return $item; + } } + return null; } @@ -107,7 +109,7 @@ class Language { * Returns language strings * @return array array filled with LanguageItem */ - public function getLanguageItems() { + public function getLanguageItems(): array { return $this->languageItems; } diff --git a/src/private/php/Utils/Language/LanguageItem.php b/src/private/php/Utils/Language/LanguageItem.php index 468e210..1856023 100644 --- a/src/private/php/Utils/Language/LanguageItem.php +++ b/src/private/php/Utils/Language/LanguageItem.php @@ -13,7 +13,7 @@ class LanguageItem { * @param $value * @param $comment */ - public function __construct($identifier, $value, $comment) { + public function __construct(string $identifier, string $value, ?string $comment) { $this->identifier = $identifier; $this->value = $value; $this->comment = $comment; @@ -23,7 +23,7 @@ class LanguageItem { * Returns item identifier * @return string */ - public function getIdentifier() { + public function getIdentifier(): string { return $this->identifier; } @@ -31,19 +31,19 @@ class LanguageItem { * Returns item value * @return string */ - public function getValue() { + public function getValue(): string { return $this->value; } /** * Returns item comment, can be null - * @return string + * @return string|null */ - public function getComment() { + public function getComment(): ?string { return $this->comment; } - public function __toString() { + public function __toString(): string { return $this->getValue(); } diff --git a/src/private/php/Utils/Language/LanguageUtils.php b/src/private/php/Utils/Language/LanguageUtils.php index 00cefa5..791086c 100644 --- a/src/private/php/Utils/Language/LanguageUtils.php +++ b/src/private/php/Utils/Language/LanguageUtils.php @@ -21,8 +21,12 @@ class LanguageUtils { /** * Short function for translate + * @param string $identifier + * @param array|string $args + * @return string + * @throws \Exception */ - public static function tl($identifier, $args = []) { + public static function tl(string $identifier, $args = []): string { return self::i()->translate($identifier, $args); } @@ -37,47 +41,50 @@ class LanguageUtils { /** * Returns language by its ID * @param $languageId int Language ID - * @return Language|boolean returns Language when found, false otherwise + * @return Language|null returns Language when found, null otherwise */ - public function getLanguageById($languageId) { + public function getLanguageById(int $languageId): ?Language { foreach ($this->getLanguages() as $lang) { - if($lang->getLanguageId() === $languageId) + if($lang->getLanguageId() === $languageId) { return $lang; + } } - return false; + return null; } /** * Returns language by its Language Code * @param $languageCode string Language Code - * @return Language|boolean returns Language when found, false otherwise + * @return Language|null returns Language when found, null otherwise */ - public function getLanguageByCode($languageCode) { + public function getLanguageByCode(string $languageCode): ?Language { foreach ($this->getLanguages() as $lang) { - if(strcasecmp($lang->getLanguageCode(), $languageCode) === 0) + if(strcasecmp($lang->getLanguageCode(), $languageCode) === 0) { return $lang; + } } - return false; + return null; } /** * Returns all available languages - * @return array|mixed + * @return array */ - public function getLanguages() { + public function getLanguages(): array { return $this->languages; } /** * Returns default language - * @return Language default language + * @return Language|null default language, null if not defined */ - public function getDefaultLanguage() { + public function getDefaultLanguage(): ?Language { foreach ($this->getLanguages() as $lang) { - if($lang->isDefault()) + if($lang->isDefault()) { return $lang; + } } return null; @@ -88,7 +95,7 @@ class LanguageUtils { * @param $language Language * @return boolean true on success, false otherwise */ - public function setDefaultLanguage($language) { + public function setDefaultLanguage(Language $language): bool { $db = DatabaseUtils::i()->getDb(); // set all languages as non-default, if this succeeds... @@ -104,9 +111,9 @@ class LanguageUtils { /** * Tried to determine user language and returns it - * @return Language user language if determined, null otherwise + * @return Language|null user language if determined, null otherwise */ - public function detectUserLanguage() { + public function detectUserLanguage(): ?Language { if (isset($_COOKIE["tswebsite_language"])) { // check cookie $langcode = $_COOKIE["tswebsite_language"]; } else if (isset($_SERVER["HTTP_ACCEPT_LANGUAGE"])) { // check http headers @@ -114,8 +121,9 @@ class LanguageUtils { } // if language with that code exists, return it - if(!empty($langcode) && ($lang = $this->getLanguageByCode($langcode))) + if(!empty($langcode) && ($lang = $this->getLanguageByCode($langcode))) { return $lang; + } return null; } @@ -125,30 +133,49 @@ class LanguageUtils { * @param bool $updateCache true if the file cache should also be updated * @return array */ - public function refreshLanguageCache($updateCache = true) { + public function refreshLanguageCache(bool $updateCache = true): array { $db = DatabaseUtils::i()->getDb(); - $data = $db->select("languages", ["langid", "englishname", "nativename", "langcode", "isdefault"]); + $data = $db->select("languages", [ + "langid", + "englishname", + "nativename", + "langcode", + "isdefault" + ]); $langs = []; foreach ($data as $lang) { - $langid = $lang["langid"]; + $langid = (int) $lang["langid"]; $englishname = $lang["englishname"]; $nativename = $lang["nativename"]; $langcode = $lang["langcode"]; - $isdefault = $lang["isdefault"]; + $isdefault = $lang["isdefault"] === "1"; - $strings = $db->select("translations", ["identifier", "value", "comment"], ["langid" => $langid]); + $strings = $db->select("translations", [ + "identifier", + "value", + "comment" + ], [ + "langid" => $langid + ]); $languageItems = []; - foreach ($strings as $str) - $languageItems[] = new LanguageItem($str["identifier"], $str["value"], $str["comment"]); + foreach ($strings as $str) { + $comment = null; + + if (isset($str["comment"]) && $str["comment"] !== "") { + $comment = $str["comment"]; + } + + $languageItems[] = new LanguageItem($str["identifier"], $str["value"], $comment); + } $langs[] = new Language($langid, $englishname, $nativename, $langcode, $isdefault, $languageItems); } - uasort($langs, function ($a, $b) { + uasort($langs, function (Language $a, Language $b) { if ($a->getLanguageId() === $b->getLanguageId()) { return 0; } @@ -158,8 +185,9 @@ class LanguageUtils { $this->languages = $langs; - if($updateCache) + if($updateCache) { $this->cache->store("languages", $langs, Config::get("cache_languages", 300)); + } return $langs; } @@ -169,12 +197,12 @@ class LanguageUtils { * language, it tries to get it from the default language. * User language is determined with getDefaultLanguage() function. * @param $identifier string Translation identifier - * @param array $args Arguments that will replace placeholders + * @param array|string $args Arguments that will replace placeholders * @return string Translated text * @throws \Exception When default site or user language cannot * be found, and/or if $identifier is not found */ - public function translate($identifier, $args = []) { + public function translate(string $identifier, $args = []): string { if (!is_array($args)) { $args = [$args]; } @@ -182,16 +210,19 @@ class LanguageUtils { $defaultlang = $this->getDefaultLanguage(); $lang = $this->getLanguageById(@$_SESSION["userlanguageid"]); - if(!$lang && !$defaultlang) + if(!$lang && !$defaultlang) { throw new \Exception("Cannot get user or default language"); + } $item = $lang->getLanguageItem($identifier); - if(!$item) + if(!$item) { $item = $defaultlang->getLanguageItem($identifier); + } - if(!$item) + if(!$item) { throw new \Exception("Cannot get translation for $identifier"); + } $val = $item->getValue(); diff --git a/src/private/php/Utils/SingletonTait.php b/src/private/php/Utils/SingletonTait.php index f868ac5..70c87d6 100644 --- a/src/private/php/Utils/SingletonTait.php +++ b/src/private/php/Utils/SingletonTait.php @@ -9,11 +9,12 @@ trait SingletonTait { * Call this method to get singleton * @return self */ - public static function Instance() { + public static function Instance(): self { static $inst = null; - if ($inst === null) + if ($inst === null) { $inst = new self(); + } return $inst; } @@ -22,7 +23,7 @@ trait SingletonTait { * A shorthand to get the singleton * @return self */ - public static function i() { + public static function i(): self { return self::Instance(); } diff --git a/src/private/php/Utils/TeamSpeakUtils.php b/src/private/php/Utils/TeamSpeakUtils.php index 260f3b9..343a6f0 100644 --- a/src/private/php/Utils/TeamSpeakUtils.php +++ b/src/private/php/Utils/TeamSpeakUtils.php @@ -25,9 +25,9 @@ class TeamSpeakUtils { /** * Returns TeamSpeak3_Node_Host object created using * data from config database - * @return \TeamSpeak3_Node_Host + * @return \TeamSpeak3_Node_Host|null */ - public function getTSNodeHost() { + public function getTSNodeHost(): ?\TeamSpeak3_Node_Host { if($this->tsNodeHost === null) { $hostname = $this->configUtils->getValue("query_hostname"); $queryport = $this->configUtils->getValue("query_port"); @@ -49,9 +49,9 @@ class TeamSpeakUtils { /** * Returns TeamSpeak3_Node_Server object created * using getTSNodeHost() method. - * @return \TeamSpeak3_Node_Server + * @return \TeamSpeak3_Node_Server|null */ - public function getTSNodeServer() { + public function getTSNodeServer(): ?\TeamSpeak3_Node_Server { // Don't continue if TSNodeHost is NULL (not working / not initialised) if($this->tsNodeServer === null && $this->getTSNodeHost()) { $port = $this->configUtils->getValue("tsserver_port"); @@ -92,15 +92,22 @@ class TeamSpeakUtils { /** * Tries to download file from the TS3 server. It might be an actual file, * icon or avatar. Returns downloaded data. Might throw exceptions when filetransfer fails. - * @param $filename + * @param string $filename * @param int $cid Channel Id (defaults to 0 - server) * @param string $cpw Channel password (defaults to empty) - * @return mixed - * @throws \TeamSpeak3_Adapter_ServerQuery_Exception + * @return \TeamSpeak3_Helper_String + * @throws \TeamSpeak3_Adapter_ServerQuery_Exception|\TeamSpeak3_Exception */ - public function ftDownloadFile($filename, $cid = 0, $cpw = "") { + public function ftDownloadFile(string $filename, int $cid = 0, string $cpw = ""): \TeamSpeak3_Helper_String { + if (!$this->checkTSConnection()) { + throw new \TeamSpeak3_Exception("Cannot connect to the TeamSpeak server"); + } + $dl = $this->getTSNodeServer()->transferInitDownload(mt_rand(0x0000, 0xFFFF), $cid, $filename, $cpw); + + // wrap host in brackets if it contains a colon (is a IPv6) $host = (false !== strpos($dl["host"], ":") ? "[" . $dl["host"] . "]" : $dl["host"]); + $filetransfer = \TeamSpeak3::factory("filetransfer://$host:" . $dl["port"]); return $filetransfer->download($dl["ftkey"], $dl["size"]); @@ -110,7 +117,7 @@ class TeamSpeakUtils { * Resets current connection, forces to reconnect to the TeamSpeak server * next time you call getTSNodeHost or getTSNodeServer */ - public function reset() { + public function reset(): void { $this->tsNodeHost = null; $this->tsNodeServer = null; } @@ -121,7 +128,7 @@ class TeamSpeakUtils { * Use it just before accessing the server, preferably after checking cache. * @return bool true if TeamSpeak connection succeeded, false otherwise */ - public function checkTSConnection() { + public function checkTSConnection(): bool { return $this->getTSNodeHost() !== null && $this->getTSNodeServer() !== null && empty($this->getExceptionsList()); @@ -131,7 +138,7 @@ class TeamSpeakUtils { * Adds exception to the exceptions list * @param \Exception $exception */ - public function addExceptionToExceptionsList($exception) { + public function addExceptionToExceptionsList(\Exception $exception): void { $this->exceptionsList[$exception->getCode()] = $exception; } @@ -140,7 +147,7 @@ class TeamSpeakUtils { * when calling getTSNodeServer(), getTSNodeServer() and other methods * @return array Array filled with exceptions. Empty if no exceptions where thrown. */ - public function getExceptionsList() { + public function getExceptionsList(): array { return $this->exceptionsList; } } diff --git a/src/private/php/Utils/TemplateUtils.php b/src/private/php/Utils/TemplateUtils.php index 0a3bfc6..b2baac9 100644 --- a/src/private/php/Utils/TemplateUtils.php +++ b/src/private/php/Utils/TemplateUtils.php @@ -45,15 +45,16 @@ class TemplateUtils { * Returns latte object * @return \Latte\Engine Latte object */ - public function getLatte() { + public function getLatte(): Engine { return $this->latte; } /** * Echoes rendered template + * @throws \Exception * @see renderTemplateToString */ - public function renderTemplate($templateName, $data = [], $loadLangs = true) { + public function renderTemplate(string $templateName, array $data = [], bool $loadLangs = true): void { echo $this->renderTemplateToString($templateName, $data, $loadLangs); } @@ -63,8 +64,13 @@ class TemplateUtils { * @param string $errorname Error title * @param string $description Error description */ - public function renderErrorTemplate($errorcode = "", $errorname = "", $description = "") { - $data = ["errorcode" => $errorcode, "errorname" => $errorname, "description" => $description]; + public function renderErrorTemplate(string $errorcode = null, string $errorname = "Error", string $description = null): void { + $data = [ + "errorcode" => $errorcode, + "errorname" => $errorname, + "description" => $description + ]; + $this->renderTemplate("errorpage", $data, false); } @@ -75,11 +81,16 @@ class TemplateUtils { * @return string Rendered template * @throws \Exception when we cannot get the CSRF token */ - public function renderTemplateToString($templateName, $data = [], $loadLangs = true) { + public function renderTemplateToString($templateName, $data = [], $loadLangs = true): string { $dbutils = DatabaseUtils::i(); if($loadLangs) { - $userlang = LanguageUtils::i()->getLanguageById($_SESSION["userlanguageid"]); + $langUtils = LanguageUtils::i(); + $userlang = $langUtils->getLanguageById($_SESSION["userlanguageid"]); + + if ($userlang === null) { + $userlang = $langUtils->getDefaultLanguage(); + } $data["languageList"] = LanguageUtils::i()->getLanguages(); $data["userLanguage"] = $userlang; @@ -120,9 +131,9 @@ class TemplateUtils { * Returns time elapsed from website load start until now * @param bool $raw If true, returns elapsed time in * milliseconds. Defaults to false. - * @return string + * @return string|float */ - public static function getRenderTime($raw = false) { + public static function getRenderTime(bool $raw = false) { if($raw) { return microtime(true) - __RENDER_START; } else { @@ -136,16 +147,17 @@ class TemplateUtils { * @see getOldestCacheTimestamp * @param $data */ - public function storeOldestCache($data) { - if ($data["expired"] && (!$this->oldestCache || $this->oldestCache > $data["time"])) + public function storeOldestCache($data): void { + if ($data["expired"] && (!$this->oldestCache || $this->oldestCache > $data["time"])) { $this->oldestCache = $data["time"]; + } } /** * @see storeOldestCache - * @return int Oldest cache timestamp, null if not set + * @return int|null Oldest cache timestamp, null if not set */ - public function getOldestCacheTimestamp() { + public function getOldestCacheTimestamp(): ?int { return $this->oldestCache; } @@ -158,7 +170,7 @@ class TemplateUtils { * resource and add a version timestamp. If string, its gonna treat it as a * integrity hash and add it along with crossorigin="anonymous" tag. */ - public static function includeResource($resourceType, $url, $parameter = null) { + public static function includeResource(string $resourceType, string $url, $parameter = null): void { $url = str_replace('{cdnjs}', 'https://cdnjs.cloudflare.com/ajax/libs', $url); $attributes = ""; @@ -185,14 +197,14 @@ class TemplateUtils { /** * @see includeResource */ - public static function includeStylesheet($url, $parameter = null) { + public static function includeStylesheet(string $url, $parameter = null): void { self::includeResource("stylesheet", $url, $parameter); } /** * @see includeResource */ - public static function includeScript($url, $parameter = null) { + public static function includeScript(string $url, $parameter = null): void { self::includeResource("script", $url, $parameter); } } diff --git a/src/private/php/ViewerRenderer.php b/src/private/php/ViewerRenderer.php index 728ae05..ab4a982 100644 --- a/src/private/php/ViewerRenderer.php +++ b/src/private/php/ViewerRenderer.php @@ -20,7 +20,7 @@ class ViewerRenderer { private $hiddenChannelIds; - public function __construct($imgPath, array $hiddenChannelIds = []) { + public function __construct(string $imgPath, array $hiddenChannelIds = []) { $this->imgPath = $imgPath; $this->hiddenChannelIds = $hiddenChannelIds; diff --git a/src/private/php/load.php b/src/private/php/load.php index 86683be..7e5cb7a 100644 --- a/src/private/php/load.php +++ b/src/private/php/load.php @@ -65,14 +65,14 @@ if(!isset($_SESSION["userlanguageid"])) { /** * Shortcut to translate and output the result */ - function __($identifier, $args = []) { + function __(string $identifier, array $args = []) { echo __get($identifier, $args); } /** * Shortcut to translate and return the result */ - function __get($identifier, $args = []) { + function __get(string $identifier, array $args = []) { try { return LanguageUtils::i()->translate($identifier, $args); } catch (\Exception $e) {