diff --git a/assets/js/misuzu/userrels.js b/assets/js/misuzu/userrels.js deleted file mode 100644 index 791c4933..00000000 --- a/assets/js/misuzu/userrels.js +++ /dev/null @@ -1,104 +0,0 @@ -Misuzu.UserRelations = {}; -Misuzu.UserRelations.Type = DefineEnum({ none: 0, follow: 1, }); -Misuzu.UserRelations.init = function() { - var buttons = document.getElementsByClassName('js-user-relation-action'); - - for(var i = 0; i < buttons.length; ++i) { - switch(buttons[i].tagName.toLowerCase()) { - case 'a': - buttons[i].removeAttribute('href'); - buttons[i].removeAttribute('target'); - buttons[i].removeAttribute('rel'); - break; - } - - buttons[i].addEventListener('click', Misuzu.UserRelations.setRelationHandler); - } -}; -Misuzu.UserRelations.setRelation = function(user, type, onSuccess, onFailure) { - var xhr = new XMLHttpRequest; - xhr.addEventListener('readystatechange', function() { - if(xhr.readyState !== 4) - return; - - Misuzu.CSRF.setToken(xhr.getResponseHeader('X-Misuzu-CSRF')); - - var json = JSON.parse(xhr.responseText), - message = json.error || json.message; - - if(message && onFailure) - onFailure(message); - else if(!message && onSuccess) - onSuccess(json); - }); - xhr.open('GET', Misuzu.Urls.format('user-relation-create', [Misuzu.Urls.v('user', user), Misuzu.Urls.v('type', type)])); - xhr.setRequestHeader('X-Misuzu-XHR', 'user_relation'); - xhr.setRequestHeader('X-Misuzu-CSRF', Misuzu.CSRF.getToken()); - xhr.send(); -}; -Misuzu.UserRelations.ICO_ADD = 'fas fa-user-plus'; -Misuzu.UserRelations.ICO_REM = 'fas fa-user-minus'; -Misuzu.UserRelations.ICO_BUS = 'fas fa-spinner fa-pulse'; -Misuzu.UserRelations.BTN_BUS = 'input__button--busy'; -Misuzu.UserRelations.setRelationHandler = function(ev) { - var target = this, - userId = parseInt(target.dataset.relationUser), - relationType = parseInt(target.dataset.relationType), - isButton = target.classList.contains('input__button'), - icon = target.querySelector('[class^="fa"]'); - - if(isButton) { - if(target.classList.contains(Misuzu.UserRelations.BTN_BUS)) - return; - target.classList.add(Misuzu.UserRelations.BTN_BUS); - } - - if(icon) - icon.className = Misuzu.UserRelations.ICO_BUS; - - Misuzu.UserRelations.setRelation( - userId, - relationType, - function(info) { - target.classList.remove(Misuzu.UserRelations.BTN_BUS); - - switch(info.relation_type) { - case Misuzu.UserRelations.Type.none: - if(isButton) { - if(target.classList.contains('input__button--destroy')) - target.classList.remove('input__button--destroy'); - - target.textContent = 'Follow'; - } - - if(icon) { - icon.className = Misuzu.UserRelations.ICO_ADD; - target.title = 'Follow'; - } - - target.dataset.relationType = Misuzu.UserRelations.Type.follow.toString(); - break; - - case Misuzu.UserRelations.Type.follow: - if(isButton) { - if(!target.classList.contains('input__button--destroy')) - target.classList.add('input__button--destroy'); - - target.textContent = 'Unfollow'; - } - - if(icon) { - icon.className = Misuzu.UserRelations.ICO_REM; - target.title = 'Unfollow'; - } - - target.dataset.relationType = Misuzu.UserRelations.Type.none.toString(); - break; - } - }, - function(msg) { - target.classList.remove(Misuzu.UserRelations.BTN_BUS); - Misuzu.showMessageBox(msg); - } - ); -}; diff --git a/misuzu.php b/misuzu.php index dcb54266..35de7582 100644 --- a/misuzu.php +++ b/misuzu.php @@ -242,7 +242,7 @@ if(parse_url($_SERVER['PHP_SELF'], PHP_URL_PATH) !== '/index.php') if(!empty($userInfo)) Template::set('current_user', $userInfo); -$inManageMode = starts_with($_SERVER['REQUEST_URI'], '/manage'); +$inManageMode = str_starts_with($_SERVER['REQUEST_URI'], '/manage'); $hasManageAccess = User::hasCurrent() && !User::getCurrent()->hasActiveWarning() && perms_check_user(MSZ_PERMS_GENERAL, User::getCurrent()->getId(), MSZ_PERM_GENERAL_CAN_MANAGE); diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 00000000..a2e32736 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,6 @@ +parameters: + level: 5 + paths: + - src + bootstrapFiles: + - misuzu.php diff --git a/src/AuditLog.php b/src/AuditLog.php index 0d4be27f..11e86962 100644 --- a/src/AuditLog.php +++ b/src/AuditLog.php @@ -149,7 +149,7 @@ class AuditLog { public static function create(string $action, array $params = [], ?User $user = null, ?string $remoteAddr = null): void { $user = $user ?? User::getCurrent(); - $remoteAddr = $ipAddress ?? IPAddress::remote(); + $remoteAddr = $remoteAddr ?? IPAddress::remote(); $createLog = DB::prepare( 'INSERT INTO `' . DB::PREFIX . self::TABLE . '` (`log_action`, `user_id`, `log_params`, `log_ip`, `log_country`)' . ' VALUES (:action, :user, :params, INET6_ATON(:ip), :country)' @@ -162,7 +162,7 @@ class AuditLog { } private static function countQueryBase(): string { - return sprintf(self::QUERY_SELECT, sprintf('COUNT(*)', self::TABLE)); + return sprintf(self::QUERY_SELECT, 'COUNT(*)'); } public static function countAll(?User $user = null): int { $getCount = DB::prepare( diff --git a/src/AuthToken.php b/src/AuthToken.php index 90dda21b..a4b0820d 100644 --- a/src/AuthToken.php +++ b/src/AuthToken.php @@ -65,7 +65,7 @@ class AuthToken { } public static function unpack(string $data, bool $base64 = true): self { - $obj = new static; + $obj = new AuthToken; if(empty($data)) return $obj; @@ -83,7 +83,7 @@ class AuthToken { } public static function create(User $user, UserSession $session): self { - return (new static) + return (new AuthToken) ->setUser($user) ->setSession($session); } diff --git a/src/Changelog/ChangelogChange.php b/src/Changelog/ChangelogChange.php index 76176c75..7b96a20b 100644 --- a/src/Changelog/ChangelogChange.php +++ b/src/Changelog/ChangelogChange.php @@ -183,7 +183,7 @@ class ChangelogChange implements JsonSerializable { return [ 'id' => $this->getId(), 'user' => $this->getUserId(), - 'action' => $this->getActionId(), + 'action' => $this->getAction(), 'header' => $this->getHeader(), 'body' => $this->getBody(), 'comments' => $this->getCommentsCategoryName(), diff --git a/src/Changelog/ChangelogChangeTag.php b/src/Changelog/ChangelogChangeTag.php index f4ec7f98..9ddf6e6d 100644 --- a/src/Changelog/ChangelogChangeTag.php +++ b/src/Changelog/ChangelogChangeTag.php @@ -78,7 +78,7 @@ class ChangelogChangeTag implements JsonSerializable { private static function byQueryBase(): string { return sprintf(self::QUERY_SELECT, sprintf(self::SELECT, self::TABLE)); } - public static function byExact(ChangelogChange $change, ChangelogTag $tag): array { + public static function byExact(ChangelogChange $change, ChangelogTag $tag): self { $tag = DB::prepare(self::byQueryBase() . ' WHERE `tag_id` = :tag') ->bind('change', $change->getId()) ->bind('tag', $tag->getId()) diff --git a/src/Colour.php b/src/Colour.php index 832dbab2..67300af0 100644 --- a/src/Colour.php +++ b/src/Colour.php @@ -18,14 +18,14 @@ class Colour { } public static function none(): self { - return new static(self::FLAG_INHERIT); + return new Colour(self::FLAG_INHERIT); } public static function fromRgb(int $red, int $green, int $blue): self { - return (new static)->setRed($red)->setGreen($green)->setBlue($blue); + return (new Colour)->setRed($red)->setGreen($green)->setBlue($blue); } public static function fromHex(string $hex): self { - return (new static)->setHex($hex); + return (new Colour)->setHex($hex); } public function getRaw(): int { @@ -99,7 +99,7 @@ class Colour { return $this; } - public function getLuminance(): int { + public function getLuminance(): float { return self::LUMINANCE_WEIGHT_RED * $this->getRed() + self::LUMINANCE_WEIGHT_GREEN * $this->getGreen() + self::LUMINANCE_WEIGHT_BLUE * $this->getBlue(); diff --git a/src/Comments/CommentsVote.php b/src/Comments/CommentsVote.php index 5a8f62c5..0ab2bd9f 100644 --- a/src/Comments/CommentsVote.php +++ b/src/Comments/CommentsVote.php @@ -128,7 +128,7 @@ class CommentsVote implements JsonSerializable { } private static function fake(CommentsPost $post, User $user, int $vote): CommentsVote { - $fake = new static; + $fake = new CommentsVote; $fake->comment_id = $post->getId(); $fake->comment = $post; $fake->user_id = $user->getId(); diff --git a/src/DB.php b/src/DB.php index a07cb1f4..6ce4293d 100644 --- a/src/DB.php +++ b/src/DB.php @@ -4,6 +4,14 @@ namespace Misuzu; use PDO; use Misuzu\Database\Database; +/** + * @method static PDO getPDO() + * @method static int queries() + * @method static int exec(string $stmt) + * @method static \Misuzu\Database\DatabaseStatement prepare(string $stmt, array $options = []) + * @method static \Misuzu\Database\DatabaseStatement query(string $stmt, ?int $fetchMode = null, ...$args) + * @method static int lastId() + */ final class DB { private static $instance; diff --git a/src/Emoticon.php b/src/Emoticon.php index 611f5290..fa6bdda2 100644 --- a/src/Emoticon.php +++ b/src/Emoticon.php @@ -1,7 +1,14 @@ feedItems) > 0; } public function addItem(FeedItem $item): self { - if($item === null) - throw new InvalidArgumentException('item may not be null'); $this->feedItems[] = $item; return $this; } diff --git a/src/Forum/forum.php b/src/Forum/forum.php index 04e5296d..6dbdf88a 100644 --- a/src/Forum/forum.php +++ b/src/Forum/forum.php @@ -238,9 +238,8 @@ function forum_get_child_ids(int $forumId): array { } function forum_topics_unread(int $forumId, int $userId): int { - if($userId < 1 || $forumId < 1) { - return false; - } + if($userId < 1 || $forumId < 1) + return 0; static $memoized = []; $memoId = "{$forumId}-{$userId}"; diff --git a/src/Forum/post.php b/src/Forum/post.php index c569eb50..8fc36756 100644 --- a/src/Forum/post.php +++ b/src/Forum/post.php @@ -308,7 +308,7 @@ function forum_post_can_delete($postId, ?int $userId = null): int { return MSZ_E_FORUM_POST_DELETE_OWNER; } - if(strtotime($post['post_created']) <= time() - MSZ_FORUM_POST_DELETE_LIMIT) { + if(strtotime($post['post_created']) <= (time() - MSZ_FORUM_POST_DELETE_LIMIT)) { return MSZ_E_FORUM_POST_DELETE_OLD; } } diff --git a/src/Forum/topic.php b/src/Forum/topic.php index 6dd5c42d..bfc83255 100644 --- a/src/Forum/topic.php +++ b/src/Forum/topic.php @@ -575,7 +575,7 @@ function forum_topic_can_delete($topicId, ?int $userId = null): int { return MSZ_E_FORUM_TOPIC_DELETE_OWNER; } - if(strtotime($topic['topic_created']) <= time() - MSZ_FORUM_TOPIC_DELETE_TIME_LIMIT) { + if(strtotime($topic['topic_created']) <= (time() - MSZ_FORUM_TOPIC_DELETE_TIME_LIMIT)) { return MSZ_E_FORUM_TOPIC_DELETE_OLD; } diff --git a/src/Http/Handlers/ChangelogHandler.php b/src/Http/Handlers/ChangelogHandler.php index 44b1e5bc..c4a90c63 100644 --- a/src/Http/Handlers/ChangelogHandler.php +++ b/src/Http/Handlers/ChangelogHandler.php @@ -26,7 +26,7 @@ class ChangelogHandler extends Handler { if($filterDate !== null) try { $dateParts = explode('-', $filterDate, 3); - $filterDate = gmmktime(12, 0, 0, $dateParts[1], $dateParts[2], $dateParts[0]); + $filterDate = gmmktime(12, 0, 0, intval($dateParts[1]), intval($dateParts[2]), intval($dateParts[0])); } catch(ErrorException $ex) { return 404; } diff --git a/src/Http/Handlers/ForumHandler.php b/src/Http/Handlers/ForumHandler.php index 9afb40b1..49f6ac2f 100644 --- a/src/Http/Handlers/ForumHandler.php +++ b/src/Http/Handlers/ForumHandler.php @@ -11,7 +11,7 @@ final class ForumHandler extends Handler { $forumId = (int)$request->getQueryParam('forum', FILTER_SANITIZE_NUMBER_INT); $response->setTemplate('confirm', [ 'title' => 'Mark forum as read', - 'message' => 'Are you sure you want to mark ' . ($forumId === null ? 'the entire' : 'this') . ' forum as read?', + 'message' => 'Are you sure you want to mark ' . ($forumId === 0 ? 'the entire' : 'this') . ' forum as read?', 'return' => url($forumId ? 'forum-category' : 'forum-index', ['forum' => $forumId]), 'params' => [ 'forum' => $forumId, diff --git a/src/Http/Handlers/InfoHandler.php b/src/Http/Handlers/InfoHandler.php index 84f02c40..bd3efacb 100644 --- a/src/Http/Handlers/InfoHandler.php +++ b/src/Http/Handlers/InfoHandler.php @@ -20,7 +20,7 @@ final class InfoHandler extends Handler { 'title' => '', ]; - $isMisuzuDoc = $name === 'misuzu' || starts_with($name, 'misuzu/'); + $isMisuzuDoc = $name === 'misuzu' || str_starts_with($name, 'misuzu/'); if($isMisuzuDoc) { $filename = substr($name, 7); @@ -41,8 +41,8 @@ final class InfoHandler extends Handler { if(empty($document['content'])) return 404; - if(empty($document['title'])) { - if(starts_with($document['content'], '# ')) { + if($document['title'] === '') { + if(str_starts_with($document['content'], '# ')) { $titleOffset = strpos($document['content'], "\n"); $document['title'] = trim(substr($document['content'], 2, $titleOffset - 1)); $document['content'] = substr($document['content'], $titleOffset); diff --git a/src/Http/Handlers/NewsHandler.php b/src/Http/Handlers/NewsHandler.php index 9c90acfa..728ce720 100644 --- a/src/Http/Handlers/NewsHandler.php +++ b/src/Http/Handlers/NewsHandler.php @@ -13,7 +13,7 @@ use Misuzu\Feeds\RssFeedSerializer; use Misuzu\News\NewsCategory; use Misuzu\News\NewsPost; use Misuzu\News\NewsCategoryNotFoundException; -use Misuzu\News\NewsPostNotException; +use Misuzu\News\NewsPostNotFoundException; use Misuzu\Parsers\Parser; use Misuzu\Users\User; diff --git a/src/Http/Handlers/SockChatHandler.php b/src/Http/Handlers/SockChatHandler.php index c8769e43..6a2a3822 100644 --- a/src/Http/Handlers/SockChatHandler.php +++ b/src/Http/Handlers/SockChatHandler.php @@ -67,12 +67,14 @@ final class SockChatHandler extends Handler { $body = $request->getParsedBody(); - if(isset($body['bump'], $body['hash']) && is_string($body['bump']) && is_string($body['hash'])) - return $this->bump( + if(isset($body['bump'], $body['hash']) && is_string($body['bump']) && is_string($body['hash'])) { + $this->bump( $response, $request->setHeader('X-SharpChat-Signature', $body['hash']) ->setBody(Stream::create($body['bump'])) ); + return; + } $source = isset($body['user_id']) ? $body : $query; @@ -381,9 +383,10 @@ final class SockChatHandler extends Handler { $userInfo = User::byUsername($param); break; } - } catch(UserNotFoundException $ex) { + } catch(UserNotFoundException $ex) {} + + if(!isset($userInfo)) return []; - } return [ 'user_id' => $userInfo->getId(), diff --git a/src/Http/Headers/AcceptHttpHeader.php b/src/Http/Headers/AcceptHttpHeader.php index 62009cb7..269895aa 100644 --- a/src/Http/Headers/AcceptHttpHeader.php +++ b/src/Http/Headers/AcceptHttpHeader.php @@ -16,7 +16,7 @@ class AcceptHttpHeaderChild implements HasQualityInterface { if(isset($parts[1])) { $split = explode('=', $parts[1], 2); if($split[0] === 'q' && isset($split[1])) - $this->quality = max(min(round(filter_var($split[1], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) ?? 1, 2), 1), 0); + $this->quality = max(min(round((float)filter_var($split[1], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION), 2), 1), 0); } } diff --git a/src/Http/Headers/HttpHeader.php b/src/Http/Headers/HttpHeader.php index e64a8125..ce86f44a 100644 --- a/src/Http/Headers/HttpHeader.php +++ b/src/Http/Headers/HttpHeader.php @@ -52,7 +52,7 @@ class HttpHeader { case 'TE': return new AcceptHttpHeader($name, $line); default: - return new static($name, $line); + return new HttpHeader($name, $line); } } } diff --git a/src/Http/HttpRequestMessage.php b/src/Http/HttpRequestMessage.php index 637f491c..74240573 100644 --- a/src/Http/HttpRequestMessage.php +++ b/src/Http/HttpRequestMessage.php @@ -190,7 +190,7 @@ class HttpRequestMessage extends HttpMessage { } } - if(!isset($headers['Authorization'])) { + if(empty($headers['Authorization'])) { if(isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) { $headers['Authorization'] = $_SERVER['REDIRECT_HTTP_AUTHORIZATION']; } elseif(isset($_SERVER['PHP_AUTH_USER'])) { diff --git a/src/Http/HttpResponseMessage.php b/src/Http/HttpResponseMessage.php index e6eefddb..77286c33 100644 --- a/src/Http/HttpResponseMessage.php +++ b/src/Http/HttpResponseMessage.php @@ -131,7 +131,6 @@ class HttpResponseMessage extends HttpMessage { 414 => 'URI Too Long', 416 => 'Range Not Satisfiable', 417 => 'Expectation Failed', - 417 => 'Expectation Failed', 418 => 'I\'m a teapot', 421 => 'Misdirected Request', 422 => 'Unprocessable Entity', diff --git a/src/Http/Routing/Route.php b/src/Http/Routing/Route.php index 917d7b8d..affe4a39 100644 --- a/src/Http/Routing/Route.php +++ b/src/Http/Routing/Route.php @@ -23,7 +23,7 @@ class Route { } public static function create(array $methods, string $path, ?string $method = null, ?string $class = null): self { - return new static($methods, $path, $method, $class); + return new Route($methods, $path, $method, $class); } public static function get(string $path, ?string $method = null, ?string $class = null): self { return self::create(['GET'], $path, $method, $class); diff --git a/src/Http/Routing/Router.php b/src/Http/Routing/Router.php index 5bfec620..176d0b7e 100644 --- a/src/Http/Routing/Router.php +++ b/src/Http/Routing/Router.php @@ -21,7 +21,7 @@ class Router { if($name[0] === '_') return null; if(self::$instance === null) - (new static)->setInstance(); + (new Router)->setInstance(); return self::$instance->{'_' . $name}(...$args); } @@ -92,7 +92,7 @@ class Router { $handlerMethod = $route->getHandlerMethod(); if(is_callable($handlerMethod)) { - $result = call_user_func_array($handlerMethod, $args); + $result = call_user_func_array($handlerMethod, $matches); } elseif($handlerMethod[0] === '/') { $response->redirect($handlerMethod); } else { diff --git a/src/Http/UploadedFile.php b/src/Http/UploadedFile.php index eeba719b..74d4fa10 100644 --- a/src/Http/UploadedFile.php +++ b/src/Http/UploadedFile.php @@ -38,7 +38,7 @@ class UploadedFile { $this->stream = $fileNameOrStream; if($size === null && $this->stream !== null) - $this->size = $stream->getSize(); + $this->size = $this->stream->getSize(); } } @@ -47,7 +47,7 @@ class UploadedFile { throw new RuntimeException('Can\'t open stream because of an upload error.'); if($this->hasMoved) throw new RuntimeException('Can\'t open stream because file has already been moved.'); - if($this->steam === null) + if($this->stream === null) $this->stream = Stream::createFromFile($this->fileName); return $this->stream; @@ -97,7 +97,7 @@ class UploadedFile { } public static function createFromFILE(array $file): self { - return new static( + return new UploadedFile( $file['tmp_name'] ?? '', $file['error'] ?? UPLOAD_ERR_NO_FILE, $file['size'] ?? null, diff --git a/src/Imaging/GdImage.php b/src/Imaging/GdImage.php index c3544cc3..255d4992 100644 --- a/src/Imaging/GdImage.php +++ b/src/Imaging/GdImage.php @@ -26,7 +26,7 @@ final class GdImage extends Image { ]; public function __construct($pathOrWidth, int $height = -1) { - parent::__construct($pathOrWidth, $height); + parent::__construct($pathOrWidth); if(is_int($pathOrWidth)) { $this->gd = imagecreatetruecolor($pathOrWidth, $height < 1 ? $pathOrWidth : $height); diff --git a/src/Imaging/Image.php b/src/Imaging/Image.php index 015a299a..c7c531c7 100644 --- a/src/Imaging/Image.php +++ b/src/Imaging/Image.php @@ -5,7 +5,7 @@ use InvalidArgumentException; use UnexpectedValueException; abstract class Image { - public function __construct($pathOrWidth, int $height = -1) { + public function __construct($pathOrWidth) { if(!is_int($pathOrWidth) && !is_string($pathOrWidth)) throw new InvalidArgumentException('The first argument must be or type string to open an image file, or int to set a width for a new image.'); } diff --git a/src/Imaging/ImagickImage.php b/src/Imaging/ImagickImage.php index a6c8c71f..4fd59502 100644 --- a/src/Imaging/ImagickImage.php +++ b/src/Imaging/ImagickImage.php @@ -8,12 +8,12 @@ final class ImagickImage extends Image { private ?Imagick $imagick = null; public function __construct($pathOrWidth, int $height = -1) { - parent::__construct($pathOrWidth, $height); + parent::__construct($pathOrWidth); if(is_int($pathOrWidth)) { $this->imagick = new Imagick(); - $this->newImage($pathOrWidth, $height < 1 ? $pathOrWidth : $height, 'none'); - $this->setImageFormat('png'); + $this->imagick->newImage($pathOrWidth, $height < 1 ? $pathOrWidth : $height, 'none'); + $this->imagick->setImageFormat('png'); } elseif(is_string($pathOrWidth)) { $imagick = new Imagick($pathOrWidth); $imagick->setImageFormat($imagick->getNumberImages() > 1 ? 'gif' : 'png'); diff --git a/src/Mailer.php b/src/Mailer.php index 1e7d90be..366dde7f 100644 --- a/src/Mailer.php +++ b/src/Mailer.php @@ -14,6 +14,9 @@ final class Mailer { private static $dsn = 'null://null'; private static $transport = null; + private static string $senderName = 'Flashii'; + private static string $senderAddr = 'sys@flashii.net'; + public static function init(string $method, array $config): void { if($method !== 'smtp') { self::$dsn = 'null://null'; @@ -42,6 +45,12 @@ final class Mailer { $dsn .= $config['port'] ?? 25; self::$dsn = $dsn; + + if(!empty($config['sender_name'])) + self::$senderName = $config['sender_name']; + + if(!empty($config['sender_addr'])) + self::$senderAddr = $config['sender_addr']; } public static function getTransport() { @@ -59,8 +68,8 @@ final class Mailer { $message = new SymfonyMessage; $message->from(new SymfonyAddress( - $config['sender_addr'] ?? 'sys@flashii.net', - $config['sender_name'] ?? 'Flashii' + self::$senderAddr, + self::$senderName )); if($bcc) diff --git a/src/MediaType.php b/src/MediaType.php index 10282ac9..f3a71f1e 100644 --- a/src/MediaType.php +++ b/src/MediaType.php @@ -68,7 +68,7 @@ class MediaType implements HasQualityInterface { } public function matchPattern(string $pattern): bool { try { - $mediaType = new static($pattern); + $mediaType = new MediaType($pattern); } catch(InvalidArgumentException $ex) { return false; } diff --git a/src/Pagination.php b/src/Pagination.php index 213d44a4..7f77a157 100644 --- a/src/Pagination.php +++ b/src/Pagination.php @@ -27,7 +27,7 @@ final class Pagination { } public function getPages(): int { - return ceil($this->getCount() / $this->getRange()); + return (int)ceil($this->getCount() / $this->getRange()); } public function hasValidOffset(): bool { @@ -50,7 +50,7 @@ final class Pagination { if($this->getOffset() < 1) return self::START_PAGE; - return floor($this->getOffset() / $this->getRange()) + self::START_PAGE; + return (int)floor($this->getOffset() / $this->getRange()) + self::START_PAGE; } public function setPage(int $page, bool $zeroBased = false): self { @@ -70,7 +70,7 @@ final class Pagination { $source ??= $_GET; if(isset($source[$name]) && is_string($source[$name]) && ctype_digit($source[$name])) - return $source[$name]; + return intval($source[$name]); return $default; } diff --git a/src/Stream.php b/src/Stream.php index 3034e2d5..d1d92d7b 100644 --- a/src/Stream.php +++ b/src/Stream.php @@ -47,7 +47,7 @@ class Stream { if($contents instanceof Stream) return $contents; - return new static($contents); + return new Stream($contents); } public static function createFromFile(string $filename, string $mode = 'rb'): Stream { if(!in_array($mode[0], ['r', 'w', 'a', 'x', 'c'])) @@ -79,9 +79,9 @@ class Stream { return $this->readable; } - public function read($length): int { + public function read($length): string { if(!$this->isReadable()) - throw RuntimeException('Can\'t read from this stream.'); + throw new RuntimeException('Can\'t read from this stream.'); return fread($this->stream, $length); } diff --git a/src/TOTP.php b/src/TOTP.php index 8ee4b26a..ccf9fef8 100644 --- a/src/TOTP.php +++ b/src/TOTP.php @@ -32,6 +32,6 @@ class TOTP { $bin |= (ord($hash[$offset + 3]) & 0xFF); $otp = $bin % pow(10, self::DIGITS); - return str_pad($otp, self::DIGITS, STR_PAD_LEFT); + return str_pad(strval($otp), self::DIGITS, '0', STR_PAD_LEFT); } } diff --git a/src/Template.php b/src/Template.php index b4ac4a43..01a6a592 100644 --- a/src/Template.php +++ b/src/Template.php @@ -34,7 +34,7 @@ final class Template { define('MSZ_TPL_RENDER', microtime(true)); } - if(!ends_with($file, self::FILE_EXT)) { + if(!str_ends_with($file, self::FILE_EXT)) { $file = str_replace('.', DIRECTORY_SEPARATOR, $file) . self::FILE_EXT; } diff --git a/src/Users/Assets/UserAvatarAsset.php b/src/Users/Assets/UserAvatarAsset.php index d9c59d53..bfafba26 100644 --- a/src/Users/Assets/UserAvatarAsset.php +++ b/src/Users/Assets/UserAvatarAsset.php @@ -57,7 +57,7 @@ class UserAvatarAsset extends UserImageAsset implements UserAssetScalableInterfa } public function getScaledFileExtension(int $dims): string { $imageSize = getimagesize($this->getScaledPath($dims)); - if($imageSize === null) + if($imageSize === false) return 'img'; return self::TYPES_EXT[$imageSize[2]] ?? 'img'; } diff --git a/src/Users/Assets/UserBackgroundAsset.php b/src/Users/Assets/UserBackgroundAsset.php index f44a0114..991ec864 100644 --- a/src/Users/Assets/UserBackgroundAsset.php +++ b/src/Users/Assets/UserBackgroundAsset.php @@ -94,7 +94,7 @@ class UserBackgroundAsset extends UserImageAsset { return $this; } public function isBlend(): bool { - return $this->getAttributes() & self::ATTRIB_BLEND; + return ($this->getAttributes() & self::ATTRIB_BLEND) > 0; } public function setBlend(bool $blend): self { $this->getUser()->setBackgroundSettings( @@ -105,7 +105,7 @@ class UserBackgroundAsset extends UserImageAsset { return $this; } public function isSlide(): bool { - return $this->getAttributes() & self::ATTRIB_SLIDE; + return ($this->getAttributes() & self::ATTRIB_SLIDE) > 0; } public function setSlide(bool $slide): self { $this->getUser()->setBackgroundSettings( diff --git a/src/Users/Assets/UserImageAsset.php b/src/Users/Assets/UserImageAsset.php index 1151e583..8912600c 100644 --- a/src/Users/Assets/UserImageAsset.php +++ b/src/Users/Assets/UserImageAsset.php @@ -120,7 +120,7 @@ abstract class UserImageAsset implements JsonSerializable, UserImageAssetInterfa public function setFromData(string $data): void { $file = tempnam(sys_get_temp_dir(), 'msz'); - if($file === null || !is_file($file)) + if($file === false || !is_file($file)) throw new UserImageAssetFileCreationFailedException; chmod($file, 0664); file_put_contents($file, $data); diff --git a/src/Users/User.php b/src/Users/User.php index 72d3afee..43f784b3 100644 --- a/src/Users/User.php +++ b/src/Users/User.php @@ -790,7 +790,7 @@ class User implements HasRankInterface, JsonSerializable { ************/ private static function countQueryBase(): string { - return sprintf(self::QUERY_SELECT, sprintf('COUNT(*)', self::TABLE)); + return sprintf(self::QUERY_SELECT, 'COUNT(*)'); } public static function countAll(bool $showDeleted = false): int { return (int)DB::prepare( diff --git a/src/Users/UserLoginAttempt.php b/src/Users/UserLoginAttempt.php index c3f52e3b..1d4b897e 100644 --- a/src/Users/UserLoginAttempt.php +++ b/src/Users/UserLoginAttempt.php @@ -93,7 +93,7 @@ class UserLoginAttempt { } private static function countQueryBase(): string { - return sprintf(self::QUERY_SELECT, sprintf('COUNT(*)', self::TABLE)); + return sprintf(self::QUERY_SELECT, 'COUNT(*)'); } public static function countAll(?User $user = null): int { $getCount = DB::prepare( diff --git a/src/Users/UserRole.php b/src/Users/UserRole.php index c412efe6..d0aeac9f 100644 --- a/src/Users/UserRole.php +++ b/src/Users/UserRole.php @@ -83,7 +83,7 @@ class UserRole implements ArrayAccess, HasRankInterface { public function getCanLeave(): bool { return boolval($this->role_can_leave); } - public function setCanLeave(bool $canLeave): bool { + public function setCanLeave(bool $canLeave): self { $this->role_can_leave = $canLeave ? 1 : 0; return $this; } @@ -159,7 +159,7 @@ class UserRole implements ArrayAccess, HasRankInterface { } private static function countQueryBase(): string { - return sprintf(self::QUERY_SELECT, sprintf('COUNT(*)', self::TABLE)); + return sprintf(self::QUERY_SELECT, 'COUNT(*)'); } public static function countAll(bool $showHidden = false): int { return (int)DB::prepare( diff --git a/src/Users/UserRoleRelation.php b/src/Users/UserRoleRelation.php index 0fc682d8..0946d97b 100644 --- a/src/Users/UserRoleRelation.php +++ b/src/Users/UserRoleRelation.php @@ -60,7 +60,7 @@ class UserRoleRelation { ->execute(); // data is predictable, just create a "fake" - $object = new static; + $object = new UserRoleRelation; $object->user = $user; $object->user_id = $user->getId(); $object->role = $role; @@ -69,7 +69,7 @@ class UserRoleRelation { } private static function countQueryBase(): string { - return sprintf(self::QUERY_SELECT, sprintf('COUNT(*)', self::TABLE)); + return sprintf(self::QUERY_SELECT, 'COUNT(*)'); } public static function countUsers(UserRole $role): int { return (int)DB::prepare(self::countQueryBase() . ' WHERE `role_id` = :role') diff --git a/src/Users/UserSession.php b/src/Users/UserSession.php index 9e5f56c0..f6416f4a 100644 --- a/src/Users/UserSession.php +++ b/src/Users/UserSession.php @@ -199,7 +199,7 @@ class UserSession { } private static function countQueryBase(): string { - return sprintf(self::QUERY_SELECT, sprintf('COUNT(*)', self::TABLE)); + return sprintf(self::QUERY_SELECT, 'COUNT(*)'); } public static function countAll(?User $user = null): int { $getCount = DB::prepare( diff --git a/src/Users/UserWarning.php b/src/Users/UserWarning.php index 143dd207..95836cc1 100644 --- a/src/Users/UserWarning.php +++ b/src/Users/UserWarning.php @@ -197,7 +197,7 @@ class UserWarning { } private static function countQueryBase(): string { - return sprintf(self::QUERY_SELECT, sprintf('COUNT(*)', self::TABLE)); + return sprintf(self::QUERY_SELECT, 'COUNT(*)'); } public static function countByRemoteAddress(?string $address = null, bool $withDuration = true): int { $address = $address ?? IPAddress::remote(); diff --git a/src/Zalgo.php b/src/Zalgo.php index 080f6097..784ba56e 100644 --- a/src/Zalgo.php +++ b/src/Zalgo.php @@ -86,6 +86,7 @@ final class Zalgo { continue; $str .= $char; + $num_up = $num_mid = $num_down = 0; switch($mode) { case self::MODE_MINI: diff --git a/src/perms.php b/src/perms.php index 361e851f..875a2c6b 100644 --- a/src/perms.php +++ b/src/perms.php @@ -74,17 +74,15 @@ function perms_get_key(string $prefix, string $suffix): string { function perms_get_select(array $modes = MSZ_PERM_MODES, string $allow = MSZ_PERMS_ALLOW, string $deny = MSZ_PERMS_DENY): string { $select = ''; - if(empty($select)) { - foreach($modes as $mode) { - $select .= sprintf( - '(BIT_OR(`%1$s_perms_%2$s`) &~ BIT_OR(`%1$s_perms_%3$s`)) AS `%1$s`,', - $mode, $allow, $deny - ); - } - - $select = substr($select, 0, -1); + foreach($modes as $mode) { + $select .= sprintf( + '(BIT_OR(`%1$s_perms_%2$s`) &~ BIT_OR(`%1$s_perms_%3$s`)) AS `%1$s`,', + $mode, $allow, $deny + ); } + $select = substr($select, 0, -1); + return $select; } diff --git a/src/url.php b/src/url.php index 8dca95d2..44be4a1d 100644 --- a/src/url.php +++ b/src/url.php @@ -132,7 +132,7 @@ function url(string $name, array $variables = []): string { $info = MSZ_URLS[$name]; - if(!is_string($info[0] ?? null)) { + if(!isset($info[0]) || !is_string($info[0])) { return ''; } @@ -175,13 +175,13 @@ function url_redirect(string $name, array $variables = []): void { } function url_variable(string $value, array $variables): string { - if(starts_with($value, '<') && ends_with($value, '>')) + if(str_starts_with($value, '<') && str_ends_with($value, '>')) return $variables[trim($value, '<>')] ?? ''; - if(starts_with($value, '[') && ends_with($value, ']')) + if(str_starts_with($value, '[') && str_ends_with($value, ']')) return constant(trim($value, '[]')); - if(starts_with($value, '{') && ends_with($value, '}')) + if(str_starts_with($value, '{') && str_ends_with($value, '}')) return \Misuzu\CSRF::token(); // Hack that allows variables with file extensions @@ -201,7 +201,7 @@ function url_list(): array { $collection = []; foreach(MSZ_URLS as $name => $urlInfo) { - if(empty($hasManageAccess) && starts_with($name, 'manage-')) + if(empty($hasManageAccess) && str_starts_with($name, 'manage-')) continue; $item = [ @@ -271,5 +271,5 @@ function is_local_url(string $url): bool { if($url[0] === '/' && ($length > 1 ? $url[1] !== '/' : true)) return true; - return starts_with($url, url_prefix()); + return str_starts_with($url, url_prefix()); } diff --git a/utility.php b/utility.php index f242cda5..d46d7873 100644 --- a/utility.php +++ b/utility.php @@ -33,16 +33,12 @@ function clamp($num, int $min, int $max): int { return max($min, min($max, intval($num))); } -function starts_with(string $string, string $text, bool $multibyte = true): bool { - $strlen = $multibyte ? 'mb_strlen' : 'strlen'; - $substr = $multibyte ? 'mb_substr' : 'substr'; - return $substr($string, 0, $strlen($text)) === $text; +function starts_with(string $string, string $text): bool { + return str_starts_with($string, $text); } -function ends_with(string $string, string $text, bool $multibyte = true): bool { - $strlen = $multibyte ? 'mb_strlen' : 'strlen'; - $substr = $multibyte ? 'mb_substr' : 'substr'; - return $substr($string, 0 - $strlen($text)) === $text; +function ends_with(string $string, string $text): bool { + return str_ends_with($string, $text); } function first_paragraph(string $text, string $delimiter = "\n"): string {