Made data source argument lists for News, Changelog, Comments and Emotes consistent with the rest.

This commit is contained in:
flash 2023-08-05 13:50:15 +00:00
parent 87915b6a25
commit d4f6990e8a
27 changed files with 334 additions and 433 deletions

View File

@ -38,13 +38,13 @@ $commentVote = (int)filter_input(INPUT_GET, 'v', FILTER_SANITIZE_NUMBER_INT);
if(!empty($commentId)) {
try {
$commentInfo = $comments->getPostById($commentId);
$commentInfo = $comments->getPost($commentId);
} catch(RuntimeException $ex) {
echo render_info('Post not found.', 404);
return;
}
$categoryInfo = $comments->getCategoryByPost($commentInfo);
$categoryInfo = $comments->getCategory(postInfo: $commentInfo);
}
if($commentMode !== 'create' && empty($commentInfo)) {
@ -186,7 +186,7 @@ switch($commentMode) {
$categoryId = isset($_POST['comment']['category']) && is_string($_POST['comment']['category'])
? (int)$_POST['comment']['category']
: 0;
$categoryInfo = $comments->getCategoryById($categoryId);
$categoryInfo = $comments->getCategory(categoryId: $categoryId);
} catch(RuntimeException $ex) {
echo render_info('This comment category doesn\'t exist.', 404);
break;
@ -227,7 +227,7 @@ switch($commentMode) {
if($commentReply > 0) {
try {
$parentInfo = $comments->getPostById($commentReply);
$parentInfo = $comments->getPost($commentReply);
} catch(RuntimeException $ex) {}
if(!isset($parentInfo) || $parentInfo->isDeleted()) {

View File

@ -4,6 +4,7 @@ namespace Misuzu;
use DateTimeInterface;
use RuntimeException;
use Index\DateTime;
use Index\XArray;
use Misuzu\Changelog\Changelog;
if(!$msz->isLoggedIn() || !perms_check_user(MSZ_PERMS_CHANGELOG, $msz->getActiveUser()->getId(), MSZ_PERM_CHANGELOG_MANAGE_CHANGES)) {
@ -17,15 +18,17 @@ foreach(Changelog::ACTIONS as $action)
$changelog = $msz->getChangelog();
$changeId = (string)filter_input(INPUT_GET, 'c', FILTER_SANITIZE_NUMBER_INT);
$loadChangeInfo = fn() => $changelog->getChangeById($changeId, withTags: true);
$changeTags = $changelog->getAllTags();
$changeInfo = null;
$changeTagIds = [];
$tagInfos = $changelog->getTags();
if(empty($changeId))
$isNew = true;
else
try {
$isNew = false;
$changeInfo = $loadChangeInfo();
$changeInfo = $changelog->getChange($changeId);
$changeTagIds = XArray::select($changelog->getTags(changeInfo: $changeInfo), fn($tagInfo) => $tagInfo->getId());
} catch(RuntimeException $ex) {
echo render_error(404);
return;
@ -78,7 +81,7 @@ while($_SERVER['REQUEST_METHOD'] === 'POST' && CSRF::validateRequest()) {
}
if(!empty($tags)) {
$tCurrent = $changeInfo->getTagIds();
$tCurrent = $changeTagIds;
$tApply = $tags;
$tRemove = [];
@ -102,17 +105,15 @@ while($_SERVER['REQUEST_METHOD'] === 'POST' && CSRF::validateRequest()) {
[$changeInfo->getId()]
);
if($isNew) {
url_redirect('manage-changelog-change', ['change' => $changeInfo->getId()]);
return;
} else $changeInfo = $loadChangeInfo();
break;
url_redirect('manage-changelog-change', ['change' => $changeInfo->getId()]);
return;
}
Template::render('manage.changelog.change', [
'change_new' => $isNew,
'change_info' => $changeInfo ?? null,
'change_tags' => $changeTags,
'change_info' => $changeInfo,
'change_info_tags' => $changeTagIds,
'change_tags' => $tagInfos,
'change_actions' => $changeActions,
'change_author_id' => $msz->getActiveUser()->getId(),
]);

View File

@ -9,14 +9,14 @@ if(!$msz->isLoggedIn() || !perms_check_user(MSZ_PERMS_CHANGELOG, $msz->getActive
}
$changelog = $msz->getChangelog();
$changelogPagination = new Pagination($changelog->countAllChanges(), 30);
$changelogPagination = new Pagination($changelog->countChanges(), 30);
if(!$changelogPagination->hasValidOffset()) {
echo render_error(404);
return;
}
$changeInfos = $changelog->getAllChanges(withTags: true, pagination: $changelogPagination);
$changeInfos = $changelog->getChanges(pagination: $changelogPagination);
$changes = [];
$userInfos = [];
$userColours = [];
@ -39,6 +39,7 @@ foreach($changeInfos as $changeInfo) {
$changes[] = [
'change' => $changeInfo,
'tags' => $changelog->getTags(changeInfo: $changeInfo),
'user' => $userInfo,
'user_colour' => $userColours[$userId] ?? \Index\Colour\Colour::none(),
];

View File

@ -10,7 +10,7 @@ if(!$msz->isLoggedIn() || !perms_check_user(MSZ_PERMS_CHANGELOG, $msz->getActive
$changelog = $msz->getChangelog();
$tagId = (string)filter_input(INPUT_GET, 't', FILTER_SANITIZE_NUMBER_INT);
$loadTagInfo = fn() => $changelog->getTagById($tagId);
$loadTagInfo = fn() => $changelog->getTag($tagId);
if(empty($tagId))
$isNew = true;

View File

@ -7,5 +7,5 @@ if(!$msz->isLoggedIn() || !perms_check_user(MSZ_PERMS_CHANGELOG, $msz->getActive
}
Template::render('manage.changelog.tags', [
'changelog_tags' => $msz->getChangelog()->getAllTags(),
'changelog_tags' => $msz->getChangelog()->getTags(),
]);

View File

@ -2,6 +2,7 @@
namespace Misuzu;
use RuntimeException;
use Index\XArray;
if(!$msz->isLoggedIn() || !perms_check_user(MSZ_PERMS_GENERAL, $msz->getActiveUser()->getId(), MSZ_PERM_GENERAL_MANAGE_EMOTES)) {
echo render_error(403);
@ -10,14 +11,14 @@ if(!$msz->isLoggedIn() || !perms_check_user(MSZ_PERMS_GENERAL, $msz->getActiveUs
$emotes = $msz->getEmotes();
$emoteId = (string)filter_input(INPUT_GET, 'e', FILTER_SANITIZE_NUMBER_INT);
$loadEmoteInfo = fn() => $emotes->getEmoteById($emoteId, true);
if(empty($emoteId))
$isNew = true;
else
try {
$isNew = false;
$emoteInfo = $loadEmoteInfo();
$emoteInfo = $emotes->getEmote($emoteId);
$emoteStrings = $emotes->getEmoteStrings($emoteInfo);
} catch(RuntimeException $ex) {
echo render_error(404);
return;
@ -60,7 +61,7 @@ while($_SERVER['REQUEST_METHOD'] === 'POST' && CSRF::validateRequest()) {
$emotes->updateEmote($emoteInfo, $order, $minRank, $url);
}
$sCurrent = $emoteInfo->getStringsRaw();
$sCurrent = XArray::select($emoteStrings, fn($stringInfo) => $stringInfo->getString());
$sApply = $strings;
$sRemove = [];
@ -97,14 +98,12 @@ while($_SERVER['REQUEST_METHOD'] === 'POST' && CSRF::validateRequest()) {
[$emoteInfo->getId()]
);
if($isNew) {
url_redirect('manage-general-emoticon', ['emote' => $emoteInfo->getId()]);
return;
} else $emoteInfo = $loadEmoteInfo();
break;
url_redirect('manage-general-emoticon', ['emote' => $emoteInfo->getId()]);
return;
}
Template::render('manage.general.emoticon', [
'emote_new' => $isNew,
'emote_info' => $emoteInfo ?? null,
'emote_strings' => $emoteStrings ?? [],
]);

View File

@ -14,7 +14,7 @@ if(CSRF::validateRequest() && !empty($_GET['emote'])) {
$emoteId = (string)filter_input(INPUT_GET, 'emote', FILTER_SANITIZE_NUMBER_INT);
try {
$emoteInfo = $emotes->getEmoteById($emoteId);
$emoteInfo = $emotes->getEmote($emoteId);
} catch(RuntimeException $ex) {
echo render_error(404);
return;
@ -45,5 +45,5 @@ if(CSRF::validateRequest() && !empty($_GET['emote'])) {
}
Template::render('manage.general.emoticons', [
'emotes' => $emotes->getAllEmotes(),
'emotes' => $emotes->getEmotes(),
]);

View File

@ -7,14 +7,14 @@ if(!$msz->isLoggedIn() || !perms_check_user(MSZ_PERMS_NEWS, $msz->getActiveUser(
}
$news = $msz->getNews();
$pagination = new Pagination($news->countAllCategories(true), 15);
$pagination = new Pagination($news->countCategories(), 15);
if(!$pagination->hasValidOffset()) {
echo render_error(404);
return;
}
$categories = $news->getAllCategories(true, $pagination);
$categories = $news->getCategories(pagination: $pagination);
Template::render('manage.news.categories', [
'news_categories' => $categories,

View File

@ -10,7 +10,7 @@ if(!$msz->isLoggedIn() || !perms_check_user(MSZ_PERMS_NEWS, $msz->getActiveUser(
$news = $msz->getNews();
$categoryId = (string)filter_input(INPUT_GET, 'c', FILTER_SANITIZE_NUMBER_INT);
$loadCategoryInfo = fn() => $news->getCategoryById($categoryId);
$loadCategoryInfo = fn() => $news->getCategory(categoryId: $categoryId);
if(empty($categoryId))
$isNew = true;

View File

@ -10,7 +10,7 @@ if(!$msz->isLoggedIn() || !perms_check_user(MSZ_PERMS_NEWS, $msz->getActiveUser(
$news = $msz->getNews();
$postId = (string)filter_input(INPUT_GET, 'p', FILTER_SANITIZE_NUMBER_INT);
$loadPostInfo = fn() => $news->getPostById($postId);
$loadPostInfo = fn() => $news->getPost($postId);
if(empty($postId))
$isNew = true;
@ -71,7 +71,7 @@ while($_SERVER['REQUEST_METHOD'] === 'POST' && CSRF::validateRequest()) {
}
$categories = [];
foreach($news->getAllCategories(true) as $categoryInfo)
foreach($news->getCategories() as $categoryInfo)
$categories[$categoryInfo->getId()] = $categoryInfo->getName();
Template::render('manage.news.post', [

View File

@ -7,7 +7,7 @@ if(!$msz->isLoggedIn() || !perms_check_user(MSZ_PERMS_NEWS, $msz->getActiveUser(
}
$news = $msz->getNews();
$pagination = new Pagination($news->countAllPosts(
$pagination = new Pagination($news->countPosts(
includeScheduled: true,
includeDeleted: true
), 15);

View File

@ -20,7 +20,7 @@ if(!empty($searchQuery)) {
$users = $msz->getUsers();
$comments = $msz->getComments();
$newsPosts = [];
$newsPostInfos = $news->getPostsBySearchQuery($searchQuery);
$newsPostInfos = $news->getPosts(searchQuery: $searchQuery);
$newsUserInfos = [];
$newsUserColours = [];
$newsCategoryInfos = [];
@ -45,10 +45,10 @@ if(!empty($searchQuery)) {
if(array_key_exists($categoryId, $newsCategoryInfos))
$categoryInfo = $newsCategoryInfos[$categoryId];
else
$newsCategoryInfos[$categoryId] = $categoryInfo = $news->getCategoryByPost($postInfo);
$newsCategoryInfos[$categoryId] = $categoryInfo = $news->getCategory(postInfo: $postInfo);
$commentsCount = $postInfo->hasCommentsCategoryId()
? $comments->countPosts($postInfo->getCommentsCategoryId(), includeReplies: true) : 0;
? $comments->countPosts(categoryInfo: $postInfo->getCommentsCategoryId(), deleted: false) : 0;
$newsPosts[] = [
'post' => $postInfo,

View File

@ -11,16 +11,14 @@ class ChangeInfo {
private int $created;
private string $summary;
private string $body;
private array $tags;
public function __construct(IDbResult $result, array $tags = []) {
public function __construct(IDbResult $result) {
$this->id = (string)$result->getInteger(0);
$this->userId = $result->isNull(1) ? null : (string)$result->getInteger(1);
$this->action = $result->getInteger(2);
$this->created = $result->getInteger(3);
$this->summary = $result->getString(4);
$this->body = $result->getString(5);
$this->tags = $tags;
}
public function getId(): string {
@ -70,19 +68,4 @@ class ChangeInfo {
public function getCommentsCategoryName(): string {
return sprintf('changelog-date-%s', $this->getDate());
}
public function getTags(): array {
return $this->tags;
}
public function getTagIds(): array {
$ids = [];
foreach($this->tags as $tagInfo)
$ids[] = $tagInfo->getId();
return $ids;
}
public function hasTag(ChangeTagInfo|string $infoOrId): bool {
return in_array($infoOrId, $this->tags);
}
}

View File

@ -64,38 +64,7 @@ class Changelog {
};
}
private function readChanges(IDbResult $result, bool $withTags): array {
$changes = [];
if($withTags) {
while($result->next())
$changes[] = new ChangeInfo(
$result,
$this->getTagsByChange((string)$result->getInteger(0))
);
} else {
while($result->next())
$changes[] = new ChangeInfo($result);
}
return $changes;
}
private function readTags(IDbResult $result): array {
$tags = [];
while($result->next()) {
$tagId = (string)$result->getInteger(0);
if(array_key_exists($tagId, $this->tags))
$tags[] = $this->tags[$tagId];
else
$tags[] = $this->tags[$tagId] = new ChangeTagInfo($result);
}
return $tags;
}
public function countAllChanges(
public function countChanges(
UserInfo|string|null $userInfo = null,
DateTime|int|null $dateTime = null,
?array $tags = null
@ -147,8 +116,7 @@ class Changelog {
return $count;
}
public function getAllChanges(
bool $withTags = false,
public function getChanges(
UserInfo|string|null $userInfo = null,
DateTime|int|null $dateTime = null,
?array $tags = null,
@ -201,10 +169,16 @@ class Changelog {
$stmt->execute();
return self::readChanges($stmt->getResult(), $withTags);
$result = $stmt->getResult();
$changes = [];
while($result->next())
$changes[] = new ChangeInfo($result);
return $changes;
}
public function getChangeById(string $changeId, bool $withTags = false): ChangeInfo {
public function getChange(string $changeId): ChangeInfo {
$stmt = $this->cache->get('SELECT change_id, user_id, change_action, UNIX_TIMESTAMP(change_created), change_log, change_text FROM msz_changelog_changes WHERE change_id = ?');
$stmt->addParameter(1, $changeId);
$stmt->execute();
@ -213,11 +187,7 @@ class Changelog {
if(!$result->next())
throw new RuntimeException('No tag with that ID exists.');
$tags = [];
if($withTags)
$tags = $this->getTagsByChange((string)$result->getInteger(0));
return new ChangeInfo($result, $tags);
return new ChangeInfo($result);
}
public function createChange(
@ -250,7 +220,7 @@ class Changelog {
$stmt->addParameter(5, $body);
$stmt->execute();
return $this->getChangeById((string)$this->dbConn->getLastInsertId());
return $this->getChange((string)$this->dbConn->getLastInsertId());
}
public function deleteChange(ChangeInfo|string $infoOrId): void {
@ -306,25 +276,38 @@ class Changelog {
$stmt->execute();
}
public function getAllTags(): array {
// only putting the changes count in here for now, it is only used in manage
return $this->readTags(
$this->dbConn->query('SELECT tag_id, tag_name, tag_description, UNIX_TIMESTAMP(tag_created), UNIX_TIMESTAMP(tag_archived), (SELECT COUNT(*) FROM msz_changelog_change_tags AS ct WHERE ct.tag_id = t.tag_id) AS `tag_changes` FROM msz_changelog_tags AS t')
);
}
public function getTags(
ChangeInfo|string|null $changeInfo = null
): array {
if($changeInfo instanceof ChangeInfo)
$changeInfo = $changeInfo->getId();
public function getTagsByChange(ChangeInfo|string $infoOrId): array {
if($infoOrId instanceof ChangeInfo)
$infoOrId = $infoOrId->getId();
$hasChangeInfo = $changeInfo !== null;
$stmt = $this->cache->get('SELECT tag_id, tag_name, tag_description, UNIX_TIMESTAMP(tag_created), UNIX_TIMESTAMP(tag_archived), 0 AS `tag_changes` FROM msz_changelog_tags WHERE tag_id IN (SELECT tag_id FROM msz_changelog_change_tags WHERE change_id = ?)');
$stmt->addParameter(1, $infoOrId);
$query = 'SELECT tag_id, tag_name, tag_description, UNIX_TIMESTAMP(tag_created), UNIX_TIMESTAMP(tag_archived), (SELECT COUNT(*) FROM msz_changelog_change_tags AS ct WHERE ct.tag_id = t.tag_id) AS tag_changes FROM msz_changelog_tags AS t';
if($hasChangeInfo)
$query .= ' WHERE tag_id IN (SELECT tag_id FROM msz_changelog_change_tags WHERE change_id = ?)';
$stmt = $this->cache->get($query);
if($hasChangeInfo)
$stmt->addParameter(1, $changeInfo);
$stmt->execute();
return $this->readTags($stmt->getResult());
$result = $stmt->getResult();
$tags = [];
while($result->next()) {
$tagId = (string)$result->getInteger(0);
if(array_key_exists($tagId, $this->tags))
$tags[] = $this->tags[$tagId];
else
$tags[] = $this->tags[$tagId] = new ChangeTagInfo($result);
}
return $tags;
}
public function getTagById(string $tagId): ChangeTagInfo {
public function getTag(string $tagId): ChangeTagInfo {
$stmt = $this->cache->get('SELECT tag_id, tag_name, tag_description, UNIX_TIMESTAMP(tag_created), UNIX_TIMESTAMP(tag_archived), 0 AS `tag_changes` FROM msz_changelog_tags WHERE tag_id = ?');
$stmt->addParameter(1, $tagId);
$stmt->execute();
@ -355,7 +338,7 @@ class Changelog {
$stmt->addParameter(3, $archived ? 1 : 0);
$stmt->execute();
return $this->getTagById((string)$this->dbConn->getLastInsertId());
return $this->getTag((string)$this->dbConn->getLastInsertId());
}
public function deleteTag(ChangeTagInfo|string $infoOrId): void {

View File

@ -96,12 +96,12 @@ final class ChangelogRoutes {
$tag = trim($tag);
}
$count = $this->changelog->countAllChanges($filterUser, $filterDate, $filterTags);
$count = $this->changelog->countChanges($filterUser, $filterDate, $filterTags);
$pagination = new Pagination($count, 30);
if(!$pagination->hasValidOffset())
return 404;
$changeInfos = $this->changelog->getAllChanges(userInfo: $filterUser, dateTime: $filterDate, tags: $filterTags, pagination: $pagination);
$changeInfos = $this->changelog->getChanges(userInfo: $filterUser, dateTime: $filterDate, tags: $filterTags, pagination: $pagination);
if(empty($changeInfos))
return 404;
@ -145,11 +145,13 @@ final class ChangelogRoutes {
public function getChange($response, $request, string $changeId) {
try {
$changeInfo = $this->changelog->getChangeById($changeId, withTags: true);
$changeInfo = $this->changelog->getChange($changeId);
} catch(RuntimeException $ex) {
return 404;
}
$tagInfos = $this->changelog->getTags(changeInfo: $changeInfo);
try {
$userInfo = $this->users->getUser($changeInfo->getUserId(), 'id');
$userColour = $this->users->getUserColour($userInfo);
@ -160,6 +162,7 @@ final class ChangelogRoutes {
return Template::renderRaw('changelog.change', [
'change_info' => $changeInfo,
'change_tags' => $tagInfos,
'change_user_info' => $userInfo,
'change_user_colour' => $userColour,
'comments_info' => $this->getCommentsInfo($changeInfo->getCommentsCategoryName()),
@ -168,7 +171,7 @@ final class ChangelogRoutes {
private function createFeed(string $feedMode): Feed {
$siteName = $this->config->getString('site.name', 'Misuzu');
$changes = $this->changelog->getAllChanges(pagination: new Pagination(10));
$changes = $this->changelog->getChanges(pagination: new Pagination(10));
$feed = (new Feed)
->setTitle($siteName . ' » Changelog')

View File

@ -18,7 +18,9 @@ class Comments {
$this->cache = new DbStatementCache($dbConn);
}
public function countAllCategories(UserInfo|string|null $owner = null): int {
public function countCategories(
UserInfo|string|null $owner = null
): int {
if($owner instanceof UserInfo)
$owner = $owner->getId();
@ -79,48 +81,48 @@ class Comments {
return $categories;
}
public function getCategoryByName(string $name): CommentsCategoryInfo {
$stmt = $this->cache->get('SELECT category_id, category_name, owner_id, UNIX_TIMESTAMP(category_created), UNIX_TIMESTAMP(category_locked), (SELECT COUNT(*) FROM msz_comments_posts AS cp WHERE cp.category_id = cc.category_id AND comment_deleted IS NULL) AS `category_comments` FROM msz_comments_categories AS cc WHERE category_name = ?');
$stmt->addParameter(1, $name);
$stmt->execute();
$result = $stmt->getResult();
public function getCategory(
?string $categoryId = null,
?string $name = null,
CommentsPostInfo|string|null $postInfo = null
): CommentsCategoryInfo {
$hasCategoryId = $categoryId !== null;
$hasName = $name !== null;
$hasPostInfo = $postInfo !== null;
if(!$result->next())
throw new RuntimeException('No category with this name found.');
if(!$hasCategoryId && !$hasName && !$hasPostInfo)
throw new InvalidArgumentException('At least one of the arguments must be set.');
// there has got to be a better way to do this
if(($hasCategoryId && ($hasName || $hasPostInfo)) || ($hasName && ($hasCategoryId || $hasPostInfo)) || ($hasPostInfo && ($hasCategoryId || $hasName)))
throw new InvalidArgumentException('Only one of the arguments may be specified.');
return new CommentsCategoryInfo($result);
}
public function getCategoryById(string $id): CommentsCategoryInfo {
$stmt = $this->cache->get('SELECT category_id, category_name, owner_id, UNIX_TIMESTAMP(category_created), UNIX_TIMESTAMP(category_locked), (SELECT COUNT(*) FROM msz_comments_posts AS cp WHERE cp.category_id = cc.category_id AND comment_deleted IS NULL) AS `category_comments` FROM msz_comments_categories AS cc WHERE category_id = ?');
$stmt->addParameter(1, $id);
$stmt->execute();
$result = $stmt->getResult();
if(!$result->next())
throw new RuntimeException('No category with this ID found.');
return new CommentsCategoryInfo($result);
}
public function getCategoryByPost(CommentsPostInfo|string $infoOrId): CommentsCategoryInfo {
$query = 'SELECT category_id, category_name, owner_id, UNIX_TIMESTAMP(category_created), UNIX_TIMESTAMP(category_locked), (SELECT COUNT(*) FROM msz_comments_posts AS cp WHERE cp.category_id = cc.category_id AND comment_deleted IS NULL) AS `category_comments` FROM msz_comments_categories AS cc WHERE category_id = ';
if($infoOrId instanceof CommentsPostInfo) {
$query .= '?';
$param = $infoOrId->getCategoryId();
} else {
$query .= '(SELECT category_id FROM msz_comments_posts WHERE comment_id = ?)';
$param = $infoOrId;
$query = 'SELECT category_id, category_name, owner_id, UNIX_TIMESTAMP(category_created), UNIX_TIMESTAMP(category_locked), (SELECT COUNT(*) FROM msz_comments_posts AS cp WHERE cp.category_id = cc.category_id AND comment_deleted IS NULL) AS category_comments FROM msz_comments_categories AS cc';
$value = null;
if($hasCategoryId) {
$query .= ' WHERE category_id = ?';
$value = $categoryId;
}
if($hasName) {
$query .= ' WHERE category_name = ?';
$value = $name;
}
if($hasPostInfo) {
if($postInfo instanceof CommentsPostInfo) {
$query .= ' WHERE category_id = ?';
$value = $postInfo->getCategoryId();
} else {
$query .= ' WHERE category_id = (SELECT category_id FROM msz_comments_posts WHERE comment_id = ?)';
$value = $postInfo;
}
}
$stmt = $this->cache->get($query);
$stmt->addParameter(1, $param);
$stmt->addParameter(1, $value);
$stmt->execute();
$result = $stmt->getResult();
if(!$result->next())
throw new RuntimeException('No category belonging to this post found.');
throw new RuntimeException('Comments category not found.');
return new CommentsCategoryInfo($result);
}
@ -141,7 +143,7 @@ class Comments {
public function ensureCategory(string $name, UserInfo|string|null $owner = null): CommentsCategoryInfo {
if($this->checkCategoryNameExists($name))
return $this->getCategoryByName($name);
return $this->getCategory(name: $name);
return $this->createCategory($name, $owner);
}
@ -158,7 +160,7 @@ class Comments {
$stmt->addParameter(2, $owner);
$stmt->execute();
return $this->getCategoryById((string)$this->dbConn->getLastInsertId());
return $this->getCategory(categoryId: (string)$this->dbConn->getLastInsertId());
}
public function deleteCategory(CommentsCategoryInfo|string $category): void {
@ -214,48 +216,41 @@ class Comments {
}
public function countPosts(
CommentsCategoryInfo|string|null $category = null,
CommentsPostInfo|string|null $parent = null,
bool $includeReplies = false,
bool $includeDeleted = false
CommentsCategoryInfo|string|null $categoryInfo = null,
CommentsPostInfo|string|null $parentInfo = null,
?bool $replies = null,
?bool $deleted = null
): int {
if($category instanceof CommentsCategoryInfo)
$category = $category->getId();
if($parent instanceof CommentsPostInfo)
$parent = $parent->getId();
if($categoryInfo instanceof CommentsCategoryInfo)
$categoryInfo = $categoryInfo->getId();
if($parentInfo instanceof CommentsPostInfo)
$parentInfo = $parentInfo->getId();
$hasCategory = $category !== null;
$hasParent = $parent !== null;
$hasCategoryInfo = $categoryInfo !== null;
$hasParentInfo = $parentInfo !== null;
$hasReplies = $replies !== null;
$hasDeleted = $deleted !== null;
$args = 0;
$query = 'SELECT COUNT(*) FROM msz_comments_posts';
if($hasParent) {
if($hasParentInfo) {
++$args;
$query .= ' WHERE comment_reply_to = ?';
} else {
if($hasCategory) {
++$args;
$query .= ' WHERE category_id = ?';
}
if(!$includeReplies) {
$query .= (++$args > 1 ? ' AND' : ' WHERE');
$query .= ' comment_reply_to IS NULL';
}
}
if(!$includeDeleted) {
$query .= (++$args > 1 ? ' AND' : ' WHERE');
$query .= ' comment_deleted IS NULL';
}
if($hasCategoryInfo)
$query .= sprintf(' %s category_id = ?', ++$args > 1 ? 'AND' : 'WHERE');
if($hasReplies)
$query .= sprintf(' %s comment_reply_to %s NULL', ++$args > 1 ? 'AND' : 'WHERE', $replies ? 'IS NOT' : 'IS');
if($hasDeleted)
$query .= sprintf(' %s comment_deleted %s NULL', ++$args > 1 ? 'AND' : 'WHERE', $deleted ? 'IS NOT' : 'IS');
$args = 0;
$stmt = $this->cache->get($query);
if($hasParent)
$stmt->addParameter(++$args, $parent);
elseif($hasCategory)
$stmt->addParameter(++$args, $category);
if($hasParentInfo)
$stmt->addParameter(++$args, $parentInfo);
elseif($hasCategoryInfo)
$stmt->addParameter(++$args, $categoryInfo);
$stmt->execute();
$result = $stmt->getResult();
@ -268,20 +263,22 @@ class Comments {
}
public function getPosts(
CommentsCategoryInfo|string|null $category = null,
CommentsPostInfo|string|null $parent = null,
bool $includeReplies = false,
bool $includeDeleted = false,
CommentsCategoryInfo|string|null $categoryInfo = null,
CommentsPostInfo|string|null $parentInfo = null,
?bool $replies = null,
?bool $deleted = null,
bool $includeRepliesCount = false,
bool $includeVotesCount = false
): array {
if($category instanceof CommentsCategoryInfo)
$category = $category->getId();
if($parent instanceof CommentsPostInfo)
$parent = $parent->getId();
if($categoryInfo instanceof CommentsCategoryInfo)
$categoryInfo = $categoryInfo->getId();
if($parentInfo instanceof CommentsPostInfo)
$parentInfo = $parentInfo->getId();
$hasCategory = $category !== null;
$hasParent = $parent !== null;
$hasCategoryInfo = $categoryInfo !== null;
$hasParentInfo = $parentInfo !== null;
$hasReplies = $replies !== null;
$hasDeleted = $deleted !== null;
$args = 0;
$query = 'SELECT comment_id, category_id, user_id, comment_reply_to, comment_text, UNIX_TIMESTAMP(comment_created), UNIX_TIMESTAMP(comment_pinned), UNIX_TIMESTAMP(comment_edited), UNIX_TIMESTAMP(comment_deleted)';
@ -294,40 +291,31 @@ class Comments {
}
$query .= ' FROM msz_comments_posts AS cpp';
if($hasParent) {
if($hasParentInfo) {
++$args;
$query .= ' WHERE comment_reply_to = ?';
} else {
if($hasCategory) {
++$args;
$query .= ' WHERE category_id = ?';
}
if(!$includeReplies) {
$query .= (++$args > 1 ? ' AND' : ' WHERE');
$query .= ' comment_reply_to IS NULL';
}
}
if($hasCategoryInfo)
$query .= sprintf(' %s category_id = ?', ++$args > 1 ? 'AND' : 'WHERE');
if($hasReplies)
$query .= sprintf(' %s comment_reply_to %s NULL', ++$args > 1 ? 'AND' : 'WHERE', $replies ? 'IS NOT' : 'IS');
if($hasDeleted)
$query .= sprintf(' %s comment_deleted %s NULL', ++$args > 1 ? 'AND' : 'WHERE', $deleted ? 'IS NOT' : 'IS');
if(!$includeDeleted) {
$query .= (++$args > 1 ? ' AND' : ' WHERE');
$query .= ' comment_deleted IS NULL';
}
// this should probably not be implicit like this
if($hasParent)
// this should really not be implicit like this
if($hasParentInfo)
$query .= ' ORDER BY comment_deleted ASC, comment_pinned DESC, comment_created ASC';
elseif($hasCategory)
elseif($hasCategoryInfo)
$query .= ' ORDER BY comment_deleted ASC, comment_pinned DESC, comment_created DESC';
else
$query .= ' ORDER BY comment_created DESC';
$args = 0;
$stmt = $this->cache->get($query);
if($hasParent)
$stmt->addParameter(++$args, $parent);
elseif($hasCategory)
$stmt->addParameter(++$args, $category);
if($hasParentInfo)
$stmt->addParameter(++$args, $parentInfo);
elseif($hasCategoryInfo)
$stmt->addParameter(++$args, $categoryInfo);
$stmt->execute();
$posts = [];
@ -339,7 +327,7 @@ class Comments {
return $posts;
}
public function getPostById(
public function getPost(
string $postId,
bool $includeRepliesCount = false,
bool $includeVotesCount = false
@ -396,7 +384,7 @@ class Comments {
$stmt->addParameter(5, $pin ? 1 : 0);
$stmt->execute();
return $this->getPostById((string)$this->dbConn->getLastInsertId());
return $this->getPost((string)$this->dbConn->getLastInsertId());
}
public function deletePost(CommentsPostInfo|string $infoOrId): void {

View File

@ -28,7 +28,7 @@ class CommentsEx {
$info->category = $category;
$info->posts = [];
$root = $this->comments->getPosts($category, includeRepliesCount: true, includeVotesCount: true, includeDeleted: true);
$root = $this->comments->getPosts($category, includeRepliesCount: true, includeVotesCount: true, replies: false);
foreach($root as $postInfo)
$info->posts[] = $this->decorateComment($postInfo);
@ -65,7 +65,7 @@ class CommentsEx {
$info->vote = $this->comments->getPostVote($postInfo, $userInfo);
$info->replies = [];
$root = $this->comments->getPosts(parent: $postInfo, includeRepliesCount: true, includeVotesCount: true, includeDeleted: true);
$root = $this->comments->getPosts(parentInfo: $postInfo, includeRepliesCount: true, includeVotesCount: true);
foreach($root as $childInfo)
$info->replies[] = $this->decorateComment($childInfo);

View File

@ -9,14 +9,12 @@ class EmoteInfo implements Stringable {
private int $order;
private int $rank;
private string $url;
private array $strings;
public function __construct(IDbResult $result, array $strings = []) {
public function __construct(IDbResult $result) {
$this->id = (string)$result->getInteger(0);
$this->order = $result->getInteger(1);
$this->rank = $result->getInteger(2);
$this->url = $result->getString(3);
$this->strings = $strings;
}
public function getId(): string {
@ -35,17 +33,6 @@ class EmoteInfo implements Stringable {
return $this->url;
}
public function getStrings(): array {
return $this->strings;
}
public function getStringsRaw(): array {
$strings = [];
foreach($this->strings as $info)
$strings[] = $info->getString();
return $strings;
}
public function __toString(): string {
return $this->url;
}

View File

@ -21,18 +21,17 @@ class Emotes {
$this->cache = new DbStatementCache($dbConn);
}
public function getEmoteById(string $emoteId, bool $withStrings = false): EmoteInfo {
public function getEmote(string $emoteId): EmoteInfo {
$stmt = $this->cache->get('SELECT emote_id, emote_order, emote_hierarchy, emote_url FROM msz_emoticons WHERE emote_id = ?');
$stmt->addParameter(1, $emoteId);
$stmt->execute();
$result = $stmt->getResult();
if(!$result->next())
throw new RuntimeException('No emoticon with that ID exists.');
$strings = $withStrings ? $this->getEmoteStrings($emoteId) : [];
return new EmoteInfo($result, $strings);
return new EmoteInfo($result);
}
public static function emoteOrderOptions(): array {
@ -40,32 +39,37 @@ class Emotes {
}
// TODO: pagination
public function getAllEmotes(
int $minRank = -1,
string $orderBy = '',
bool $desc = false,
bool $withStrings = false
public function getEmotes(
?int $minRank = null,
?string $orderBy = null,
?bool $reverse = null
): array {
if($minRank < 0) $minRank = PHP_INT_MAX;
$orderBy = self::EMOTE_ORDER[$orderBy] ?? self::EMOTE_ORDER[array_key_first(self::EMOTE_ORDER)];
$hasMinRank = $minRank !== null;
$hasOrderBy = $orderBy !== null;
$hasReverse = $reverse !== null;
$stmt = $this->cache->get(sprintf(
'SELECT emote_id, emote_order, emote_hierarchy, emote_url FROM msz_emoticons WHERE emote_hierarchy <= ? ORDER BY %s %s',
$orderBy, ($desc ? 'DESC' : 'ASC')
));
$stmt->addParameter(1, $minRank);
$query = 'SELECT emote_id, emote_order, emote_hierarchy, emote_url FROM msz_emoticons';
if($hasMinRank)
$query .= ' WHERE emote_hierarchy <= ?';
if($hasOrderBy) {
if(!array_key_exists($orderBy, self::EMOTE_ORDER))
throw new InvalidArgumentException('Invalid $orderBy specified.');
$query .= sprintf(' ORDER BY %s', self::EMOTE_ORDER[$orderBy]);
if($hasReverse)
$query .= $hasReverse ? ' DESC' : ' ASC';
}
$stmt = $this->cache->get($query);
if($hasMinRank)
$stmt->addParameter(1, $minRank);
$stmt->execute();
$emotes = [];
$result = $stmt->getResult();
if($withStrings) {
while($result->next())
$emotes[] = new EmoteInfo($result, $this->getEmoteStrings((string)$result->getInteger(0)));
} else {
while($result->next())
$emotes[] = new EmoteInfo($result);
}
while($result->next())
$emotes[] = new EmoteInfo($result);
return $emotes;
}
@ -106,7 +110,7 @@ class Emotes {
$stmt->addParameter(3, $order);
$stmt->execute();
return $this->getEmoteById((string)$this->dbConn->getLastInsertId());
return $this->getEmote((string)$this->dbConn->getLastInsertId());
}
public function deleteEmote(EmoteInfo|string $infoOrId): void {

View File

@ -79,7 +79,7 @@ class HomeRoutes {
private array $newsCategoryInfos = [];
private function getFeaturedNewsPosts(int $amount, bool $decorate): array {
$postInfos = $this->news->getAllPosts(
$postInfos = $this->news->getPosts(
onlyFeatured: true,
pagination: new Pagination($amount)
);
@ -112,10 +112,10 @@ class HomeRoutes {
if(array_key_exists($categoryId, $this->newsCategoryInfos))
$categoryInfo = $this->newsCategoryInfos[$categoryId];
else
$this->newsCategoryInfos[$categoryId] = $categoryInfo = $this->news->getCategoryByPost($postInfo);
$this->newsCategoryInfos[$categoryId] = $categoryInfo = $this->news->getCategory(postInfo: $postInfo);
$commentsCount = $postInfo->hasCommentsCategoryId()
? $this->comments->countPosts($postInfo->getCommentsCategoryId(), includeReplies: true) : 0;
? $this->comments->countPosts(categoryInfo: $postInfo->getCommentsCategoryId(), deleted: false) : 0;
$posts[] = [
'post' => $postInfo,
@ -205,7 +205,7 @@ class HomeRoutes {
$stats = $this->getStats();
$onlineUserInfos = $this->getOnlineUsers();
$featuredNews = $this->getFeaturedNewsPosts(5, true);
$changelog = $this->changelog->getAllChanges(pagination: new Pagination(10));
$changelog = $this->changelog->getChanges(pagination: new Pagination(10));
$stats['users:online:recent'] = count($onlineUserInfos);

View File

@ -20,15 +20,6 @@ class News {
$this->cache = new DbStatementCache($dbConn);
}
private function readCategories(IDbResult $result): array {
$categories = [];
while($result->next())
$categories[] = new NewsCategoryInfo($result);
return $categories;
}
private function readPosts(IDbResult $result): array {
$posts = [];
@ -38,10 +29,14 @@ class News {
return $posts;
}
public function countAllCategories(bool $includeHidden = false): int {
public function countCategories(
?bool $hidden = null
): int {
$hasHidden = $hidden !== null;
$query = 'SELECT COUNT(*) FROM msz_news_categories';
if($includeHidden)
$query .= ' WHERE category_is_hidden = 0';
if($hasHidden)
$query .= sprintf(' WHERE category_is_hidden %s 0', $hidden ? '<>' : '=');
$result = $this->dbConn->query($query);
$count = 0;
@ -52,15 +47,16 @@ class News {
return $count;
}
public function getAllCategories(
bool $includeHidden = false,
public function getCategories(
?bool $hidden = null,
?Pagination $pagination = null
): array {
$hasHidden = $hidden !== null;
$hasPagination = $pagination !== null;
$query = 'SELECT category_id, category_name, category_description, category_is_hidden, UNIX_TIMESTAMP(category_created), (SELECT COUNT(*) FROM msz_news_posts AS np WHERE np.category_id = nc.category_id) AS category_posts_count FROM msz_news_categories AS nc';
if(!$includeHidden)
$query .= ' WHERE category_is_hidden = 0';
if($hasHidden)
$query .= sprintf(' WHERE category_is_hidden %s 0', $hidden ? '<>' : '=');
$query .= ' ORDER BY category_created ASC';
if($hasPagination)
$query .= ' LIMIT ? OFFSET ?';
@ -74,39 +70,51 @@ class News {
$stmt->execute();
return self::readCategories($stmt->getResult());
$result = $stmt->getResult();
$categories = [];
while($result->next())
$categories[] = new NewsCategoryInfo($result);
return $categories;
}
public function getCategoryByPost(NewsPostInfo|string $postInfo): NewsCategoryInfo {
$query = 'SELECT category_id, category_name, category_description, category_is_hidden, UNIX_TIMESTAMP(category_created) FROM msz_news_categories WHERE category_id = ';
public function getCategory(
?string $categoryId = null,
NewsPostInfo|string|null $postInfo = null
): NewsCategoryInfo {
$hasCategoryId = $categoryId !== null;
$hasPostInfo = $postInfo !== null;
if($postInfo instanceof NewsPostInfo) {
$query .= '?';
$param = $postInfo->getCategoryId();
} else {
$query .= '(SELECT category_id FROM msz_news_posts WHERE post_id = ?)';
$param = $postInfo;
if(!$hasCategoryId && !$hasPostInfo)
throw new InvalidArgumentException('At least one argument must be specified.');
if($hasCategoryId && $hasPostInfo)
throw new InvalidArgumentException('Only one argument may be specified.');
$value = null;
$query = 'SELECT category_id, category_name, category_description, category_is_hidden, UNIX_TIMESTAMP(category_created) FROM msz_news_categories';
if($hasCategoryId) {
$query .= ' WHERE category_id = ?';
$value = $categoryId;
}
if($hasPostInfo) {
if($postInfo instanceof NewsPostInfo) {
$query .= ' WHERE category_id = ?';
$value = $postInfo->getCategoryId();
} else {
$query .= ' WHERE category_id = (SELECT category_id FROM msz_news_posts WHERE post_id = ?)';
$value = $postInfo;
}
}
$stmt = $this->cache->get($query);
$stmt->addParameter(1, $param);
$stmt->addParameter(1, $value);
$stmt->execute();
$result = $stmt->getResult();
if(!$result->next())
throw new RuntimeException('No news category associated with that ID exists.');
return new NewsCategoryInfo($result);
}
public function getCategoryById(string $categoryId): NewsCategoryInfo {
$stmt = $this->cache->get('SELECT category_id, category_name, category_description, category_is_hidden, UNIX_TIMESTAMP(category_created) FROM msz_news_categories WHERE category_id = ?');
$stmt->addParameter(1, $categoryId);
$stmt->execute();
$result = $stmt->getResult();
if(!$result->next())
throw new RuntimeException('No news category with that ID exists.');
throw new RuntimeException('News category not found.');
return new NewsCategoryInfo($result);
}
@ -130,7 +138,7 @@ class News {
$stmt->addParameter(3, $hidden ? 1 : 0);
$stmt->execute();
return $this->getCategoryById((string)$this->dbConn->getLastInsertId());
return $this->getCategory(categoryId: (string)$this->dbConn->getLastInsertId());
}
public function deleteCategory(NewsCategoryInfo|string $infoOrId): void {
@ -174,16 +182,26 @@ class News {
$stmt->execute();
}
public function countAllPosts(
public function countPosts(
NewsCategoryInfo|string|null $categoryInfo = null,
bool $onlyFeatured = false,
bool $includeScheduled = false,
bool $includeDeleted = false
): int {
if($categoryInfo instanceof NewsCategoryInfo)
$categoryInfo = $categoryInfo->getId();
$hasCategoryInfo = $categoryInfo !== null;
$args = 0;
$query = 'SELECT COUNT(*) FROM msz_news_posts';
if($onlyFeatured) {
if($hasCategoryInfo) {
++$args;
$query .= ' WHERE post_is_featured = 1';
$query .= ' WHERE category_id = ?';
}
if($onlyFeatured) {
$query .= (++$args > 1 ? ' AND' : ' WHERE');
$query .= ' post_is_featured = 1';
}
if(!$includeScheduled) {
$query .= (++$args > 1 ? ' AND' : ' WHERE');
@ -194,34 +212,9 @@ class News {
$query .= ' post_deleted IS NULL';
}
$result = $this->dbConn->query($query);
$count = 0;
if($result->next())
$count = $result->getInteger(0);
return $count;
}
public function countPostsByCategory(
NewsCategoryInfo|string $categoryInfo,
bool $onlyFeatured = false,
bool $includeScheduled = false,
bool $includeDeleted = false
): int {
if($categoryInfo instanceof NewsCategoryInfo)
$categoryInfo = $categoryInfo->getId();
$query = 'SELECT COUNT(*) FROM msz_news_posts WHERE category_id = ?';
if($onlyFeatured)
$query .= ' AND post_is_featured = 1';
if(!$includeScheduled)
$query .= ' AND post_scheduled <= NOW()';
if(!$includeDeleted)
$query .= ' AND post_deleted IS NULL';
$stmt = $this->cache->get($query);
$stmt->addParameter(1, $categoryInfo);
if($hasCategoryInfo)
$stmt->addParameter(1, $categoryInfo);
$stmt->execute();
$result = $stmt->getResult();
@ -233,22 +226,34 @@ class News {
return $count;
}
private const POSTS_SELECT_QUERY = 'SELECT post_id, category_id, user_id, comment_section_id, post_is_featured, post_title, post_text, UNIX_TIMESTAMP(post_scheduled), UNIX_TIMESTAMP(post_created), UNIX_TIMESTAMP(post_updated), UNIX_TIMESTAMP(post_deleted) FROM msz_news_posts';
private const POSTS_SELECT_ORDER = ' ORDER BY post_scheduled DESC';
public function getAllPosts(
public function getPosts(
NewsCategoryInfo|string|null $categoryInfo = null,
string $searchQuery = null,
bool $onlyFeatured = false,
bool $includeScheduled = false,
bool $includeDeleted = false,
?Pagination $pagination = null
): array {
$args = 0;
if($categoryInfo instanceof NewsCategoryInfo)
$categoryInfo = $categoryInfo->getId();
$hasCategoryInfo = $categoryInfo !== null;
$hasSearchQuery = $searchQuery !== null;
$hasPagination = $pagination !== null;
$query = self::POSTS_SELECT_QUERY;
if($onlyFeatured) {
$args = 0;
$query = 'SELECT post_id, category_id, user_id, comment_section_id, post_is_featured, post_title, post_text, UNIX_TIMESTAMP(post_scheduled), UNIX_TIMESTAMP(post_created), UNIX_TIMESTAMP(post_updated), UNIX_TIMESTAMP(post_deleted) FROM msz_news_posts';
if($hasCategoryInfo) {
++$args;
$query .= ' WHERE post_is_featured = 1';
$query .= ' WHERE category_id = ?';
}
if($hasSearchQuery) {
$query .= (++$args > 1 ? ' AND' : ' WHERE');
$query .= ' MATCH(post_title, post_text) AGAINST (? IN NATURAL LANGUAGE MODE)';
}
if($onlyFeatured) {
$query .= (++$args > 1 ? ' AND' : ' WHERE');
$query .= ' post_is_featured = 1';
}
if(!$includeScheduled) {
$query .= (++$args > 1 ? ' AND' : ' WHERE');
@ -258,12 +263,16 @@ class News {
$query .= (++$args > 1 ? ' AND' : ' WHERE');
$query .= ' post_deleted IS NULL';
}
$query .= self::POSTS_SELECT_ORDER;
$query .= ' ORDER BY post_scheduled DESC';
if($hasPagination)
$query .= ' LIMIT ? OFFSET ?';
$stmt = $this->cache->get($query);
$args = 0;
if($hasCategoryInfo)
$stmt->addParameter(++$args, $categoryInfo);
if($hasSearchQuery)
$stmt->addParameter(++$args, $searchQuery);
if($hasPagination) {
$stmt->addParameter(++$args, $pagination->getRange());
$stmt->addParameter(++$args, $pagination->getOffset());
@ -271,78 +280,16 @@ class News {
$stmt->execute();
return self::readPosts($stmt->getResult());
$result = $stmt->getResult();
$posts = [];
while($result->next())
$posts[] = new NewsPostInfo($result);
return $posts;
}
public function getPostsByCategory(
NewsCategoryInfo|string $categoryInfo,
bool $onlyFeatured = false,
bool $includeScheduled = false,
bool $includeDeleted = false,
?Pagination $pagination = null
): array {
if($categoryInfo instanceof NewsCategoryInfo)
$categoryInfo = $categoryInfo->getId();
$hasPagination = $pagination !== null;
$query = self::POSTS_SELECT_QUERY;
$query .= ' WHERE category_id = ?';
if($onlyFeatured)
$query .= ' AND post_is_featured = 1';
if(!$includeScheduled)
$query .= ' AND post_scheduled <= NOW()';
if(!$includeDeleted)
$query .= ' AND post_deleted IS NULL';
$query .= self::POSTS_SELECT_ORDER;
if($hasPagination)
$query .= ' LIMIT ? OFFSET ?';
$stmt = $this->cache->get($query);
$args = 0;
$stmt->addParameter(++$args, $categoryInfo);
if($hasPagination) {
$stmt->addParameter(++$args, $pagination->getRange());
$stmt->addParameter(++$args, $pagination->getOffset());
}
$stmt->execute();
return self::readPosts($stmt->getResult());
}
public function getPostsBySearchQuery(
string $searchQuery,
bool $includeScheduled = false,
bool $includeDeleted = false,
?Pagination $pagination = null
): array {
$hasPagination = $pagination !== null;
$query = self::POSTS_SELECT_QUERY;
$query .= ' WHERE MATCH(post_title, post_text) AGAINST (? IN NATURAL LANGUAGE MODE)';
if(!$includeScheduled)
$query .= ' AND post_scheduled <= NOW()';
if(!$includeDeleted)
$query .= ' AND post_deleted IS NULL';
$query .= self::POSTS_SELECT_ORDER;
if($hasPagination)
$query .= ' LIMIT ? OFFSET ?';
$stmt = $this->cache->get($query);
$args = 0;
$stmt->addParameter(++$args, $searchQuery);
if($hasPagination) {
$stmt->addParameter(++$args, $pagination->getRange());
$stmt->addParameter(++$args, $pagination->getOffset());
}
$stmt->execute();
return self::readPosts($stmt->getResult());
}
public function getPostById(string $postId): NewsPostInfo {
public function getPost(string $postId): NewsPostInfo {
$stmt = $this->cache->get('SELECT post_id, category_id, user_id, comment_section_id, post_is_featured, post_title, post_text, UNIX_TIMESTAMP(post_scheduled), UNIX_TIMESTAMP(post_created), UNIX_TIMESTAMP(post_updated), UNIX_TIMESTAMP(post_deleted) FROM msz_news_posts WHERE post_id = ?');
$stmt->addParameter(1, $postId);
$stmt->execute();
@ -386,7 +333,7 @@ class News {
$stmt->addParameter(6, $schedule);
$stmt->execute();
return $this->getPostById((string)$this->dbConn->getLastInsertId());
return $this->getPost((string)$this->dbConn->getLastInsertId());
}
public function deletePost(NewsPostInfo|string $postInfo): void {

View File

@ -118,9 +118,11 @@ class NewsRoutes {
private function getNewsPostsForView(Pagination $pagination, ?NewsCategoryInfo $categoryInfo = null): array {
$posts = [];
$postInfos = $categoryInfo === null
? $this->news->getAllPosts(onlyFeatured: true, pagination: $pagination)
: $this->news->getPostsByCategory($categoryInfo, pagination: $pagination);
$postInfos = $this->news->getPosts(
categoryInfo: $categoryInfo,
onlyFeatured: $categoryInfo === null,
pagination: $pagination
);
foreach($postInfos as $postInfo) {
$userId = $postInfo->getUserId();
@ -153,10 +155,10 @@ class NewsRoutes {
if(array_key_exists($categoryId, $this->categoryInfos))
$categoryInfo = $this->categoryInfos[$categoryId];
else
$this->categoryInfos[$categoryId] = $categoryInfo = $this->news->getCategoryByPost($postInfo);
$this->categoryInfos[$categoryId] = $categoryInfo = $this->news->getCategory(postInfo: $postInfo);
$commentsCount = $postInfo->hasCommentsCategoryId()
? $this->comments->countPosts($postInfo->getCommentsCategoryId(), includeReplies: true)
? $this->comments->countPosts(categoryInfo: $postInfo->getCommentsCategoryId(), deleted: false)
: 0;
$posts[] = [
@ -173,9 +175,11 @@ class NewsRoutes {
private function getNewsPostsForFeed(?NewsCategoryInfo $categoryInfo = null): array {
$posts = [];
$postInfos = $categoryInfo === null
? $this->news->getAllPosts(onlyFeatured: true, pagination: new Pagination(10))
: $this->news->getPostsByCategory($categoryInfo, pagination: new Pagination(10));
$postInfos = $this->news->getPosts(
categoryInfo: $categoryInfo,
onlyFeatured: $categoryInfo === null,
pagination: new Pagination(10)
);
foreach($postInfos as $postInfo) {
$userId = $postInfo->getUserId();
@ -204,9 +208,9 @@ class NewsRoutes {
}
public function getIndex() {
$categories = $this->news->getAllCategories();
$categories = $this->news->getCategories(hidden: false);
$pagination = new Pagination($this->news->countAllPosts(onlyFeatured: true), 5);
$pagination = new Pagination($this->news->countPosts(onlyFeatured: true), 5);
if(!$pagination->hasValidOffset())
return 404;
@ -232,7 +236,7 @@ class NewsRoutes {
$type = pathinfo($fileName, PATHINFO_EXTENSION);
try {
$categoryInfo = $this->news->getCategoryById($categoryId);
$categoryInfo = $this->news->getCategory(categoryId: $categoryId);
} catch(RuntimeException $ex) {
return 404;
}
@ -244,7 +248,7 @@ class NewsRoutes {
elseif($type !== '')
return 404;
$pagination = new Pagination($this->news->countPostsByCategory($categoryInfo), 5);
$pagination = new Pagination($this->news->countPosts(categoryInfo: $categoryInfo), 5);
if(!$pagination->hasValidOffset())
return 404;
@ -267,7 +271,7 @@ class NewsRoutes {
public function getPost($response, $request, string $postId) {
try {
$postInfo = $this->news->getPostById($postId);
$postInfo = $this->news->getPost($postId);
} catch(RuntimeException $ex) {
return 404;
}
@ -275,11 +279,11 @@ class NewsRoutes {
if(!$postInfo->isPublished() || $postInfo->isDeleted())
return 404;
$categoryInfo = $this->news->getCategoryByPost($postInfo);
$categoryInfo = $this->news->getCategory(postInfo: $postInfo);
if($postInfo->hasCommentsCategoryId())
try {
$commentsCategory = $this->comments->getCategoryById($postInfo->getCommentsCategoryId());
$commentsCategory = $this->comments->getCategory(categoryId: $postInfo->getCommentsCategoryId());
} catch(RuntimeException $ex) {}
if(!isset($commentsCategory)) {

View File

@ -81,13 +81,13 @@ final class SharpChatRoutes {
$response->setHeader('Access-Control-Allow-Origin', '*');
$response->setHeader('Access-Control-Allow-Methods', 'GET');
$emotes = $this->emotes->getAllEmotes(withStrings: true);
$emotes = $this->emotes->getEmotes();
$out = [];
foreach($emotes as $emoteInfo) {
$strings = [];
foreach($emoteInfo->getStrings() as $stringInfo)
foreach($this->emotes->getEmoteStrings($emoteInfo) as $stringInfo)
$strings[] = sprintf(':%s:', $stringInfo->getString());
$out[] = [

View File

@ -42,9 +42,9 @@
</time>
</a>
{% if change_info.tags|length > 0 %}
{% if change_tags|length > 0 %}
<ul class="changelog__change__tags">
{% for tag in change_info.tags %}
{% for tag in change_tags %}
<li class="changelog__change__tag" title="{{ tag.description }}">
<a href="{{ url('changelog-index', {'tags': tag.id}) }}" class="changelog__change__tag__link">
{{ tag.name }}

View File

@ -27,6 +27,7 @@
{% macro changelog_entry(change, is_small, is_manage) %}
{% set user = change.user|default(null) %}
{% set user_colour = change.user_colour|default(null) %}
{% set tags = change.tags|default([]) %}
{% if change.change is defined %}
{% set change = change.change %}
{% endif %}
@ -74,7 +75,7 @@
{% if is_manage %}
<div class="changelog__entry__tags">
{% for tag in change.tags %}
{% for tag in tags %}
<a href="{{ is_manage ? url('manage-changelog-tag', {'tag': tag.id}) : url('changelog-index', {'tags': tag.id}) }}" class="changelog__entry__tag">
{{ tag.name }}
</a>

View File

@ -44,7 +44,7 @@
<label class="manage__tag">
<div class="manage__tag__background"></div>
<div class="manage__tag__content">
{{ input_checkbox('cl_tags[]', '', change_info.hasTag(tag)|default(0), 'manage__tag__checkbox', tag.id) }}
{{ input_checkbox('cl_tags[]', '', tag.id in change_info_tags, 'manage__tag__checkbox', tag.id) }}
<div class="manage__tag__title">
{{ tag.name }}
</div>

View File

@ -28,7 +28,7 @@
<label class="manage__emote__field">
<div class="manage__emote__field__name">Strings</div>
{{ input_text('em_strings', 'manage__emote__field__value', emote_info.strings|default([])|join(' '), 'text', '', true) }}
{{ input_text('em_strings', 'manage__emote__field__value', emote_strings|default([])|join(' '), 'text', '', true) }}
</label>
<div class="manage__emote__actions">