From e6c826a7d76229f2a0082ae46f114ca0ae300bdb Mon Sep 17 00:00:00 2001 From: flashwave Date: Tue, 18 Jul 2023 22:24:23 +0000 Subject: [PATCH] Fixed various errors and oversights caught by phpstan. --- src/AuditLog/AuditLog.php | 10 +++--- src/AuthToken.php | 4 +-- src/Changelog/Changelog.php | 8 ++--- src/Comments/Comments.php | 16 ++++----- src/Config/DbConfig.php | 12 ------- src/Config/DbConfigValueInfo.php | 1 + src/Config/ScopedConfig.php | 4 +-- src/Feeds/AtomFeedSerializer.php | 34 +++++++++++--------- src/Feeds/RssFeedSerializer.php | 37 +++++++++++---------- src/Feeds/XmlFeedSerializer.php | 36 ++++++++++----------- src/Forum/topic.php | 2 +- src/Http/Handlers/AssetsHandler.php | 2 +- src/Imaging/Image.php | 4 +-- src/Mailer.php | 23 +++---------- src/MisuzuContext.php | 7 ---- src/News/News.php | 8 ++--- src/SharpChat/SharpChatRoutes.php | 50 ++++++++++++++++------------- src/Users/Assets/UserImageAsset.php | 2 +- src/Users/ProfileField.php | 6 ++++ src/Users/User.php | 7 +++- src/Users/UserRole.php | 1 - src/Users/Users.php | 43 ------------------------- src/manage.php | 1 + 23 files changed, 130 insertions(+), 188 deletions(-) delete mode 100644 src/Users/Users.php diff --git a/src/AuditLog/AuditLog.php b/src/AuditLog/AuditLog.php index f155165..91df2f8 100644 --- a/src/AuditLog/AuditLog.php +++ b/src/AuditLog/AuditLog.php @@ -11,11 +11,9 @@ use Misuzu\Pagination; use Misuzu\Users\User; class AuditLog { - private IDbConnection $dbConn; private DbStatementCache $cache; public function __construct(IDbConnection $dbConn) { - $this->dbConn = $dbConn; $this->cache = new DbStatementCache($dbConn); } @@ -34,8 +32,8 @@ class AuditLog { $args = 0; $query = 'SELECT COUNT(*) FROM msz_audit_log'; if($hasUserInfo) { - $query .= (++$args > 1 ? ' AND' : ' WHERE'); - $query .= ' user_id = ?'; + ++$args; + $query .= ' WHERE user_id = ?'; } if($hasRemoteAddr) { $query .= (++$args > 1 ? ' AND' : ' WHERE'); @@ -77,8 +75,8 @@ class AuditLog { $args = 0; $query = 'SELECT user_id, log_action, log_params, UNIX_TIMESTAMP(log_created), INET6_NTOA(log_ip), log_country FROM msz_audit_log'; if($hasUserInfo) { - $query .= (++$args > 1 ? ' AND' : ' WHERE'); - $query .= ' user_id = ?'; + ++$args; + $query .= ' WHERE user_id = ?'; } if($hasRemoteAddr) { $query .= (++$args > 1 ? ' AND' : ' WHERE'); diff --git a/src/AuthToken.php b/src/AuthToken.php index f51f17f..138f64a 100644 --- a/src/AuthToken.php +++ b/src/AuthToken.php @@ -131,8 +131,8 @@ class AuthToken { if(!hash_equals($realHash, $userHash)) return $obj; - extract(unpack('Ntimestamp', $timestamp)); - $obj->timestamp = $timestamp; + $unpacked = unpack('Nts', $timestamp); + $obj->timestamp = (int)$unpacked['ts']; $stream = MemoryStream::fromString($data); $stream->seek(0); diff --git a/src/Changelog/Changelog.php b/src/Changelog/Changelog.php index c5eee52..ad6965c 100644 --- a/src/Changelog/Changelog.php +++ b/src/Changelog/Changelog.php @@ -111,8 +111,8 @@ class Changelog { $query = 'SELECT COUNT(*) FROM msz_changelog_changes'; if($hasUserInfo) { - $query .= (++$args > 1 ? ' AND' : ' WHERE'); - $query .= ' user_id = ?'; + ++$args; + $query .= ' WHERE user_id = ?'; } if($hasDateTime) { $query .= (++$args > 1 ? ' AND' : ' WHERE'); @@ -166,8 +166,8 @@ class Changelog { $query = 'SELECT change_id, user_id, change_action, UNIX_TIMESTAMP(change_created), change_log, change_text FROM msz_changelog_changes'; if($hasUserInfo) { - $query .= (++$args > 1 ? ' AND' : ' WHERE'); - $query .= ' user_id = ?'; + ++$args; + $query .= ' WHERE user_id = ?'; } if($hasDateTime) { $query .= (++$args > 1 ? ' AND' : ' WHERE'); diff --git a/src/Comments/Comments.php b/src/Comments/Comments.php index 66013c8..bb85365 100644 --- a/src/Comments/Comments.php +++ b/src/Comments/Comments.php @@ -231,12 +231,12 @@ class Comments { $query = 'SELECT COUNT(*) FROM msz_comments_posts'; if($hasParent) { - $query .= (++$args > 1 ? ' AND' : ' WHERE'); - $query .= ' comment_reply_to = ?'; + ++$args; + $query .= ' WHERE comment_reply_to = ?'; } else { if($hasCategory) { - $query .= (++$args > 1 ? ' AND' : ' WHERE'); - $query .= ' category_id = ?'; + ++$args; + $query .= ' WHERE category_id = ?'; } if(!$includeReplies) { @@ -295,12 +295,12 @@ class Comments { $query .= ' FROM msz_comments_posts AS cpp'; if($hasParent) { - $query .= (++$args > 1 ? ' AND' : ' WHERE'); - $query .= ' comment_reply_to = ?'; + ++$args; + $query .= ' WHERE comment_reply_to = ?'; } else { if($hasCategory) { - $query .= (++$args > 1 ? ' AND' : ' WHERE'); - $query .= ' category_id = ?'; + ++$args; + $query .= ' WHERE category_id = ?'; } if(!$includeReplies) { diff --git a/src/Config/DbConfig.php b/src/Config/DbConfig.php index 40d228e..d312218 100644 --- a/src/Config/DbConfig.php +++ b/src/Config/DbConfig.php @@ -11,12 +11,10 @@ use Misuzu\DbStatementCache; use Misuzu\Pagination; class DbConfig implements IConfig { - private IDbConnection $dbConn; private DbStatementCache $cache; private array $values = []; public function __construct(IDbConnection $dbConn) { - $this->dbConn = $dbConn; $this->cache = new DbStatementCache($dbConn); } @@ -265,16 +263,6 @@ class DbConfig implements IConfig { return $valueInfo?->isArray() ? $valueInfo->getArray() : $default; } - private function setValue(string $name, $value): void { - $this->values[$name] = $value; - $value = serialize($value); - - $stmt = $this->cache->get('REPLACE INTO msz_config (config_name, config_value) VALUES (?, ?)'); - $stmt->addParameter(1, $name); - $stmt->addParameter(2, $value); - $stmt->execute(); - } - public function setValues(array $values): void { if(empty($values)) return; diff --git a/src/Config/DbConfigValueInfo.php b/src/Config/DbConfigValueInfo.php index 16ec885..f8941c6 100644 --- a/src/Config/DbConfigValueInfo.php +++ b/src/Config/DbConfigValueInfo.php @@ -24,6 +24,7 @@ class DbConfigValueInfo implements IConfigValueInfo { 'i' => 'int', 'b' => 'bool', 'd' => 'float', + default => 'unknown', }; } diff --git a/src/Config/ScopedConfig.php b/src/Config/ScopedConfig.php index 06ea5d9..f8fbc9d 100644 --- a/src/Config/ScopedConfig.php +++ b/src/Config/ScopedConfig.php @@ -24,7 +24,7 @@ class ScopedConfig implements IConfig { private function prefixNames(string|array $names): array { if(is_string($names)) - return [$this->prefix . $name]; + return [$this->prefix . $names]; foreach($names as $key => $name) $names[$key] = $this->prefix . $name; @@ -41,7 +41,7 @@ class ScopedConfig implements IConfig { } public function hasValues(string|array $names): bool { - $this->config->hasValues($this->prefixNames($names)); + return $this->config->hasValues($this->prefixNames($names)); } public function removeValues(string|array $names): void { diff --git a/src/Feeds/AtomFeedSerializer.php b/src/Feeds/AtomFeedSerializer.php index 486017a..2905293 100644 --- a/src/Feeds/AtomFeedSerializer.php +++ b/src/Feeds/AtomFeedSerializer.php @@ -3,15 +3,17 @@ namespace Misuzu\Feeds; use DOMDocument; use DOMElement; +use DOMNode; class AtomFeedSerializer extends XmlFeedSerializer { protected function formatTime(int $time): string { return date('c', $time); } - protected function createRoot(DOMDocument $document, Feed $feed): DOMElement { + protected function createRoot(DOMDocument $document, Feed $feed): DOMNode { $atom = $document->appendChild($document->createElement('feed')); - $atom->setAttribute('xmlns', 'http://www.w3.org/2005/Atom'); + if($atom instanceof DOMElement) + $atom->setAttribute('xmlns', 'http://www.w3.org/2005/Atom'); $atom->appendChild( $document->createElement( @@ -25,32 +27,32 @@ class AtomFeedSerializer extends XmlFeedSerializer { return $atom; } - protected function createTitle(DOMDocument $document, string $title): DOMElement { + protected function createTitle(DOMDocument $document, string $title): DOMNode { return $document->createElement('title', $this->cleanString($title)); } - protected function createDescription(DOMDocument $document, string $description): ?DOMElement { + protected function createDescription(DOMDocument $document, string $description): ?DOMNode { return $document->createElement('subtitle', $this->cleanString($description)); } - protected function createLastUpdate(DOMDocument $document, int $lastUpdate): ?DOMElement { + protected function createLastUpdate(DOMDocument $document, int $lastUpdate): ?DOMNode { return $document->createElement('updated', $this->formatTime($lastUpdate)); } - protected function createContentUrl(DOMDocument $document, string $contentUrl): ?DOMElement { + protected function createContentUrl(DOMDocument $document, string $contentUrl): ?DOMNode { $link = $document->createElement('link'); $link->setAttribute('href', $this->cleanString($contentUrl)); return $link; } - protected function createFeedUrl(DOMDocument $document, string $feedUrl): ?DOMElement { + protected function createFeedUrl(DOMDocument $document, string $feedUrl): ?DOMNode { $link = $document->createElement('link'); $link->setAttribute('href', $this->cleanString($feedUrl)); $link->setAttribute('ref', 'self'); return $link; } - protected function createItem(DOMDocument $document, FeedItem $feedItem): DOMElement { + protected function createItem(DOMDocument $document, FeedItem $feedItem): DOMNode { $elem = $document->createElement('entry'); $elem->appendChild( @@ -65,40 +67,40 @@ class AtomFeedSerializer extends XmlFeedSerializer { return $elem; } - protected function createItemTitle(DOMDocument $document, string $title): DOMElement { + protected function createItemTitle(DOMDocument $document, string $title): DOMNode { return $document->createElement('title', $this->cleanString($title)); } - protected function createItemSummary(DOMDocument $document, string $summary): ?DOMElement { + protected function createItemSummary(DOMDocument $document, string $summary): ?DOMNode { return $document->createElement('summary', $this->cleanString($summary)); } - protected function createItemContent(DOMDocument $document, string $content): ?DOMElement { + protected function createItemContent(DOMDocument $document, string $content): ?DOMNode { $elem = $document->createElement('content', $this->cleanString($content)); $elem->setAttribute('type', 'html'); return $elem; } - protected function createItemCreationDate(DOMDocument $document, int $creationDate): ?DOMElement { + protected function createItemCreationDate(DOMDocument $document, int $creationDate): ?DOMNode { return $document->createElement('updated', $this->formatTime($creationDate)); } - protected function createItemUniqueId(DOMDocument $document, string $uniqueId): ?DOMElement { + protected function createItemUniqueId(DOMDocument $document, string $uniqueId): ?DOMNode { return null; } - protected function createItemContentUrl(DOMDocument $document, string $contentUrl): ?DOMElement { + protected function createItemContentUrl(DOMDocument $document, string $contentUrl): ?DOMNode { $elem = $document->createElement('link'); $elem->setAttribute('href', $this->cleanString($contentUrl)); $elem->setAttribute('type', 'text/html'); return $elem; } - protected function createItemCommentsUrl(DOMDocument $document, string $commentsUrl): ?DOMElement { + protected function createItemCommentsUrl(DOMDocument $document, string $commentsUrl): ?DOMNode { return null; } - protected function createItemAuthor(DOMDocument $document, ?string $authorName, ?string $authorUrl): ?DOMElement { + protected function createItemAuthor(DOMDocument $document, ?string $authorName, ?string $authorUrl): ?DOMNode { if(empty($authorName) && empty($authorUrl)) return null; diff --git a/src/Feeds/RssFeedSerializer.php b/src/Feeds/RssFeedSerializer.php index f876cd9..f70758b 100644 --- a/src/Feeds/RssFeedSerializer.php +++ b/src/Feeds/RssFeedSerializer.php @@ -3,80 +3,83 @@ namespace Misuzu\Feeds; use DOMDocument; use DOMElement; +use DOMNode; class RssFeedSerializer extends XmlFeedSerializer { protected function formatTime(int $time): string { return date('r', $time); } - protected function createRoot(DOMDocument $document, Feed $feed): DOMElement { + protected function createRoot(DOMDocument $document, Feed $feed): DOMNode { $rss = $document->appendChild($document->createElement('rss')); - $rss->setAttribute('version', '2.0'); - $rss->setAttribute('xmlns:atom', 'http://www.w3.org/2005/Atom'); + if($rss instanceof DOMElement) { + $rss->setAttribute('version', '2.0'); + $rss->setAttribute('xmlns:atom', 'http://www.w3.org/2005/Atom'); + } $channel = $rss->appendChild($document->createElement('channel')); $channel->appendChild($document->createElement('ttl', '900')); return $channel; } - protected function createTitle(DOMDocument $document, string $title): DOMElement { + protected function createTitle(DOMDocument $document, string $title): DOMNode { return $document->createElement('title', $this->cleanString($title)); } - protected function createDescription(DOMDocument $document, string $description): ?DOMElement { + protected function createDescription(DOMDocument $document, string $description): ?DOMNode { return $document->createElement('description', $this->cleanString($description)); } - protected function createLastUpdate(DOMDocument $document, int $lastUpdate): ?DOMElement { + protected function createLastUpdate(DOMDocument $document, int $lastUpdate): ?DOMNode { return $document->createElement('pubDate', $this->formatTime($lastUpdate)); } - protected function createContentUrl(DOMDocument $document, string $contentUrl): ?DOMElement { + protected function createContentUrl(DOMDocument $document, string $contentUrl): ?DOMNode { return $document->createElement('link', $this->cleanString($contentUrl)); } - protected function createFeedUrl(DOMDocument $document, string $feedUrl): ?DOMElement { + protected function createFeedUrl(DOMDocument $document, string $feedUrl): ?DOMNode { $link = $document->createElement('atom:link'); $link->setAttribute('href', $this->cleanString($feedUrl)); $link->setAttribute('ref', 'self'); return $link; } - protected function createItem(DOMDocument $document, FeedItem $feedItem): DOMElement { + protected function createItem(DOMDocument $document, FeedItem $feedItem): DOMNode { return $document->createElement('item'); } - protected function createItemTitle(DOMDocument $document, string $title): DOMElement { + protected function createItemTitle(DOMDocument $document, string $title): DOMNode { return $document->createElement('title', $this->cleanString($title)); } - protected function createItemSummary(DOMDocument $document, string $summary): ?DOMElement { + protected function createItemSummary(DOMDocument $document, string $summary): ?DOMNode { return $document->createElement('description', $this->cleanString($summary)); } - protected function createItemContent(DOMDocument $document, string $content): ?DOMElement { + protected function createItemContent(DOMDocument $document, string $content): ?DOMNode { return null; } - protected function createItemCreationDate(DOMDocument $document, int $creationDate): ?DOMElement { + protected function createItemCreationDate(DOMDocument $document, int $creationDate): ?DOMNode { return $document->createElement('pubDate', $this->formatTime($creationDate)); } - protected function createItemUniqueId(DOMDocument $document, string $uniqueId): ?DOMElement { + protected function createItemUniqueId(DOMDocument $document, string $uniqueId): ?DOMNode { $elem = $document->createElement('guid', $uniqueId); $elem->setAttribute('isPermaLink', 'true'); return $elem; } - protected function createItemContentUrl(DOMDocument $document, string $contentUrl): ?DOMElement { + protected function createItemContentUrl(DOMDocument $document, string $contentUrl): ?DOMNode { return $document->createElement('link', $contentUrl); } - protected function createItemCommentsUrl(DOMDocument $document, string $commentsUrl): ?DOMElement { + protected function createItemCommentsUrl(DOMDocument $document, string $commentsUrl): ?DOMNode { return $document->createElement('comments', $commentsUrl); } - protected function createItemAuthor(DOMDocument $document, ?string $authorName, ?string $authorUrl): ?DOMElement { + protected function createItemAuthor(DOMDocument $document, ?string $authorName, ?string $authorUrl): ?DOMNode { return null; } } diff --git a/src/Feeds/XmlFeedSerializer.php b/src/Feeds/XmlFeedSerializer.php index 289e0b3..c7236a6 100644 --- a/src/Feeds/XmlFeedSerializer.php +++ b/src/Feeds/XmlFeedSerializer.php @@ -2,7 +2,7 @@ namespace Misuzu\Feeds; use DOMDocument; -use DOMElement; +use DOMNode; abstract class XmlFeedSerializer extends FeedSerializer { public function serializeFeed(Feed $feed): string { @@ -28,7 +28,7 @@ abstract class XmlFeedSerializer extends FeedSerializer { return $document->saveXML(); } - private function serializeFeedItem(DOMDocument $document, FeedItem $feedItem): DOMElement { + private function serializeFeedItem(DOMDocument $document, FeedItem $feedItem): DOMNode { $elem = $this->createItem($document, $feedItem); $elem->appendChild($this->createItemTitle($document, $feedItem->getTitle())); @@ -54,26 +54,26 @@ abstract class XmlFeedSerializer extends FeedSerializer { return htmlspecialchars($string, ENT_XML1 | ENT_COMPAT | ENT_SUBSTITUTE); } - protected static function appendChild(DOMElement $parent, ?DOMElement $elem): ?DOMElement { + protected static function appendChild(DOMNode $parent, ?DOMNode $elem): ?DOMNode { if($elem !== null) return $parent->appendChild($elem); return $elem; } abstract protected function formatTime(int $time): string; - abstract protected function createRoot(DOMDocument $document, Feed $feed): DOMElement; - abstract protected function createTitle(DOMDocument $document, string $title): DOMElement; - abstract protected function createDescription(DOMDocument $document, string $description): ?DOMElement; - abstract protected function createLastUpdate(DOMDocument $document, int $lastUpdate): ?DOMElement; - abstract protected function createContentUrl(DOMDocument $document, string $contentUrl): ?DOMElement; - abstract protected function createFeedUrl(DOMDocument $document, string $feedUrl): ?DOMElement; - abstract protected function createItem(DOMDocument $document, FeedItem $feedItem): DOMElement; - abstract protected function createItemTitle(DOMDocument $document, string $title): DOMElement; - abstract protected function createItemSummary(DOMDocument $document, string $summary): ?DOMElement; - abstract protected function createItemContent(DOMDocument $document, string $content): ?DOMElement; - abstract protected function createItemCreationDate(DOMDocument $document, int $creationDate): ?DOMElement; - abstract protected function createItemUniqueId(DOMDocument $document, string $uniqueId): ?DOMElement; - abstract protected function createItemContentUrl(DOMDocument $document, string $contentUrl): ?DOMElement; - abstract protected function createItemCommentsUrl(DOMDocument $document, string $commentsUrl): ?DOMElement; - abstract protected function createItemAuthor(DOMDocument $document, ?string $authorName, ?string $authorUrl): ?DOMElement; + abstract protected function createRoot(DOMDocument $document, Feed $feed): DOMNode; + abstract protected function createTitle(DOMDocument $document, string $title): DOMNode; + abstract protected function createDescription(DOMDocument $document, string $description): ?DOMNode; + abstract protected function createLastUpdate(DOMDocument $document, int $lastUpdate): ?DOMNode; + abstract protected function createContentUrl(DOMDocument $document, string $contentUrl): ?DOMNode; + abstract protected function createFeedUrl(DOMDocument $document, string $feedUrl): ?DOMNode; + abstract protected function createItem(DOMDocument $document, FeedItem $feedItem): DOMNode; + abstract protected function createItemTitle(DOMDocument $document, string $title): DOMNode; + abstract protected function createItemSummary(DOMDocument $document, string $summary): ?DOMNode; + abstract protected function createItemContent(DOMDocument $document, string $content): ?DOMNode; + abstract protected function createItemCreationDate(DOMDocument $document, int $creationDate): ?DOMNode; + abstract protected function createItemUniqueId(DOMDocument $document, string $uniqueId): ?DOMNode; + abstract protected function createItemContentUrl(DOMDocument $document, string $contentUrl): ?DOMNode; + abstract protected function createItemCommentsUrl(DOMDocument $document, string $commentsUrl): ?DOMNode; + abstract protected function createItemAuthor(DOMDocument $document, ?string $authorName, ?string $authorUrl): ?DOMNode; } diff --git a/src/Forum/topic.php b/src/Forum/topic.php index f79999c..727b8ba 100644 --- a/src/Forum/topic.php +++ b/src/Forum/topic.php @@ -616,7 +616,7 @@ function forum_topic_can_delete($topicId, ?int $userId = null): int { return MSZ_E_FORUM_TOPIC_DELETE_OLD; } - $totalReplies = $topic['topic_count_posts'] + $topic['topic_count_posts_deleted']; + $totalReplies = (int)$topic['topic_count_posts'] + (int)$topic['topic_count_posts_deleted']; if($totalReplies > MSZ_E_FORUM_TOPIC_DELETE_POSTS) { return MSZ_E_FORUM_TOPIC_DELETE_POSTS; diff --git a/src/Http/Handlers/AssetsHandler.php b/src/Http/Handlers/AssetsHandler.php index d942dfb..61eb128 100644 --- a/src/Http/Handlers/AssetsHandler.php +++ b/src/Http/Handlers/AssetsHandler.php @@ -86,7 +86,7 @@ final class AssetsHandler extends Handler { } public function serveLegacy($response, $request) { - $assetUserId = (int)$request->getParam('u', FILTER_SANITIZE_NUMBER_INT); + $assetUserId = $request->getParam('u', FILTER_SANITIZE_NUMBER_INT); switch($request->getParam('m')) { case 'avatar': diff --git a/src/Imaging/Image.php b/src/Imaging/Image.php index 6526645..70abaea 100644 --- a/src/Imaging/Image.php +++ b/src/Imaging/Image.php @@ -47,8 +47,8 @@ abstract class Image { $this->resize($targetWidth, $targetHeight); $this->crop( $dimensions, $dimensions, - ceil(($targetWidth - $dimensions) / 2), - ceil(($targetHeight - $dimensions) / 2) + (int)ceil(($targetWidth - $dimensions) / 2), + (int)ceil(($targetHeight - $dimensions) / 2) ); $this->setPage($dimensions, $dimensions, 0, 0); } while($this->next()); diff --git a/src/Mailer.php b/src/Mailer.php index 896ddbe..bfd7378 100644 --- a/src/Mailer.php +++ b/src/Mailer.php @@ -15,9 +15,6 @@ final class Mailer { private static IConfig $config; private static $transport = null; - private static string $senderName = 'Flashii'; - private static string $senderAddr = 'sys@flashii.net'; - public static function init(IConfig $config): void { self::$config = $config; } @@ -49,12 +46,6 @@ final class Mailer { $dsn .= ':'; $dsn .= $config['port'] ?? 25; - if(!empty($config['sender.name'])) - self::$senderName = $config['sender.name']; - - if(!empty($config['sender.address'])) - self::$senderAddr = $config['sender.address']; - return $dsn; } @@ -71,8 +62,8 @@ final class Mailer { } $config = self::$config->getValues([ - 'sender.name:s', - 'sender.address:s', + ['sender.name:s', 'Flashii'], + ['sender.address:s', 'sys@flashii.net'], ]); $message = new SymfonyMessage; @@ -90,14 +81,8 @@ final class Mailer { $message->subject(trim($subject)); $message->text(trim($contents)); - try { - self::getTransport()->send($message); - return true; - } catch(TransportExceptionInterface $ex) { - if(MSZ_DEBUG) - throw $ex; - return false; - } + self::getTransport()->send($message); + return true; } public static function template(string $name, array $vars = []): array { diff --git a/src/MisuzuContext.php b/src/MisuzuContext.php index 53ff120..52d22ce 100644 --- a/src/MisuzuContext.php +++ b/src/MisuzuContext.php @@ -10,7 +10,6 @@ use Misuzu\Emoticons\Emotes; use Misuzu\News\News; use Misuzu\SharpChat\SharpChatRoutes; use Misuzu\Users\User; -use Misuzu\Users\Users; use Index\Data\IDbConnection; use Index\Data\Migration\IDbMigrationRepo; use Index\Data\Migration\DbMigrationManager; @@ -25,7 +24,6 @@ use Index\Routing\Router; class MisuzuContext { private IDbConnection $dbConn; private IConfig $config; - private Users $users; private HttpFx $router; private AuditLog $auditLog; private Emotes $emotes; @@ -36,7 +34,6 @@ class MisuzuContext { public function __construct(IDbConnection $dbConn, IConfig $config) { $this->dbConn = $dbConn; $this->config = $config; - $this->users = new Users($this->dbConn); $this->auditLog = new AuditLog($this->dbConn); $this->emotes = new Emotes($this->dbConn); $this->changelog = new Changelog($this->dbConn); @@ -69,10 +66,6 @@ class MisuzuContext { return $this->router->getRouter(); } - /*public function getUsers(): Users { - return $this->users; - }*/ - public function getEmotes(): Emotes { return $this->emotes; } diff --git a/src/News/News.php b/src/News/News.php index 5c87861..3bcc8c7 100644 --- a/src/News/News.php +++ b/src/News/News.php @@ -182,8 +182,8 @@ class News { $args = 0; $query = 'SELECT COUNT(*) FROM msz_news_posts'; if($onlyFeatured) { - $query .= (++$args > 1 ? ' AND' : ' WHERE'); - $query .= ' post_is_featured = 1'; + ++$args; + $query .= ' WHERE post_is_featured = 1'; } if(!$includeScheduled) { $query .= (++$args > 1 ? ' AND' : ' WHERE'); @@ -247,8 +247,8 @@ class News { $query = self::POSTS_SELECT_QUERY; if($onlyFeatured) { - $query .= (++$args > 1 ? ' AND' : ' WHERE'); - $query .= ' post_is_featured = 1'; + ++$args; + $query .= ' WHERE post_is_featured = 1'; } if(!$includeScheduled) { $query .= (++$args > 1 ? ' AND' : ' WHERE'); diff --git a/src/SharpChat/SharpChatRoutes.php b/src/SharpChat/SharpChatRoutes.php index 4804626..d295ee4 100644 --- a/src/SharpChat/SharpChatRoutes.php +++ b/src/SharpChat/SharpChatRoutes.php @@ -3,6 +3,7 @@ namespace Misuzu\SharpChat; use Index\Colour\Colour; use Index\Routing\IRouter; +use Index\Http\HttpFx; use Misuzu\AuthToken; use Misuzu\Config\IConfig; use Misuzu\Emoticons\Emotes; @@ -35,23 +36,24 @@ final class SharpChatRoutes { } // Simplify default error pages - $router->use('/_sockchat', function() use($router) { - $router->addErrorHandler(400, function($response) { - $response->setContent('HTTP 400'); + if($router instanceof HttpFx) + $router->use('/_sockchat', function() use($router) { + $router->addErrorHandler(400, function($response) { + $response->setContent('HTTP 400'); + }); + $router->addErrorHandler(403, function($response) { + $response->setContent('HTTP 403'); + }); + $router->addErrorHandler(404, function($response) { + $response->setContent('HTTP 404'); + }); + $router->addErrorHandler(500, function($response) { + $response->setContent('HTTP 500'); + }); + $router->addErrorHandler(503, function($response) { + $response->setContent('HTTP 503'); + }); }); - $router->addErrorHandler(403, function($response) { - $response->setContent('HTTP 403'); - }); - $router->addErrorHandler(404, function($response) { - $response->setContent('HTTP 404'); - }); - $router->addErrorHandler(500, function($response) { - $response->setContent('HTTP 500'); - }); - $router->addErrorHandler(503, function($response) { - $response->setContent('HTTP 503'); - }); - }); // Public endpoints $router->get('/_sockchat/emotes', [$this, 'getEmotes']); @@ -201,6 +203,8 @@ final class SharpChatRoutes { } else { $bumpString = (string)$request->getContent(); $signature = $bumpString; + $userTime = 0; + $bumpList = []; } $userHash = (string)$request->getHeaderFirstLine('X-SharpChat-Signature'); @@ -212,7 +216,6 @@ final class SharpChatRoutes { if($userTime < time() - 60) return 403; } else { - $bumpList = []; $bumpInfo = json_decode($bumpString); if(empty($bumpInfo)) return; @@ -246,7 +249,7 @@ final class SharpChatRoutes { if(strlen($userHash) !== 64) return ['success' => false, 'reason' => 'length']; - if(isset($authInfo) && !empty($authInfo->token) && !empty($authInfo->ip)) { + if(!empty($authInfo->token) && !empty($authInfo->ip)) { // user_id is discarded now // tokens should be entirely unique anyway @@ -257,13 +260,14 @@ final class SharpChatRoutes { } else [$authMethod, $authToken] = $tokenParts; $ipAddress = $authInfo->ip; - $signature = "{$authInfo->user_id}#{$authInfo->token}#{$authInfo->ip}"; + $sigUserId = $authInfo->user_id ?? 0; // still need it for the signature + $signature = "{$sigUserId}#{$authInfo->token}#{$authInfo->ip}"; } - if(empty($authMethod) || empty($authToken)) + if(empty($authMethod) || empty($authToken) || empty($ipAddress)) return ['success' => false, 'reason' => 'data']; - if(!isset($signature)) + if(empty($signature)) $signature = "verify#{$authMethod}#{$authToken}#{$ipAddress}"; $realHash = hash_hmac('sha256', $signature, $this->hashKey); @@ -463,8 +467,8 @@ final class SharpChatRoutes { // IPs cannot be banned on their own // substituting with the unused Railgun account for now. - if(empty($targetId)) - $targetId = 69; + if(empty($userId)) + $userId = 69; if(empty($modId)) $modId = 69; diff --git a/src/Users/Assets/UserImageAsset.php b/src/Users/Assets/UserImageAsset.php index c943170..bf5ccdf 100644 --- a/src/Users/Assets/UserImageAsset.php +++ b/src/Users/Assets/UserImageAsset.php @@ -93,7 +93,7 @@ abstract class UserImageAsset implements UserImageAssetInterface { throw new UserImageAssetFileNotFoundException; $imageInfo = getimagesize($path); - if($imageInfo === false || count($imageInfo) < 3 || $imageInfo[0] < 1 || $imageInfo[1] < 1) + if($imageInfo === false || $imageInfo[0] < 1 || $imageInfo[1] < 1) throw new UserImageAssetInvalidImageException; if(!self::isAllowedType($imageInfo[2])) diff --git a/src/Users/ProfileField.php b/src/Users/ProfileField.php index fb3ab88..9305381 100644 --- a/src/Users/ProfileField.php +++ b/src/Users/ProfileField.php @@ -4,6 +4,12 @@ namespace Misuzu\Users; use Misuzu\DB; class ProfileField { + // Database fields + public $field_id; + public $user_id; + public $field_regex; + public $field_value; + public static function createField( string $fieldKey, string $fieldTitle, diff --git a/src/Users/User.php b/src/Users/User.php index 4d85b6e..c3c206c 100644 --- a/src/Users/User.php +++ b/src/Users/User.php @@ -779,7 +779,12 @@ class User implements HasRankInterface { private static function byQueryBase(): string { return sprintf(self::QUERY_SELECT, sprintf(self::SELECT, self::TABLE)); } - public static function byId(int $userId): ?self { + public static function byId(string|int $userId): ?self { + // newer classes all treat ids as if they're strings + // php plays nice with it but may as well be sure since phpstan screams about it + if(is_string($userId)) + $userId = (int)$userId; + return self::memoizer()->find($userId, function() use ($userId) { $user = DB::prepare(self::byQueryBase() . ' WHERE `user_id` = :user_id') ->bind('user_id', $userId) diff --git a/src/Users/UserRole.php b/src/Users/UserRole.php index 875e4a2..2655888 100644 --- a/src/Users/UserRole.php +++ b/src/Users/UserRole.php @@ -33,7 +33,6 @@ class UserRole implements ArrayAccess, HasRankInterface { . ', UNIX_TIMESTAMP(%1$s.`role_created`) AS `role_created`'; private $colour = null; - private $users = []; private $userCount = -1; public function getId(): int { diff --git a/src/Users/Users.php b/src/Users/Users.php deleted file mode 100644 index 4832403..0000000 --- a/src/Users/Users.php +++ /dev/null @@ -1,43 +0,0 @@ -dbConn = $dbConn; - } - - public function getById(string $userId): User { - // - } - - public function getByName(string $userName): User { - // - } - - public function getByMailAddress(string $mailAddress): User { - // - } - - public function getByNameOrMailAddress(string $userNameOrMailAddress): User { - // - } - - public function getByIdOrName(string $userIdOrName): User { - // - } - - public function getByBirthDate(DateTimeImmutable $dateTime): array { - // - } - - public function getByAll(bool $includeDeleted = false, ?Pagination $pagination = null): array { - // - } -} diff --git a/src/manage.php b/src/manage.php index b042eec..0a2bff8 100644 --- a/src/manage.php +++ b/src/manage.php @@ -66,6 +66,7 @@ function manage_perms_apply(array $list, array $post, ?array $raw = null): ?arra foreach($section['perms'] as $perm) { if(empty($post[$section['section']][$perm['section']]['value'])) continue; + $perm['perm'] = (int)$perm['perm']; // makes phpstan happy switch($post[$section['section']][$perm['section']]['value']) { case MSZ_MANAGE_PERM_YES: