diff --git a/database/2025_02_08_213207_moved_forum_signature_to_dedicated_table.php b/database/2025_02_08_213207_moved_forum_signature_to_dedicated_table.php new file mode 100644 index 00000000..f0a08591 --- /dev/null +++ b/database/2025_02_08_213207_moved_forum_signature_to_dedicated_table.php @@ -0,0 +1,36 @@ +<?php +use Index\Db\DbConnection; +use Index\Db\Migration\DbMigration; + +final class MovedForumSignatureToDedicatedTable_20250208_213207 implements DbMigration { + public function migrate(DbConnection $conn): void { + $conn->execute(<<<SQL + CREATE TABLE msz_forum_signatures ( + user_id INT UNSIGNED NOT NULL, + signature_body TEXT NOT NULL COLLATE 'utf8mb4_unicode_520_ci', + signature_body_format ENUM('','bb','md') NOT NULL COLLATE 'ascii_general_ci', + signature_created TIMESTAMP NOT NULL DEFAULT NOW(), + PRIMARY KEY (user_id), + CONSTRAINT forum_signatures_users_foreign + FOREIGN KEY (user_id) + REFERENCES msz_users (user_id) + ON UPDATE CASCADE + ON DELETE CASCADE + ) COLLATE='utf8mb4_bin'; + SQL); + + $conn->execute(<<<SQL + INSERT INTO msz_forum_signatures + SELECT user_id, user_signature_content, user_signature_content_format, NOW() + FROM msz_users + WHERE user_signature_content IS NOT NULL + AND TRIM(user_signature_content) <> '' + SQL); + + $conn->execute(<<<SQL + ALTER TABLE msz_users + DROP COLUMN user_signature_content, + DROP COLUMN user_signature_content_format; + SQL); + } +} diff --git a/public-legacy/profile.php b/public-legacy/profile.php index d81427be..84975433 100644 --- a/public-legacy/profile.php +++ b/public-legacy/profile.php @@ -5,6 +5,7 @@ use stdClass; use InvalidArgumentException; use RuntimeException; use Index\ByteFormat; +use Misuzu\Forum\ForumSignaturesData; use Misuzu\Parsers\TextFormat; use Misuzu\Profile\ProfileBackgroundAttach; use Misuzu\Users\{User,UsersContext}; @@ -79,6 +80,8 @@ $avatarAsset = new UserAvatarAsset($userInfo); $backgroundInfo = $msz->profileCtx->backgrounds->getProfileBackground($userInfo); $backgroundAsset = new UserBackgroundAsset($userInfo, $backgroundInfo); +$sigInfo = $msz->forumCtx->signatures->getSignature($userInfo); + if($isEditing) { if(!$canEdit) Template::throwError(403); @@ -152,18 +155,22 @@ if($isEditing) { } } - if(!empty($_POST['signature']) && is_array($_POST['signature'])) { + if(filter_has_var(INPUT_POST, 'sig_body')) { if(!$perms->edit_signature) { $notices[] = 'You\'re not allowed to edit your forum signature.'; } else { - $sigText = (string)($_POST['signature']['text'] ?? ''); - $sigParse = TextFormat::tryFrom((string)($_POST['signature']['parser'] ?? '')) ?? TextFormat::Plain; - $sigValid = $msz->usersCtx->users->validateForumSignature($sigParse, $sigText); - - if($sigValid === '') - $msz->usersCtx->users->updateUser($userInfo, signatureBody: $sigText, signatureBodyFormat: $sigParse); - else - $notices[] = $msz->usersCtx->users->validateForumSignatureText($sigValid); + $sigBody = (string)filter_input(INPUT_POST, 'sig_body'); + if(trim($sigBody) === '') { + $msz->forumCtx->signatures->deleteSignature($userInfo); + $sigInfo = null; + } else { + $sigFormat = TextFormat::tryFrom(filter_input(INPUT_POST, 'sig_format')); + $sigValid = ForumSignaturesData::validateSignature($sigFormat, $sigBody); + if($sigValid === '') + $sigInfo = $msz->forumCtx->signatures->updateSignature($userInfo, $sigBody, $sigFormat); + else + $notices[] = ForumSignaturesData::validateSignatureText($sigValid); + } } } @@ -395,4 +402,5 @@ Template::render('profile.index', [ 'profile_background_asset' => $backgroundAsset, 'profile_can_send_messages' => $viewerPermsGlobal->check(Perm::G_MESSAGES_SEND), 'profile_age' => $msz->usersCtx->birthdates->getUserAge($userInfo), + 'profile_forum_signature_info' => $sigInfo, ]); diff --git a/public-legacy/settings/data.php b/public-legacy/settings/data.php index fd919016..a991f5c8 100644 --- a/public-legacy/settings/data.php +++ b/public-legacy/settings/data.php @@ -134,6 +134,7 @@ if(isset($_POST['action']) && is_string($_POST['action'])) { $tmpFiles[] = db_to_zip($archive, $userInfo, 'comments_posts', ['comment_id:s', 'category_id:s', 'user_id:s:n', 'comment_reply_to:s:n', 'comment_text:s', 'comment_created:t', 'comment_pinned:t:n', 'comment_edited:t:n', 'comment_deleted:t:n']); $tmpFiles[] = db_to_zip($archive, $userInfo, 'comments_votes', ['comment_id:s', 'user_id:s', 'comment_vote:i']); $tmpFiles[] = db_to_zip($archive, $userInfo, 'forum_posts', ['post_id:s', 'topic_id:s', 'forum_id:s', 'user_id:s:n', 'post_remote_addr:a', 'post_text:s', 'post_text_format:s', 'post_display_signature:b', 'post_created:t', 'post_edited:t:n', 'post_deleted:t:n']); + $tmpFiles[] = db_to_zip($archive, $userInfo, 'forum_signatures', ['user_id:s', 'signature_body:s', 'signature_body_format:s', 'signature_created:t']); $tmpFiles[] = db_to_zip($archive, $userInfo, 'forum_topics', ['topic_id:s', 'forum_id:s', 'user_id:s:n', 'topic_type:i', 'topic_title:s', 'topic_count_views:i', 'topic_created:t', 'topic_bumped:t', 'topic_deleted:t:n', 'topic_locked:t:n']); $tmpFiles[] = db_to_zip($archive, $userInfo, 'forum_topics_redirects', ['topic_id:s', 'user_id:s:n', 'redir_url:s', 'redir_created:t']); $tmpFiles[] = db_to_zip($archive, $userInfo, 'forum_topics_track', ['user_id:s', 'topic_id:s', 'forum_id:s', 'track_last_read:t']); @@ -149,7 +150,7 @@ if(isset($_POST['action']) && is_string($_POST['action'])) { $tmpFiles[] = db_to_zip($archive, $userInfo, 'profile_backgrounds', ['user_id:s', 'bg_attach:s', 'bg_blend:i', 'bg_slide:i']); $tmpFiles[] = db_to_zip($archive, $userInfo, 'profile_fields_values', ['field_id:s', 'user_id:s', 'format_id:s', 'field_value:s']); $tmpFiles[] = db_to_zip($archive, $userInfo, 'sessions', ['session_id:s', 'user_id:s', 'session_key:n', 'session_remote_addr_first:a', 'session_remote_addr_last:a:n', 'session_user_agent:s', 'session_country:s', 'session_expires:t', 'session_expires_bump:b', 'session_created:t', 'session_active:t:n']); - $tmpFiles[] = db_to_zip($archive, $userInfo, 'users', ['user_id:s', 'user_name:s', 'user_password:n', 'user_email:s', 'user_remote_addr_first:a', 'user_remote_addr_last:a', 'user_super:b', 'user_country:s', 'user_colour:i:n', 'user_created:t', 'user_active:t:n', 'user_deleted:t:n', 'user_display_role_id:s:n', 'user_about_content:s:n', 'user_about_content_format:s', 'user_signature_content:s:n', 'user_signature_content_format:s', 'user_title:s:n']); + $tmpFiles[] = db_to_zip($archive, $userInfo, 'users', ['user_id:s', 'user_name:s', 'user_password:n', 'user_email:s', 'user_remote_addr_first:a', 'user_remote_addr_last:a', 'user_super:b', 'user_country:s', 'user_colour:i:n', 'user_created:t', 'user_active:t:n', 'user_deleted:t:n', 'user_display_role_id:s:n', 'user_about_content:s:n', 'user_about_content_format:s', 'user_title:s:n']); $tmpFiles[] = db_to_zip($archive, $userInfo, 'users_bans', ['ban_id:s', 'user_id:s', 'mod_id:n', 'ban_severity:i', 'ban_reason_public:s', 'ban_reason_private:s', 'ban_created:t', 'ban_expires:t:n']); $tmpFiles[] = db_to_zip($archive, $userInfo, 'users_birthdates', ['user_id:s', 'birth_year:i:n', 'birth_month:i', 'birth_day:i']); $tmpFiles[] = db_to_zip($archive, $userInfo, 'users_password_resets', ['reset_id:s', 'user_id:s', 'reset_remote_addr:a', 'reset_requested:t', 'reset_code:n']); diff --git a/src/Forum/ForumContext.php b/src/Forum/ForumContext.php index 1cb142ca..3b90ba87 100644 --- a/src/Forum/ForumContext.php +++ b/src/Forum/ForumContext.php @@ -3,6 +3,7 @@ namespace Misuzu\Forum; use stdClass; use Index\Db\DbConnection; +use Misuzu\Parsers\TextFormat; use Misuzu\Users\UserInfo; class ForumContext { @@ -10,6 +11,7 @@ class ForumContext { public private(set) ForumTopicsData $topics; public private(set) ForumTopicRedirectsData $topicRedirects; public private(set) ForumPostsData $posts; + public private(set) ForumSignaturesData $signatures; /** @var array<string, int> */ private array $totalUserTopics = []; @@ -17,11 +19,15 @@ class ForumContext { /** @var array<string, int> */ private array $totalUserPosts = []; + /** @var array<string, ForumSignatureInfo> */ + private array $cachedSignatures = []; + public function __construct(DbConnection $dbConn) { $this->categories = new ForumCategoriesData($dbConn); $this->topics = new ForumTopicsData($dbConn); $this->topicRedirects = new ForumTopicRedirectsData($dbConn); $this->posts = new ForumPostsData($dbConn); + $this->signatures = new ForumSignaturesData($dbConn); } // should be replaced by a static counter @@ -47,4 +53,15 @@ class ForumContext { return $this->totalUserPosts[$userId] = $this->posts->countPosts(userInfo: $userInfo, deleted: false); } + + public function getCachedSignature(UserInfo|string|null $userInfo): ?ForumSignatureInfo { + if($userInfo === null) + return null; + + $userId = $userInfo instanceof UserInfo ? $userInfo->id : $userInfo; + if(array_key_exists($userId, $this->cachedSignatures)) + return $this->cachedSignatures[$userId]; + + return $this->cachedSignatures[$userId] = $this->signatures->getSignature($userInfo); + } } diff --git a/src/Forum/ForumSignatureInfo.php b/src/Forum/ForumSignatureInfo.php new file mode 100644 index 00000000..0af68227 --- /dev/null +++ b/src/Forum/ForumSignatureInfo.php @@ -0,0 +1,40 @@ +<?php +namespace Misuzu\Forum; + +use Carbon\CarbonImmutable; +use Index\Db\DbResult; +use Misuzu\Parsers\TextFormat; + +class ForumSignatureInfo { + public function __construct( + public private(set) string $userId, + public private(set) string $body, + public private(set) TextFormat $bodyFormat, + public private(set) int $createdTime, + ) {} + + public static function fromResult(DbResult $result): self { + return new ForumSignatureInfo( + userId: $result->getString(0), + body: $result->getString(1), + bodyFormat: TextFormat::tryFrom($result->getString(2)) ?? TextFormat::Plain, + createdTime: $result->getInteger(3), + ); + } + + public CarbonImmutable $createdAt { + get => CarbonImmutable::createFromTimestampUTC($this->createdTime); + } + + public bool $isBodyPlain { + get => $this->bodyFormat === TextFormat::Plain; + } + + public bool $isBodyBBCode { + get => $this->bodyFormat === TextFormat::BBCode; + } + + public bool $isBodyMarkdown { + get => $this->bodyFormat === TextFormat::Markdown; + } +} diff --git a/src/Forum/ForumSignaturesData.php b/src/Forum/ForumSignaturesData.php new file mode 100644 index 00000000..f782f713 --- /dev/null +++ b/src/Forum/ForumSignaturesData.php @@ -0,0 +1,84 @@ +<?php +namespace Misuzu\Forum; + +use RuntimeException; +use Index\Db\{DbConnection,DbStatementCache}; +use Misuzu\Parsers\TextFormat; +use Misuzu\Users\UserInfo; + +class ForumSignaturesData { + public const int BODY_MAX_LENGTH = 2000; + + private DbStatementCache $cache; + + public function __construct(DbConnection $dbConn) { + $this->cache = new DbStatementCache($dbConn); + } + + public function getSignature(UserInfo|string $userInfo): ?ForumSignatureInfo { + $stmt = $this->cache->get(<<<SQL + SELECT user_id, signature_body, signature_body_format, UNIX_TIMESTAMP(signature_created) + FROM msz_forum_signatures + WHERE user_id = ? + SQL); + $stmt->nextParameter($userInfo instanceof UserInfo ? $userInfo->id : $userInfo); + $stmt->execute(); + + $result = $stmt->getResult(); + return $result->next() ? ForumSignatureInfo::fromResult($result) : null; + } + + public function deleteSignature(UserInfo|string $userInfo): void { + $stmt = $this->cache->get(<<<SQL + DELETE FROM msz_forum_signatures + WHERE user_id = ? + SQL); + $stmt->nextParameter($userInfo instanceof UserInfo ? $userInfo->id : $userInfo); + $stmt->execute(); + } + + public function updateSignature( + UserInfo|string $userInfo, + string $body, + TextFormat|string $format + ): ForumSignatureInfo { + if(is_string($format)) + $format = TextFormat::from($format); + + $stmt = $this->cache->get(<<<SQL + REPLACE INTO msz_forum_signatures ( + user_id, signature_body, signature_body_format + ) VALUES (?, ?, ?) + SQL); + $stmt->nextParameter($userInfo instanceof UserInfo ? $userInfo->id : $userInfo); + $stmt->nextParameter($body); + $stmt->nextParameter($format->value); + $stmt->execute(); + + $sigInfo = $this->getSignature($userInfo); + if($sigInfo === null) + throw new RuntimeException('failed to update forum signature'); + + return $sigInfo; + } + + public static function validateSignature(?TextFormat $format, string $text): string { + if($format === null) + return 'parser'; + + $length = mb_strlen($text); + if($length > self::BODY_MAX_LENGTH) + return 'long'; + + return ''; + } + + public static function validateSignatureText(string $error): string { + return match($error) { + 'parser' => 'You attempted to select an invalid parser for your forum signature.', + 'long' => sprintf('Please keep the length of your forum signature below %d characters.', self::BODY_MAX_LENGTH), + '' => 'Your forum signature is fine, why are you seeing this?', + default => 'Your forum signature is not acceptable.', + }; + } +} diff --git a/src/Forum/ForumTopicsRoutes.php b/src/Forum/ForumTopicsRoutes.php index d24b6e18..cf616d78 100644 --- a/src/Forum/ForumTopicsRoutes.php +++ b/src/Forum/ForumTopicsRoutes.php @@ -15,7 +15,7 @@ class ForumTopicsRoutes implements RouteHandler, UrlSource { use RouteHandlerCommon, UrlSourceCommon; public function __construct( - private ForumContext $forum, + private ForumContext $forumCtx, private UsersContext $usersCtx, private AuditLogData $auditLog, private AuthInfo $authInfo, @@ -26,7 +26,7 @@ class ForumTopicsRoutes implements RouteHandler, UrlSource { public function getTopic(HttpResponseBuilder $response, HttpRequest $request, string $topicId): mixed { $isNuked = $deleted = $canDeleteAny = false; try { - $topic = $this->forum->topics->getTopic(topicId: $topicId); + $topic = $this->forumCtx->topics->getTopic(topicId: $topicId); $deleted = $topic->deleted; $perms = $this->authInfo->getPerms('forum', $topic->categoryId); @@ -39,8 +39,8 @@ class ForumTopicsRoutes implements RouteHandler, UrlSource { } if($isNuked || $deleted) { - if($this->forum->topicRedirects->hasTopicRedirect($topicId)) { - $redirect = $this->forum->topicRedirects->getTopicRedirect($topicId); + if($this->forumCtx->topicRedirects->hasTopicRedirect($topicId)) { + $redirect = $this->forumCtx->topicRedirects->getTopicRedirect($topicId); Template::set('topic_redir_info', $redirect); if($isNuked || !$canDeleteAny) { @@ -70,7 +70,7 @@ class ForumTopicsRoutes implements RouteHandler, UrlSource { // this should be in the config $deletePostThreshold = 1; - $categoryInfo = $this->forum->categories->getCategory(topicInfo: $topic); + $categoryInfo = $this->forumCtx->categories->getCategory(topicInfo: $topic); $isFrozen = $categoryInfo->archived || $deleted; $canDeleteOwn = !$isFrozen && !$topic->locked && $perms->check(Perm::F_POST_DELETE_OWN); $canBump = !$isFrozen && $perms->check(Perm::F_TOPIC_BUMP); @@ -86,7 +86,7 @@ class ForumTopicsRoutes implements RouteHandler, UrlSource { ) ); - $postInfos = $this->forum->posts->getPosts( + $postInfos = $this->forumCtx->posts->getPosts( topicInfo: $topic, deleted: $perms->check(Perm::F_POST_DELETE_ANY) ? null : false, pagination: $pagination, @@ -95,7 +95,7 @@ class ForumTopicsRoutes implements RouteHandler, UrlSource { return 404; try { - $originalPostInfo = $this->forum->posts->getPost(topicInfo: $topic); + $originalPostInfo = $this->forumCtx->posts->getPost(topicInfo: $topic); } catch(RuntimeException $ex) { return 404; } @@ -109,7 +109,13 @@ class ForumTopicsRoutes implements RouteHandler, UrlSource { if($postInfo->userId !== null) { $post->user = $this->usersCtx->getUserInfo($postInfo->userId); $post->colour = $this->usersCtx->getUserColour($post->user); - $post->postsCount = $this->forum->countTotalUserPosts($post->user); + $post->postsCount = $this->forumCtx->countTotalUserPosts($post->user); + + if($postInfo->shouldDisplaySignature) { + $sigInfo = $this->forumCtx->getCachedSignature($post->user); + if($sigInfo !== null) + $post->signature = $sigInfo; + } } $post->isOriginalPost = $originalPostInfo->id == $postInfo->id; @@ -117,14 +123,14 @@ class ForumTopicsRoutes implements RouteHandler, UrlSource { && $originalPostInfo->userId === $postInfo->userId; } - if(!$this->forum->topics->checkUserHasReadTopic($this->authInfo->userInfo, $topic)) - $this->forum->topics->incrementTopicViews($topic); + if(!$this->forumCtx->topics->checkUserHasReadTopic($this->authInfo->userInfo, $topic)) + $this->forumCtx->topics->incrementTopicViews($topic); - $this->forum->topics->updateUserReadTopic($this->authInfo->userInfo, $topic); + $this->forumCtx->topics->updateUserReadTopic($this->authInfo->userInfo, $topic); return Template::renderRaw('forum.topic', [ - 'topic_breadcrumbs' => iterator_to_array($this->forum->categories->getCategoryAncestry($topic)), - 'global_accent_colour' => $this->forum->categories->getCategoryColour($topic), + 'topic_breadcrumbs' => iterator_to_array($this->forumCtx->categories->getCategoryAncestry($topic)), + 'global_accent_colour' => $this->forumCtx->categories->getCategoryColour($topic), 'topic_info' => $topic, 'category_info' => $categoryInfo, 'topic_posts' => $posts, @@ -167,7 +173,7 @@ class ForumTopicsRoutes implements RouteHandler, UrlSource { } try { - $topic = $this->forum->topics->getTopic( + $topic = $this->forumCtx->topics->getTopic( topicId: $topicId, deleted: false, ); @@ -231,7 +237,7 @@ class ForumTopicsRoutes implements RouteHandler, UrlSource { $deletePostThreshold = 1; // deleted posts are intentionally included - $topicPostCount = $this->forum->posts->countPosts(topicInfo: $topic); + $topicPostCount = $this->forumCtx->posts->countPosts(topicInfo: $topic); if($topicPostCount > $deletePostThreshold) { $response->statusCode = 403; return [ @@ -243,7 +249,7 @@ class ForumTopicsRoutes implements RouteHandler, UrlSource { } } - $category = $this->forum->categories->getCategory(topicInfo: $topic); + $category = $this->forumCtx->categories->getCategory(topicInfo: $topic); if($category->archived) { $response->statusCode = 400; return [ @@ -254,7 +260,7 @@ class ForumTopicsRoutes implements RouteHandler, UrlSource { ]; } - $this->forum->topics->deleteTopic($topic); + $this->forumCtx->topics->deleteTopic($topic); $this->auditLog->createLog( $this->authInfo->userInfo, 'FORUM_TOPIC_DELETE', @@ -287,7 +293,7 @@ class ForumTopicsRoutes implements RouteHandler, UrlSource { } try { - $topic = $this->forum->topics->getTopic( + $topic = $this->forumCtx->topics->getTopic( topicId: $topicId, deleted: true, ); @@ -323,7 +329,7 @@ class ForumTopicsRoutes implements RouteHandler, UrlSource { ]; } - $category = $this->forum->categories->getCategory(topicInfo: $topic); + $category = $this->forumCtx->categories->getCategory(topicInfo: $topic); if($category->archived) { $response->statusCode = 400; return [ @@ -334,7 +340,7 @@ class ForumTopicsRoutes implements RouteHandler, UrlSource { ]; } - $this->forum->topics->restoreTopic($topic); + $this->forumCtx->topics->restoreTopic($topic); $this->auditLog->createLog( $this->authInfo->userInfo, 'FORUM_TOPIC_RESTORE', @@ -367,7 +373,7 @@ class ForumTopicsRoutes implements RouteHandler, UrlSource { } try { - $topic = $this->forum->topics->getTopic( + $topic = $this->forumCtx->topics->getTopic( topicId: $topicId, deleted: true, ); @@ -403,7 +409,7 @@ class ForumTopicsRoutes implements RouteHandler, UrlSource { ]; } - $category = $this->forum->categories->getCategory(topicInfo: $topic); + $category = $this->forumCtx->categories->getCategory(topicInfo: $topic); if($category->archived) { $response->statusCode = 400; return [ @@ -414,7 +420,7 @@ class ForumTopicsRoutes implements RouteHandler, UrlSource { ]; } - $this->forum->topics->nukeTopic($topic); + $this->forumCtx->topics->nukeTopic($topic); $this->auditLog->createLog( $this->authInfo->userInfo, 'FORUM_TOPIC_NUKE', @@ -447,7 +453,7 @@ class ForumTopicsRoutes implements RouteHandler, UrlSource { } try { - $topic = $this->forum->topics->getTopic( + $topic = $this->forumCtx->topics->getTopic( topicId: $topicId, deleted: false, ); @@ -483,7 +489,7 @@ class ForumTopicsRoutes implements RouteHandler, UrlSource { ]; } - $category = $this->forum->categories->getCategory(topicInfo: $topic); + $category = $this->forumCtx->categories->getCategory(topicInfo: $topic); if($category->archived) { $response->statusCode = 400; return [ @@ -494,7 +500,7 @@ class ForumTopicsRoutes implements RouteHandler, UrlSource { ]; } - $this->forum->topics->bumpTopic($topic); + $this->forumCtx->topics->bumpTopic($topic); $this->auditLog->createLog( $this->authInfo->userInfo, 'FORUM_TOPIC_BUMP', @@ -527,7 +533,7 @@ class ForumTopicsRoutes implements RouteHandler, UrlSource { } try { - $topic = $this->forum->topics->getTopic( + $topic = $this->forumCtx->topics->getTopic( topicId: $topicId, deleted: false, ); @@ -573,7 +579,7 @@ class ForumTopicsRoutes implements RouteHandler, UrlSource { ]; } - $category = $this->forum->categories->getCategory(topicInfo: $topic); + $category = $this->forumCtx->categories->getCategory(topicInfo: $topic); if($category->archived) { $response->statusCode = 400; return [ @@ -584,7 +590,7 @@ class ForumTopicsRoutes implements RouteHandler, UrlSource { ]; } - $this->forum->topics->lockTopic($topic); + $this->forumCtx->topics->lockTopic($topic); $this->auditLog->createLog( $this->authInfo->userInfo, 'FORUM_TOPIC_LOCK', @@ -617,7 +623,7 @@ class ForumTopicsRoutes implements RouteHandler, UrlSource { } try { - $topic = $this->forum->topics->getTopic( + $topic = $this->forumCtx->topics->getTopic( topicId: $topicId, deleted: false, ); @@ -663,7 +669,7 @@ class ForumTopicsRoutes implements RouteHandler, UrlSource { ]; } - $category = $this->forum->categories->getCategory(topicInfo: $topic); + $category = $this->forumCtx->categories->getCategory(topicInfo: $topic); if($category->archived) { $response->statusCode = 400; return [ @@ -674,7 +680,7 @@ class ForumTopicsRoutes implements RouteHandler, UrlSource { ]; } - $this->forum->topics->unlockTopic($topic); + $this->forumCtx->topics->unlockTopic($topic); $this->auditLog->createLog( $this->authInfo->userInfo, 'FORUM_TOPIC_UNLOCK', diff --git a/src/Users/UserInfo.php b/src/Users/UserInfo.php index 95ecf190..ea95ab57 100644 --- a/src/Users/UserInfo.php +++ b/src/Users/UserInfo.php @@ -23,8 +23,6 @@ class UserInfo { public private(set) ?string $displayRoleId, public private(set) ?string $aboutBody, public private(set) TextFormat $aboutBodyFormat, - public private(set) ?string $signatureBody, - public private(set) TextFormat $signatureBodyFormat, public private(set) ?string $title, ) {} @@ -45,9 +43,7 @@ class UserInfo { displayRoleId: $result->getStringOrNull(12), aboutBody: $result->getStringOrNull(13), aboutBodyFormat: TextFormat::tryFrom($result->getString(14)) ?? TextFormat::Plain, - signatureBody: $result->getStringOrNull(15), - signatureBodyFormat: TextFormat::tryFrom($result->getString(16)) ?? TextFormat::Plain, - title: $result->getString(17), + title: $result->getString(15), ); } @@ -98,16 +94,4 @@ class UserInfo { public bool $isAboutBodyMarkdown { get => $this->aboutBodyFormat === TextFormat::Markdown; } - - public bool $isSignatureBodyPlain { - get => $this->signatureBodyFormat === TextFormat::Plain; - } - - public bool $isSignatureBodyBBCode { - get => $this->signatureBodyFormat === TextFormat::BBCode; - } - - public bool $isSignatureBodyMarkdown { - get => $this->signatureBodyFormat === TextFormat::Markdown; - } } diff --git a/src/Users/UsersData.php b/src/Users/UsersData.php index 45f58e7e..649ff7a0 100644 --- a/src/Users/UsersData.php +++ b/src/Users/UsersData.php @@ -26,7 +26,6 @@ class UsersData { public const PASSWORD_UNIQUE = 6; public const PROFILE_ABOUT_MAX_LENGTH = 50000; - public const FORUM_SIGNATURE_MAX_LENGTH = 2000; public static function passwordHash(string $password): string { return password_hash($password, self::PASSWORD_ALGO, self::PASSWORD_OPTS); @@ -178,7 +177,6 @@ class UsersData { UNIX_TIMESTAMP(u.user_deleted), u.user_display_role_id, u.user_about_content, u.user_about_content_format, - u.user_signature_content, u.user_signature_content_format, u.user_title FROM msz_users AS u SQL; @@ -287,7 +285,6 @@ class UsersData { UNIX_TIMESTAMP(user_deleted), user_display_role_id, user_about_content, user_about_content_format, - user_signature_content, user_signature_content_format, user_title FROM msz_users SQL; @@ -359,8 +356,6 @@ class UsersData { RoleInfo|string|null $displayRoleInfo = null, ?string $aboutBody = null, TextFormat|string|null $aboutBodyFormat = null, - ?string $signatureBody = null, - TextFormat|string|null $signatureBodyFormat = null, ?string $title = null ): void { if($userInfo instanceof UserInfo) @@ -419,18 +414,6 @@ class UsersData { $values[] = $aboutBodyFormat->value; } - if($signatureBody !== null && $signatureBodyFormat !== null) { - if(is_string($signatureBodyFormat)) - $signatureBodyFormat = TextFormat::tryFrom($signatureBodyFormat) ?? null; - if(self::validateForumSignature($signatureBodyFormat, $signatureBody) !== '') - throw new InvalidArgumentException('$signatureBody and $signatureBodyFormat contain invalid data!'); - - $fields[] = 'user_signature_content = ?'; - $values[] = $signatureBody; - $fields[] = 'user_signature_content_format = ?'; - $values[] = $signatureBodyFormat->value; - } - if($title !== null) { $fields[] = 'user_title = ?'; $values[] = $title; @@ -726,24 +709,4 @@ class UsersData { default => 'Your profile about section is not acceptable.', }; } - - public static function validateForumSignature(?TextFormat $format, string $text): string { - if($format === null) - return 'parser'; - - $length = strlen($text); - if($length > self::FORUM_SIGNATURE_MAX_LENGTH) - return 'long'; - - return ''; - } - - public static function validateForumSignatureText(string $error): string { - return match($error) { - 'parser' => 'You attempted to select an invalid parser for your forum signature.', - 'long' => sprintf('Please keep the length of your forum signature below %d characters.', self::FORUM_SIGNATURE_MAX_LENGTH), - '' => 'Your forum signature is fine, why are you seeing this?', - default => 'Your forum signature is not acceptable.', - }; - } } diff --git a/templates/forum/macros.twig b/templates/forum/macros.twig index 49acd475..bf1c3ee7 100644 --- a/templates/forum/macros.twig +++ b/templates/forum/macros.twig @@ -482,8 +482,8 @@ {% set author_created = post.user.createdTime %} {% set author_posts_count = post.postsCount %} {% set author_is_op = post.isOriginalPoster %} - {% set signature_body = post.user.signatureBody|default('')|escape|parse_text(post.user.signatureBodyFormat) %} - {% set signature_is_markdown = post.user.isSignatureBodyMarkdown %} + {% set signature_body = post.signature.body|default('')|escape|parse_text(post.signature.bodyFormat|default('')) %} + {% set signature_is_markdown = post.signature.isBodyMarkdown|default(false) %} {% endif %} {% set viewer_is_author = has_author and user_id == author_id %} diff --git a/templates/profile/index.twig b/templates/profile/index.twig index 18cd786d..a5b0dc9b 100644 --- a/templates/profile/index.twig +++ b/templates/profile/index.twig @@ -276,18 +276,18 @@ </div> {% endif %} - {% if (not profile_is_banned or profile_can_edit) and ((profile_is_editing and perms.edit_signature) or profile_user.signatureBody is not empty) %} + {% if (not profile_is_banned or profile_can_edit) and ((profile_is_editing and perms.edit_signature) or profile_forum_signature_info is not null) %} <div class="container profile__container profile__signature" id="signature"> {{ container_title('Signature') }} {% if profile_is_editing %} <div class="profile__signature__editor"> - {{ input_select('signature[parser]', parser_options(), profile_user.signatureBodyFormat.value, '', '', false, 'profile__signature__select') }} - <textarea name="signature[text]" class="input__textarea profile__signature__text" id="signature-textarea">{{ profile_user.signatureBody }}</textarea> + {{ input_select('sig_format', parser_options(), profile_forum_signature_info.bodyFormat.value|default('bb'), '', '', false, 'profile__signature__select') }} + <textarea name="sig_body" class="input__textarea profile__signature__text" id="signature-textarea">{{ profile_forum_signature_info.body|default('') }}</textarea> </div> {% else %} - <div class="profile__signature__content{% if profile_is_editing %} profile__signature__content--edit{% elseif profile_user.isSignatureBodyMarkdown %} markdown{% endif %}"> - {{ profile_user.signatureBody|escape|parse_text(profile_user.signatureBodyFormat)|raw }} + <div class="profile__signature__content{% if profile_is_editing %} profile__signature__content--edit{% elseif profile_forum_signature_info.isBodyMarkdown %} markdown{% endif %}"> + {{ profile_forum_signature_info.body|escape|parse_text(profile_forum_signature_info.bodyFormat)|raw }} </div> {% endif %} </div>