Made data source argument lists for News, Changelog, Comments and Emotes consistent with the rest.
This commit is contained in:
parent
87915b6a25
commit
d4f6990e8a
27 changed files with 334 additions and 433 deletions
|
@ -38,13 +38,13 @@ $commentVote = (int)filter_input(INPUT_GET, 'v', FILTER_SANITIZE_NUMBER_INT);
|
||||||
|
|
||||||
if(!empty($commentId)) {
|
if(!empty($commentId)) {
|
||||||
try {
|
try {
|
||||||
$commentInfo = $comments->getPostById($commentId);
|
$commentInfo = $comments->getPost($commentId);
|
||||||
} catch(RuntimeException $ex) {
|
} catch(RuntimeException $ex) {
|
||||||
echo render_info('Post not found.', 404);
|
echo render_info('Post not found.', 404);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$categoryInfo = $comments->getCategoryByPost($commentInfo);
|
$categoryInfo = $comments->getCategory(postInfo: $commentInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($commentMode !== 'create' && empty($commentInfo)) {
|
if($commentMode !== 'create' && empty($commentInfo)) {
|
||||||
|
@ -186,7 +186,7 @@ switch($commentMode) {
|
||||||
$categoryId = isset($_POST['comment']['category']) && is_string($_POST['comment']['category'])
|
$categoryId = isset($_POST['comment']['category']) && is_string($_POST['comment']['category'])
|
||||||
? (int)$_POST['comment']['category']
|
? (int)$_POST['comment']['category']
|
||||||
: 0;
|
: 0;
|
||||||
$categoryInfo = $comments->getCategoryById($categoryId);
|
$categoryInfo = $comments->getCategory(categoryId: $categoryId);
|
||||||
} catch(RuntimeException $ex) {
|
} catch(RuntimeException $ex) {
|
||||||
echo render_info('This comment category doesn\'t exist.', 404);
|
echo render_info('This comment category doesn\'t exist.', 404);
|
||||||
break;
|
break;
|
||||||
|
@ -227,7 +227,7 @@ switch($commentMode) {
|
||||||
|
|
||||||
if($commentReply > 0) {
|
if($commentReply > 0) {
|
||||||
try {
|
try {
|
||||||
$parentInfo = $comments->getPostById($commentReply);
|
$parentInfo = $comments->getPost($commentReply);
|
||||||
} catch(RuntimeException $ex) {}
|
} catch(RuntimeException $ex) {}
|
||||||
|
|
||||||
if(!isset($parentInfo) || $parentInfo->isDeleted()) {
|
if(!isset($parentInfo) || $parentInfo->isDeleted()) {
|
||||||
|
|
|
@ -4,6 +4,7 @@ namespace Misuzu;
|
||||||
use DateTimeInterface;
|
use DateTimeInterface;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
use Index\DateTime;
|
use Index\DateTime;
|
||||||
|
use Index\XArray;
|
||||||
use Misuzu\Changelog\Changelog;
|
use Misuzu\Changelog\Changelog;
|
||||||
|
|
||||||
if(!$msz->isLoggedIn() || !perms_check_user(MSZ_PERMS_CHANGELOG, $msz->getActiveUser()->getId(), MSZ_PERM_CHANGELOG_MANAGE_CHANGES)) {
|
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();
|
$changelog = $msz->getChangelog();
|
||||||
$changeId = (string)filter_input(INPUT_GET, 'c', FILTER_SANITIZE_NUMBER_INT);
|
$changeId = (string)filter_input(INPUT_GET, 'c', FILTER_SANITIZE_NUMBER_INT);
|
||||||
$loadChangeInfo = fn() => $changelog->getChangeById($changeId, withTags: true);
|
$changeInfo = null;
|
||||||
$changeTags = $changelog->getAllTags();
|
$changeTagIds = [];
|
||||||
|
$tagInfos = $changelog->getTags();
|
||||||
|
|
||||||
if(empty($changeId))
|
if(empty($changeId))
|
||||||
$isNew = true;
|
$isNew = true;
|
||||||
else
|
else
|
||||||
try {
|
try {
|
||||||
$isNew = false;
|
$isNew = false;
|
||||||
$changeInfo = $loadChangeInfo();
|
$changeInfo = $changelog->getChange($changeId);
|
||||||
|
$changeTagIds = XArray::select($changelog->getTags(changeInfo: $changeInfo), fn($tagInfo) => $tagInfo->getId());
|
||||||
} catch(RuntimeException $ex) {
|
} catch(RuntimeException $ex) {
|
||||||
echo render_error(404);
|
echo render_error(404);
|
||||||
return;
|
return;
|
||||||
|
@ -78,7 +81,7 @@ while($_SERVER['REQUEST_METHOD'] === 'POST' && CSRF::validateRequest()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!empty($tags)) {
|
if(!empty($tags)) {
|
||||||
$tCurrent = $changeInfo->getTagIds();
|
$tCurrent = $changeTagIds;
|
||||||
$tApply = $tags;
|
$tApply = $tags;
|
||||||
$tRemove = [];
|
$tRemove = [];
|
||||||
|
|
||||||
|
@ -102,17 +105,15 @@ while($_SERVER['REQUEST_METHOD'] === 'POST' && CSRF::validateRequest()) {
|
||||||
[$changeInfo->getId()]
|
[$changeInfo->getId()]
|
||||||
);
|
);
|
||||||
|
|
||||||
if($isNew) {
|
|
||||||
url_redirect('manage-changelog-change', ['change' => $changeInfo->getId()]);
|
url_redirect('manage-changelog-change', ['change' => $changeInfo->getId()]);
|
||||||
return;
|
return;
|
||||||
} else $changeInfo = $loadChangeInfo();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Template::render('manage.changelog.change', [
|
Template::render('manage.changelog.change', [
|
||||||
'change_new' => $isNew,
|
'change_new' => $isNew,
|
||||||
'change_info' => $changeInfo ?? null,
|
'change_info' => $changeInfo,
|
||||||
'change_tags' => $changeTags,
|
'change_info_tags' => $changeTagIds,
|
||||||
|
'change_tags' => $tagInfos,
|
||||||
'change_actions' => $changeActions,
|
'change_actions' => $changeActions,
|
||||||
'change_author_id' => $msz->getActiveUser()->getId(),
|
'change_author_id' => $msz->getActiveUser()->getId(),
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -9,14 +9,14 @@ if(!$msz->isLoggedIn() || !perms_check_user(MSZ_PERMS_CHANGELOG, $msz->getActive
|
||||||
}
|
}
|
||||||
|
|
||||||
$changelog = $msz->getChangelog();
|
$changelog = $msz->getChangelog();
|
||||||
$changelogPagination = new Pagination($changelog->countAllChanges(), 30);
|
$changelogPagination = new Pagination($changelog->countChanges(), 30);
|
||||||
|
|
||||||
if(!$changelogPagination->hasValidOffset()) {
|
if(!$changelogPagination->hasValidOffset()) {
|
||||||
echo render_error(404);
|
echo render_error(404);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$changeInfos = $changelog->getAllChanges(withTags: true, pagination: $changelogPagination);
|
$changeInfos = $changelog->getChanges(pagination: $changelogPagination);
|
||||||
$changes = [];
|
$changes = [];
|
||||||
$userInfos = [];
|
$userInfos = [];
|
||||||
$userColours = [];
|
$userColours = [];
|
||||||
|
@ -39,6 +39,7 @@ foreach($changeInfos as $changeInfo) {
|
||||||
|
|
||||||
$changes[] = [
|
$changes[] = [
|
||||||
'change' => $changeInfo,
|
'change' => $changeInfo,
|
||||||
|
'tags' => $changelog->getTags(changeInfo: $changeInfo),
|
||||||
'user' => $userInfo,
|
'user' => $userInfo,
|
||||||
'user_colour' => $userColours[$userId] ?? \Index\Colour\Colour::none(),
|
'user_colour' => $userColours[$userId] ?? \Index\Colour\Colour::none(),
|
||||||
];
|
];
|
||||||
|
|
|
@ -10,7 +10,7 @@ if(!$msz->isLoggedIn() || !perms_check_user(MSZ_PERMS_CHANGELOG, $msz->getActive
|
||||||
|
|
||||||
$changelog = $msz->getChangelog();
|
$changelog = $msz->getChangelog();
|
||||||
$tagId = (string)filter_input(INPUT_GET, 't', FILTER_SANITIZE_NUMBER_INT);
|
$tagId = (string)filter_input(INPUT_GET, 't', FILTER_SANITIZE_NUMBER_INT);
|
||||||
$loadTagInfo = fn() => $changelog->getTagById($tagId);
|
$loadTagInfo = fn() => $changelog->getTag($tagId);
|
||||||
|
|
||||||
if(empty($tagId))
|
if(empty($tagId))
|
||||||
$isNew = true;
|
$isNew = true;
|
||||||
|
|
|
@ -7,5 +7,5 @@ if(!$msz->isLoggedIn() || !perms_check_user(MSZ_PERMS_CHANGELOG, $msz->getActive
|
||||||
}
|
}
|
||||||
|
|
||||||
Template::render('manage.changelog.tags', [
|
Template::render('manage.changelog.tags', [
|
||||||
'changelog_tags' => $msz->getChangelog()->getAllTags(),
|
'changelog_tags' => $msz->getChangelog()->getTags(),
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
namespace Misuzu;
|
namespace Misuzu;
|
||||||
|
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
|
use Index\XArray;
|
||||||
|
|
||||||
if(!$msz->isLoggedIn() || !perms_check_user(MSZ_PERMS_GENERAL, $msz->getActiveUser()->getId(), MSZ_PERM_GENERAL_MANAGE_EMOTES)) {
|
if(!$msz->isLoggedIn() || !perms_check_user(MSZ_PERMS_GENERAL, $msz->getActiveUser()->getId(), MSZ_PERM_GENERAL_MANAGE_EMOTES)) {
|
||||||
echo render_error(403);
|
echo render_error(403);
|
||||||
|
@ -10,14 +11,14 @@ if(!$msz->isLoggedIn() || !perms_check_user(MSZ_PERMS_GENERAL, $msz->getActiveUs
|
||||||
|
|
||||||
$emotes = $msz->getEmotes();
|
$emotes = $msz->getEmotes();
|
||||||
$emoteId = (string)filter_input(INPUT_GET, 'e', FILTER_SANITIZE_NUMBER_INT);
|
$emoteId = (string)filter_input(INPUT_GET, 'e', FILTER_SANITIZE_NUMBER_INT);
|
||||||
$loadEmoteInfo = fn() => $emotes->getEmoteById($emoteId, true);
|
|
||||||
|
|
||||||
if(empty($emoteId))
|
if(empty($emoteId))
|
||||||
$isNew = true;
|
$isNew = true;
|
||||||
else
|
else
|
||||||
try {
|
try {
|
||||||
$isNew = false;
|
$isNew = false;
|
||||||
$emoteInfo = $loadEmoteInfo();
|
$emoteInfo = $emotes->getEmote($emoteId);
|
||||||
|
$emoteStrings = $emotes->getEmoteStrings($emoteInfo);
|
||||||
} catch(RuntimeException $ex) {
|
} catch(RuntimeException $ex) {
|
||||||
echo render_error(404);
|
echo render_error(404);
|
||||||
return;
|
return;
|
||||||
|
@ -60,7 +61,7 @@ while($_SERVER['REQUEST_METHOD'] === 'POST' && CSRF::validateRequest()) {
|
||||||
$emotes->updateEmote($emoteInfo, $order, $minRank, $url);
|
$emotes->updateEmote($emoteInfo, $order, $minRank, $url);
|
||||||
}
|
}
|
||||||
|
|
||||||
$sCurrent = $emoteInfo->getStringsRaw();
|
$sCurrent = XArray::select($emoteStrings, fn($stringInfo) => $stringInfo->getString());
|
||||||
$sApply = $strings;
|
$sApply = $strings;
|
||||||
$sRemove = [];
|
$sRemove = [];
|
||||||
|
|
||||||
|
@ -97,14 +98,12 @@ while($_SERVER['REQUEST_METHOD'] === 'POST' && CSRF::validateRequest()) {
|
||||||
[$emoteInfo->getId()]
|
[$emoteInfo->getId()]
|
||||||
);
|
);
|
||||||
|
|
||||||
if($isNew) {
|
|
||||||
url_redirect('manage-general-emoticon', ['emote' => $emoteInfo->getId()]);
|
url_redirect('manage-general-emoticon', ['emote' => $emoteInfo->getId()]);
|
||||||
return;
|
return;
|
||||||
} else $emoteInfo = $loadEmoteInfo();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Template::render('manage.general.emoticon', [
|
Template::render('manage.general.emoticon', [
|
||||||
'emote_new' => $isNew,
|
'emote_new' => $isNew,
|
||||||
'emote_info' => $emoteInfo ?? null,
|
'emote_info' => $emoteInfo ?? null,
|
||||||
|
'emote_strings' => $emoteStrings ?? [],
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -14,7 +14,7 @@ if(CSRF::validateRequest() && !empty($_GET['emote'])) {
|
||||||
$emoteId = (string)filter_input(INPUT_GET, 'emote', FILTER_SANITIZE_NUMBER_INT);
|
$emoteId = (string)filter_input(INPUT_GET, 'emote', FILTER_SANITIZE_NUMBER_INT);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$emoteInfo = $emotes->getEmoteById($emoteId);
|
$emoteInfo = $emotes->getEmote($emoteId);
|
||||||
} catch(RuntimeException $ex) {
|
} catch(RuntimeException $ex) {
|
||||||
echo render_error(404);
|
echo render_error(404);
|
||||||
return;
|
return;
|
||||||
|
@ -45,5 +45,5 @@ if(CSRF::validateRequest() && !empty($_GET['emote'])) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Template::render('manage.general.emoticons', [
|
Template::render('manage.general.emoticons', [
|
||||||
'emotes' => $emotes->getAllEmotes(),
|
'emotes' => $emotes->getEmotes(),
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -7,14 +7,14 @@ if(!$msz->isLoggedIn() || !perms_check_user(MSZ_PERMS_NEWS, $msz->getActiveUser(
|
||||||
}
|
}
|
||||||
|
|
||||||
$news = $msz->getNews();
|
$news = $msz->getNews();
|
||||||
$pagination = new Pagination($news->countAllCategories(true), 15);
|
$pagination = new Pagination($news->countCategories(), 15);
|
||||||
|
|
||||||
if(!$pagination->hasValidOffset()) {
|
if(!$pagination->hasValidOffset()) {
|
||||||
echo render_error(404);
|
echo render_error(404);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$categories = $news->getAllCategories(true, $pagination);
|
$categories = $news->getCategories(pagination: $pagination);
|
||||||
|
|
||||||
Template::render('manage.news.categories', [
|
Template::render('manage.news.categories', [
|
||||||
'news_categories' => $categories,
|
'news_categories' => $categories,
|
||||||
|
|
|
@ -10,7 +10,7 @@ if(!$msz->isLoggedIn() || !perms_check_user(MSZ_PERMS_NEWS, $msz->getActiveUser(
|
||||||
|
|
||||||
$news = $msz->getNews();
|
$news = $msz->getNews();
|
||||||
$categoryId = (string)filter_input(INPUT_GET, 'c', FILTER_SANITIZE_NUMBER_INT);
|
$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))
|
if(empty($categoryId))
|
||||||
$isNew = true;
|
$isNew = true;
|
||||||
|
|
|
@ -10,7 +10,7 @@ if(!$msz->isLoggedIn() || !perms_check_user(MSZ_PERMS_NEWS, $msz->getActiveUser(
|
||||||
|
|
||||||
$news = $msz->getNews();
|
$news = $msz->getNews();
|
||||||
$postId = (string)filter_input(INPUT_GET, 'p', FILTER_SANITIZE_NUMBER_INT);
|
$postId = (string)filter_input(INPUT_GET, 'p', FILTER_SANITIZE_NUMBER_INT);
|
||||||
$loadPostInfo = fn() => $news->getPostById($postId);
|
$loadPostInfo = fn() => $news->getPost($postId);
|
||||||
|
|
||||||
if(empty($postId))
|
if(empty($postId))
|
||||||
$isNew = true;
|
$isNew = true;
|
||||||
|
@ -71,7 +71,7 @@ while($_SERVER['REQUEST_METHOD'] === 'POST' && CSRF::validateRequest()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
$categories = [];
|
$categories = [];
|
||||||
foreach($news->getAllCategories(true) as $categoryInfo)
|
foreach($news->getCategories() as $categoryInfo)
|
||||||
$categories[$categoryInfo->getId()] = $categoryInfo->getName();
|
$categories[$categoryInfo->getId()] = $categoryInfo->getName();
|
||||||
|
|
||||||
Template::render('manage.news.post', [
|
Template::render('manage.news.post', [
|
||||||
|
|
|
@ -7,7 +7,7 @@ if(!$msz->isLoggedIn() || !perms_check_user(MSZ_PERMS_NEWS, $msz->getActiveUser(
|
||||||
}
|
}
|
||||||
|
|
||||||
$news = $msz->getNews();
|
$news = $msz->getNews();
|
||||||
$pagination = new Pagination($news->countAllPosts(
|
$pagination = new Pagination($news->countPosts(
|
||||||
includeScheduled: true,
|
includeScheduled: true,
|
||||||
includeDeleted: true
|
includeDeleted: true
|
||||||
), 15);
|
), 15);
|
||||||
|
|
|
@ -20,7 +20,7 @@ if(!empty($searchQuery)) {
|
||||||
$users = $msz->getUsers();
|
$users = $msz->getUsers();
|
||||||
$comments = $msz->getComments();
|
$comments = $msz->getComments();
|
||||||
$newsPosts = [];
|
$newsPosts = [];
|
||||||
$newsPostInfos = $news->getPostsBySearchQuery($searchQuery);
|
$newsPostInfos = $news->getPosts(searchQuery: $searchQuery);
|
||||||
$newsUserInfos = [];
|
$newsUserInfos = [];
|
||||||
$newsUserColours = [];
|
$newsUserColours = [];
|
||||||
$newsCategoryInfos = [];
|
$newsCategoryInfos = [];
|
||||||
|
@ -45,10 +45,10 @@ if(!empty($searchQuery)) {
|
||||||
if(array_key_exists($categoryId, $newsCategoryInfos))
|
if(array_key_exists($categoryId, $newsCategoryInfos))
|
||||||
$categoryInfo = $newsCategoryInfos[$categoryId];
|
$categoryInfo = $newsCategoryInfos[$categoryId];
|
||||||
else
|
else
|
||||||
$newsCategoryInfos[$categoryId] = $categoryInfo = $news->getCategoryByPost($postInfo);
|
$newsCategoryInfos[$categoryId] = $categoryInfo = $news->getCategory(postInfo: $postInfo);
|
||||||
|
|
||||||
$commentsCount = $postInfo->hasCommentsCategoryId()
|
$commentsCount = $postInfo->hasCommentsCategoryId()
|
||||||
? $comments->countPosts($postInfo->getCommentsCategoryId(), includeReplies: true) : 0;
|
? $comments->countPosts(categoryInfo: $postInfo->getCommentsCategoryId(), deleted: false) : 0;
|
||||||
|
|
||||||
$newsPosts[] = [
|
$newsPosts[] = [
|
||||||
'post' => $postInfo,
|
'post' => $postInfo,
|
||||||
|
|
|
@ -11,16 +11,14 @@ class ChangeInfo {
|
||||||
private int $created;
|
private int $created;
|
||||||
private string $summary;
|
private string $summary;
|
||||||
private string $body;
|
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->id = (string)$result->getInteger(0);
|
||||||
$this->userId = $result->isNull(1) ? null : (string)$result->getInteger(1);
|
$this->userId = $result->isNull(1) ? null : (string)$result->getInteger(1);
|
||||||
$this->action = $result->getInteger(2);
|
$this->action = $result->getInteger(2);
|
||||||
$this->created = $result->getInteger(3);
|
$this->created = $result->getInteger(3);
|
||||||
$this->summary = $result->getString(4);
|
$this->summary = $result->getString(4);
|
||||||
$this->body = $result->getString(5);
|
$this->body = $result->getString(5);
|
||||||
$this->tags = $tags;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getId(): string {
|
public function getId(): string {
|
||||||
|
@ -70,19 +68,4 @@ class ChangeInfo {
|
||||||
public function getCommentsCategoryName(): string {
|
public function getCommentsCategoryName(): string {
|
||||||
return sprintf('changelog-date-%s', $this->getDate());
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,38 +64,7 @@ class Changelog {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private function readChanges(IDbResult $result, bool $withTags): array {
|
public function countChanges(
|
||||||
$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(
|
|
||||||
UserInfo|string|null $userInfo = null,
|
UserInfo|string|null $userInfo = null,
|
||||||
DateTime|int|null $dateTime = null,
|
DateTime|int|null $dateTime = null,
|
||||||
?array $tags = null
|
?array $tags = null
|
||||||
|
@ -147,8 +116,7 @@ class Changelog {
|
||||||
return $count;
|
return $count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAllChanges(
|
public function getChanges(
|
||||||
bool $withTags = false,
|
|
||||||
UserInfo|string|null $userInfo = null,
|
UserInfo|string|null $userInfo = null,
|
||||||
DateTime|int|null $dateTime = null,
|
DateTime|int|null $dateTime = null,
|
||||||
?array $tags = null,
|
?array $tags = null,
|
||||||
|
@ -201,10 +169,16 @@ class Changelog {
|
||||||
|
|
||||||
$stmt->execute();
|
$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 = $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->addParameter(1, $changeId);
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
|
@ -213,11 +187,7 @@ class Changelog {
|
||||||
if(!$result->next())
|
if(!$result->next())
|
||||||
throw new RuntimeException('No tag with that ID exists.');
|
throw new RuntimeException('No tag with that ID exists.');
|
||||||
|
|
||||||
$tags = [];
|
return new ChangeInfo($result);
|
||||||
if($withTags)
|
|
||||||
$tags = $this->getTagsByChange((string)$result->getInteger(0));
|
|
||||||
|
|
||||||
return new ChangeInfo($result, $tags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createChange(
|
public function createChange(
|
||||||
|
@ -250,7 +220,7 @@ class Changelog {
|
||||||
$stmt->addParameter(5, $body);
|
$stmt->addParameter(5, $body);
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
|
|
||||||
return $this->getChangeById((string)$this->dbConn->getLastInsertId());
|
return $this->getChange((string)$this->dbConn->getLastInsertId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function deleteChange(ChangeInfo|string $infoOrId): void {
|
public function deleteChange(ChangeInfo|string $infoOrId): void {
|
||||||
|
@ -306,25 +276,38 @@ class Changelog {
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAllTags(): array {
|
public function getTags(
|
||||||
// only putting the changes count in here for now, it is only used in manage
|
ChangeInfo|string|null $changeInfo = null
|
||||||
return $this->readTags(
|
): array {
|
||||||
$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')
|
if($changeInfo instanceof ChangeInfo)
|
||||||
);
|
$changeInfo = $changeInfo->getId();
|
||||||
}
|
|
||||||
|
|
||||||
public function getTagsByChange(ChangeInfo|string $infoOrId): array {
|
$hasChangeInfo = $changeInfo !== null;
|
||||||
if($infoOrId instanceof ChangeInfo)
|
|
||||||
$infoOrId = $infoOrId->getId();
|
|
||||||
|
|
||||||
$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 = ?)');
|
$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';
|
||||||
$stmt->addParameter(1, $infoOrId);
|
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();
|
$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);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTagById(string $tagId): ChangeTagInfo {
|
return $tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = $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->addParameter(1, $tagId);
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
|
@ -355,7 +338,7 @@ class Changelog {
|
||||||
$stmt->addParameter(3, $archived ? 1 : 0);
|
$stmt->addParameter(3, $archived ? 1 : 0);
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
|
|
||||||
return $this->getTagById((string)$this->dbConn->getLastInsertId());
|
return $this->getTag((string)$this->dbConn->getLastInsertId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function deleteTag(ChangeTagInfo|string $infoOrId): void {
|
public function deleteTag(ChangeTagInfo|string $infoOrId): void {
|
||||||
|
|
|
@ -96,12 +96,12 @@ final class ChangelogRoutes {
|
||||||
$tag = trim($tag);
|
$tag = trim($tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
$count = $this->changelog->countAllChanges($filterUser, $filterDate, $filterTags);
|
$count = $this->changelog->countChanges($filterUser, $filterDate, $filterTags);
|
||||||
$pagination = new Pagination($count, 30);
|
$pagination = new Pagination($count, 30);
|
||||||
if(!$pagination->hasValidOffset())
|
if(!$pagination->hasValidOffset())
|
||||||
return 404;
|
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))
|
if(empty($changeInfos))
|
||||||
return 404;
|
return 404;
|
||||||
|
|
||||||
|
@ -145,11 +145,13 @@ final class ChangelogRoutes {
|
||||||
|
|
||||||
public function getChange($response, $request, string $changeId) {
|
public function getChange($response, $request, string $changeId) {
|
||||||
try {
|
try {
|
||||||
$changeInfo = $this->changelog->getChangeById($changeId, withTags: true);
|
$changeInfo = $this->changelog->getChange($changeId);
|
||||||
} catch(RuntimeException $ex) {
|
} catch(RuntimeException $ex) {
|
||||||
return 404;
|
return 404;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$tagInfos = $this->changelog->getTags(changeInfo: $changeInfo);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$userInfo = $this->users->getUser($changeInfo->getUserId(), 'id');
|
$userInfo = $this->users->getUser($changeInfo->getUserId(), 'id');
|
||||||
$userColour = $this->users->getUserColour($userInfo);
|
$userColour = $this->users->getUserColour($userInfo);
|
||||||
|
@ -160,6 +162,7 @@ final class ChangelogRoutes {
|
||||||
|
|
||||||
return Template::renderRaw('changelog.change', [
|
return Template::renderRaw('changelog.change', [
|
||||||
'change_info' => $changeInfo,
|
'change_info' => $changeInfo,
|
||||||
|
'change_tags' => $tagInfos,
|
||||||
'change_user_info' => $userInfo,
|
'change_user_info' => $userInfo,
|
||||||
'change_user_colour' => $userColour,
|
'change_user_colour' => $userColour,
|
||||||
'comments_info' => $this->getCommentsInfo($changeInfo->getCommentsCategoryName()),
|
'comments_info' => $this->getCommentsInfo($changeInfo->getCommentsCategoryName()),
|
||||||
|
@ -168,7 +171,7 @@ final class ChangelogRoutes {
|
||||||
|
|
||||||
private function createFeed(string $feedMode): Feed {
|
private function createFeed(string $feedMode): Feed {
|
||||||
$siteName = $this->config->getString('site.name', 'Misuzu');
|
$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)
|
$feed = (new Feed)
|
||||||
->setTitle($siteName . ' » Changelog')
|
->setTitle($siteName . ' » Changelog')
|
||||||
|
|
|
@ -18,7 +18,9 @@ class Comments {
|
||||||
$this->cache = new DbStatementCache($dbConn);
|
$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)
|
if($owner instanceof UserInfo)
|
||||||
$owner = $owner->getId();
|
$owner = $owner->getId();
|
||||||
|
|
||||||
|
@ -79,48 +81,48 @@ class Comments {
|
||||||
return $categories;
|
return $categories;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCategoryByName(string $name): CommentsCategoryInfo {
|
public function getCategory(
|
||||||
$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 = ?');
|
?string $categoryId = null,
|
||||||
$stmt->addParameter(1, $name);
|
?string $name = null,
|
||||||
$stmt->execute();
|
CommentsPostInfo|string|null $postInfo = null
|
||||||
$result = $stmt->getResult();
|
): CommentsCategoryInfo {
|
||||||
|
$hasCategoryId = $categoryId !== null;
|
||||||
|
$hasName = $name !== null;
|
||||||
|
$hasPostInfo = $postInfo !== null;
|
||||||
|
|
||||||
if(!$result->next())
|
if(!$hasCategoryId && !$hasName && !$hasPostInfo)
|
||||||
throw new RuntimeException('No category with this name found.');
|
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);
|
$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) {
|
||||||
public function getCategoryById(string $id): CommentsCategoryInfo {
|
$query .= ' WHERE category_name = ?';
|
||||||
$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 = ?');
|
$value = $name;
|
||||||
$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);
|
|
||||||
}
|
}
|
||||||
|
if($hasPostInfo) {
|
||||||
public function getCategoryByPost(CommentsPostInfo|string $infoOrId): CommentsCategoryInfo {
|
if($postInfo instanceof CommentsPostInfo) {
|
||||||
$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 = ';
|
$query .= ' WHERE category_id = ?';
|
||||||
|
$value = $postInfo->getCategoryId();
|
||||||
if($infoOrId instanceof CommentsPostInfo) {
|
|
||||||
$query .= '?';
|
|
||||||
$param = $infoOrId->getCategoryId();
|
|
||||||
} else {
|
} else {
|
||||||
$query .= '(SELECT category_id FROM msz_comments_posts WHERE comment_id = ?)';
|
$query .= ' WHERE category_id = (SELECT category_id FROM msz_comments_posts WHERE comment_id = ?)';
|
||||||
$param = $infoOrId;
|
$value = $postInfo;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$stmt = $this->cache->get($query);
|
$stmt = $this->cache->get($query);
|
||||||
$stmt->addParameter(1, $param);
|
$stmt->addParameter(1, $value);
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
$result = $stmt->getResult();
|
$result = $stmt->getResult();
|
||||||
|
|
||||||
if(!$result->next())
|
if(!$result->next())
|
||||||
throw new RuntimeException('No category belonging to this post found.');
|
throw new RuntimeException('Comments category not found.');
|
||||||
|
|
||||||
return new CommentsCategoryInfo($result);
|
return new CommentsCategoryInfo($result);
|
||||||
}
|
}
|
||||||
|
@ -141,7 +143,7 @@ class Comments {
|
||||||
|
|
||||||
public function ensureCategory(string $name, UserInfo|string|null $owner = null): CommentsCategoryInfo {
|
public function ensureCategory(string $name, UserInfo|string|null $owner = null): CommentsCategoryInfo {
|
||||||
if($this->checkCategoryNameExists($name))
|
if($this->checkCategoryNameExists($name))
|
||||||
return $this->getCategoryByName($name);
|
return $this->getCategory(name: $name);
|
||||||
return $this->createCategory($name, $owner);
|
return $this->createCategory($name, $owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +160,7 @@ class Comments {
|
||||||
$stmt->addParameter(2, $owner);
|
$stmt->addParameter(2, $owner);
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
|
|
||||||
return $this->getCategoryById((string)$this->dbConn->getLastInsertId());
|
return $this->getCategory(categoryId: (string)$this->dbConn->getLastInsertId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function deleteCategory(CommentsCategoryInfo|string $category): void {
|
public function deleteCategory(CommentsCategoryInfo|string $category): void {
|
||||||
|
@ -214,48 +216,41 @@ class Comments {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function countPosts(
|
public function countPosts(
|
||||||
CommentsCategoryInfo|string|null $category = null,
|
CommentsCategoryInfo|string|null $categoryInfo = null,
|
||||||
CommentsPostInfo|string|null $parent = null,
|
CommentsPostInfo|string|null $parentInfo = null,
|
||||||
bool $includeReplies = false,
|
?bool $replies = null,
|
||||||
bool $includeDeleted = false
|
?bool $deleted = null
|
||||||
): int {
|
): int {
|
||||||
if($category instanceof CommentsCategoryInfo)
|
if($categoryInfo instanceof CommentsCategoryInfo)
|
||||||
$category = $category->getId();
|
$categoryInfo = $categoryInfo->getId();
|
||||||
if($parent instanceof CommentsPostInfo)
|
if($parentInfo instanceof CommentsPostInfo)
|
||||||
$parent = $parent->getId();
|
$parentInfo = $parentInfo->getId();
|
||||||
|
|
||||||
$hasCategory = $category !== null;
|
$hasCategoryInfo = $categoryInfo !== null;
|
||||||
$hasParent = $parent !== null;
|
$hasParentInfo = $parentInfo !== null;
|
||||||
|
$hasReplies = $replies !== null;
|
||||||
|
$hasDeleted = $deleted !== null;
|
||||||
|
|
||||||
$args = 0;
|
$args = 0;
|
||||||
$query = 'SELECT COUNT(*) FROM msz_comments_posts';
|
$query = 'SELECT COUNT(*) FROM msz_comments_posts';
|
||||||
|
|
||||||
if($hasParent) {
|
if($hasParentInfo) {
|
||||||
++$args;
|
++$args;
|
||||||
$query .= ' WHERE comment_reply_to = ?';
|
$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;
|
$args = 0;
|
||||||
$stmt = $this->cache->get($query);
|
$stmt = $this->cache->get($query);
|
||||||
if($hasParent)
|
if($hasParentInfo)
|
||||||
$stmt->addParameter(++$args, $parent);
|
$stmt->addParameter(++$args, $parentInfo);
|
||||||
elseif($hasCategory)
|
elseif($hasCategoryInfo)
|
||||||
$stmt->addParameter(++$args, $category);
|
$stmt->addParameter(++$args, $categoryInfo);
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
|
|
||||||
$result = $stmt->getResult();
|
$result = $stmt->getResult();
|
||||||
|
@ -268,20 +263,22 @@ class Comments {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPosts(
|
public function getPosts(
|
||||||
CommentsCategoryInfo|string|null $category = null,
|
CommentsCategoryInfo|string|null $categoryInfo = null,
|
||||||
CommentsPostInfo|string|null $parent = null,
|
CommentsPostInfo|string|null $parentInfo = null,
|
||||||
bool $includeReplies = false,
|
?bool $replies = null,
|
||||||
bool $includeDeleted = false,
|
?bool $deleted = null,
|
||||||
bool $includeRepliesCount = false,
|
bool $includeRepliesCount = false,
|
||||||
bool $includeVotesCount = false
|
bool $includeVotesCount = false
|
||||||
): array {
|
): array {
|
||||||
if($category instanceof CommentsCategoryInfo)
|
if($categoryInfo instanceof CommentsCategoryInfo)
|
||||||
$category = $category->getId();
|
$categoryInfo = $categoryInfo->getId();
|
||||||
if($parent instanceof CommentsPostInfo)
|
if($parentInfo instanceof CommentsPostInfo)
|
||||||
$parent = $parent->getId();
|
$parentInfo = $parentInfo->getId();
|
||||||
|
|
||||||
$hasCategory = $category !== null;
|
$hasCategoryInfo = $categoryInfo !== null;
|
||||||
$hasParent = $parent !== null;
|
$hasParentInfo = $parentInfo !== null;
|
||||||
|
$hasReplies = $replies !== null;
|
||||||
|
$hasDeleted = $deleted !== null;
|
||||||
|
|
||||||
$args = 0;
|
$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)';
|
$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';
|
$query .= ' FROM msz_comments_posts AS cpp';
|
||||||
|
|
||||||
if($hasParent) {
|
if($hasParentInfo) {
|
||||||
++$args;
|
++$args;
|
||||||
$query .= ' WHERE comment_reply_to = ?';
|
$query .= ' WHERE comment_reply_to = ?';
|
||||||
} else {
|
|
||||||
if($hasCategory) {
|
|
||||||
++$args;
|
|
||||||
$query .= ' WHERE category_id = ?';
|
|
||||||
}
|
}
|
||||||
|
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(!$includeReplies) {
|
// this should really not be implicit like this
|
||||||
$query .= (++$args > 1 ? ' AND' : ' WHERE');
|
if($hasParentInfo)
|
||||||
$query .= ' comment_reply_to IS NULL';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!$includeDeleted) {
|
|
||||||
$query .= (++$args > 1 ? ' AND' : ' WHERE');
|
|
||||||
$query .= ' comment_deleted IS NULL';
|
|
||||||
}
|
|
||||||
|
|
||||||
// this should probably not be implicit like this
|
|
||||||
if($hasParent)
|
|
||||||
$query .= ' ORDER BY comment_deleted ASC, comment_pinned DESC, comment_created ASC';
|
$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';
|
$query .= ' ORDER BY comment_deleted ASC, comment_pinned DESC, comment_created DESC';
|
||||||
else
|
else
|
||||||
$query .= ' ORDER BY comment_created DESC';
|
$query .= ' ORDER BY comment_created DESC';
|
||||||
|
|
||||||
$args = 0;
|
$args = 0;
|
||||||
$stmt = $this->cache->get($query);
|
$stmt = $this->cache->get($query);
|
||||||
if($hasParent)
|
if($hasParentInfo)
|
||||||
$stmt->addParameter(++$args, $parent);
|
$stmt->addParameter(++$args, $parentInfo);
|
||||||
elseif($hasCategory)
|
elseif($hasCategoryInfo)
|
||||||
$stmt->addParameter(++$args, $category);
|
$stmt->addParameter(++$args, $categoryInfo);
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
|
|
||||||
$posts = [];
|
$posts = [];
|
||||||
|
@ -339,7 +327,7 @@ class Comments {
|
||||||
return $posts;
|
return $posts;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPostById(
|
public function getPost(
|
||||||
string $postId,
|
string $postId,
|
||||||
bool $includeRepliesCount = false,
|
bool $includeRepliesCount = false,
|
||||||
bool $includeVotesCount = false
|
bool $includeVotesCount = false
|
||||||
|
@ -396,7 +384,7 @@ class Comments {
|
||||||
$stmt->addParameter(5, $pin ? 1 : 0);
|
$stmt->addParameter(5, $pin ? 1 : 0);
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
|
|
||||||
return $this->getPostById((string)$this->dbConn->getLastInsertId());
|
return $this->getPost((string)$this->dbConn->getLastInsertId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function deletePost(CommentsPostInfo|string $infoOrId): void {
|
public function deletePost(CommentsPostInfo|string $infoOrId): void {
|
||||||
|
|
|
@ -28,7 +28,7 @@ class CommentsEx {
|
||||||
$info->category = $category;
|
$info->category = $category;
|
||||||
$info->posts = [];
|
$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)
|
foreach($root as $postInfo)
|
||||||
$info->posts[] = $this->decorateComment($postInfo);
|
$info->posts[] = $this->decorateComment($postInfo);
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ class CommentsEx {
|
||||||
$info->vote = $this->comments->getPostVote($postInfo, $userInfo);
|
$info->vote = $this->comments->getPostVote($postInfo, $userInfo);
|
||||||
$info->replies = [];
|
$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)
|
foreach($root as $childInfo)
|
||||||
$info->replies[] = $this->decorateComment($childInfo);
|
$info->replies[] = $this->decorateComment($childInfo);
|
||||||
|
|
||||||
|
|
|
@ -9,14 +9,12 @@ class EmoteInfo implements Stringable {
|
||||||
private int $order;
|
private int $order;
|
||||||
private int $rank;
|
private int $rank;
|
||||||
private string $url;
|
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->id = (string)$result->getInteger(0);
|
||||||
$this->order = $result->getInteger(1);
|
$this->order = $result->getInteger(1);
|
||||||
$this->rank = $result->getInteger(2);
|
$this->rank = $result->getInteger(2);
|
||||||
$this->url = $result->getString(3);
|
$this->url = $result->getString(3);
|
||||||
$this->strings = $strings;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getId(): string {
|
public function getId(): string {
|
||||||
|
@ -35,17 +33,6 @@ class EmoteInfo implements Stringable {
|
||||||
return $this->url;
|
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 {
|
public function __toString(): string {
|
||||||
return $this->url;
|
return $this->url;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,18 +21,17 @@ class Emotes {
|
||||||
$this->cache = new DbStatementCache($dbConn);
|
$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 = $this->cache->get('SELECT emote_id, emote_order, emote_hierarchy, emote_url FROM msz_emoticons WHERE emote_id = ?');
|
||||||
$stmt->addParameter(1, $emoteId);
|
$stmt->addParameter(1, $emoteId);
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
|
|
||||||
$result = $stmt->getResult();
|
$result = $stmt->getResult();
|
||||||
|
|
||||||
if(!$result->next())
|
if(!$result->next())
|
||||||
throw new RuntimeException('No emoticon with that ID exists.');
|
throw new RuntimeException('No emoticon with that ID exists.');
|
||||||
|
|
||||||
$strings = $withStrings ? $this->getEmoteStrings($emoteId) : [];
|
return new EmoteInfo($result);
|
||||||
|
|
||||||
return new EmoteInfo($result, $strings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function emoteOrderOptions(): array {
|
public static function emoteOrderOptions(): array {
|
||||||
|
@ -40,32 +39,37 @@ class Emotes {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: pagination
|
// TODO: pagination
|
||||||
public function getAllEmotes(
|
public function getEmotes(
|
||||||
int $minRank = -1,
|
?int $minRank = null,
|
||||||
string $orderBy = '',
|
?string $orderBy = null,
|
||||||
bool $desc = false,
|
?bool $reverse = null
|
||||||
bool $withStrings = false
|
|
||||||
): array {
|
): array {
|
||||||
if($minRank < 0) $minRank = PHP_INT_MAX;
|
$hasMinRank = $minRank !== null;
|
||||||
$orderBy = self::EMOTE_ORDER[$orderBy] ?? self::EMOTE_ORDER[array_key_first(self::EMOTE_ORDER)];
|
$hasOrderBy = $orderBy !== null;
|
||||||
|
$hasReverse = $reverse !== null;
|
||||||
|
|
||||||
$stmt = $this->cache->get(sprintf(
|
$query = 'SELECT emote_id, emote_order, emote_hierarchy, emote_url FROM msz_emoticons';
|
||||||
'SELECT emote_id, emote_order, emote_hierarchy, emote_url FROM msz_emoticons WHERE emote_hierarchy <= ? ORDER BY %s %s',
|
if($hasMinRank)
|
||||||
$orderBy, ($desc ? 'DESC' : 'ASC')
|
$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->addParameter(1, $minRank);
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
|
|
||||||
$emotes = [];
|
$emotes = [];
|
||||||
$result = $stmt->getResult();
|
$result = $stmt->getResult();
|
||||||
|
|
||||||
if($withStrings) {
|
|
||||||
while($result->next())
|
|
||||||
$emotes[] = new EmoteInfo($result, $this->getEmoteStrings((string)$result->getInteger(0)));
|
|
||||||
} else {
|
|
||||||
while($result->next())
|
while($result->next())
|
||||||
$emotes[] = new EmoteInfo($result);
|
$emotes[] = new EmoteInfo($result);
|
||||||
}
|
|
||||||
|
|
||||||
return $emotes;
|
return $emotes;
|
||||||
}
|
}
|
||||||
|
@ -106,7 +110,7 @@ class Emotes {
|
||||||
$stmt->addParameter(3, $order);
|
$stmt->addParameter(3, $order);
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
|
|
||||||
return $this->getEmoteById((string)$this->dbConn->getLastInsertId());
|
return $this->getEmote((string)$this->dbConn->getLastInsertId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function deleteEmote(EmoteInfo|string $infoOrId): void {
|
public function deleteEmote(EmoteInfo|string $infoOrId): void {
|
||||||
|
|
|
@ -79,7 +79,7 @@ class HomeRoutes {
|
||||||
private array $newsCategoryInfos = [];
|
private array $newsCategoryInfos = [];
|
||||||
|
|
||||||
private function getFeaturedNewsPosts(int $amount, bool $decorate): array {
|
private function getFeaturedNewsPosts(int $amount, bool $decorate): array {
|
||||||
$postInfos = $this->news->getAllPosts(
|
$postInfos = $this->news->getPosts(
|
||||||
onlyFeatured: true,
|
onlyFeatured: true,
|
||||||
pagination: new Pagination($amount)
|
pagination: new Pagination($amount)
|
||||||
);
|
);
|
||||||
|
@ -112,10 +112,10 @@ class HomeRoutes {
|
||||||
if(array_key_exists($categoryId, $this->newsCategoryInfos))
|
if(array_key_exists($categoryId, $this->newsCategoryInfos))
|
||||||
$categoryInfo = $this->newsCategoryInfos[$categoryId];
|
$categoryInfo = $this->newsCategoryInfos[$categoryId];
|
||||||
else
|
else
|
||||||
$this->newsCategoryInfos[$categoryId] = $categoryInfo = $this->news->getCategoryByPost($postInfo);
|
$this->newsCategoryInfos[$categoryId] = $categoryInfo = $this->news->getCategory(postInfo: $postInfo);
|
||||||
|
|
||||||
$commentsCount = $postInfo->hasCommentsCategoryId()
|
$commentsCount = $postInfo->hasCommentsCategoryId()
|
||||||
? $this->comments->countPosts($postInfo->getCommentsCategoryId(), includeReplies: true) : 0;
|
? $this->comments->countPosts(categoryInfo: $postInfo->getCommentsCategoryId(), deleted: false) : 0;
|
||||||
|
|
||||||
$posts[] = [
|
$posts[] = [
|
||||||
'post' => $postInfo,
|
'post' => $postInfo,
|
||||||
|
@ -205,7 +205,7 @@ class HomeRoutes {
|
||||||
$stats = $this->getStats();
|
$stats = $this->getStats();
|
||||||
$onlineUserInfos = $this->getOnlineUsers();
|
$onlineUserInfos = $this->getOnlineUsers();
|
||||||
$featuredNews = $this->getFeaturedNewsPosts(5, true);
|
$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);
|
$stats['users:online:recent'] = count($onlineUserInfos);
|
||||||
|
|
||||||
|
|
|
@ -20,15 +20,6 @@ class News {
|
||||||
$this->cache = new DbStatementCache($dbConn);
|
$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 {
|
private function readPosts(IDbResult $result): array {
|
||||||
$posts = [];
|
$posts = [];
|
||||||
|
|
||||||
|
@ -38,10 +29,14 @@ class News {
|
||||||
return $posts;
|
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';
|
$query = 'SELECT COUNT(*) FROM msz_news_categories';
|
||||||
if($includeHidden)
|
if($hasHidden)
|
||||||
$query .= ' WHERE category_is_hidden = 0';
|
$query .= sprintf(' WHERE category_is_hidden %s 0', $hidden ? '<>' : '=');
|
||||||
|
|
||||||
$result = $this->dbConn->query($query);
|
$result = $this->dbConn->query($query);
|
||||||
$count = 0;
|
$count = 0;
|
||||||
|
@ -52,15 +47,16 @@ class News {
|
||||||
return $count;
|
return $count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAllCategories(
|
public function getCategories(
|
||||||
bool $includeHidden = false,
|
?bool $hidden = null,
|
||||||
?Pagination $pagination = null
|
?Pagination $pagination = null
|
||||||
): array {
|
): array {
|
||||||
|
$hasHidden = $hidden !== null;
|
||||||
$hasPagination = $pagination !== 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';
|
$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)
|
if($hasHidden)
|
||||||
$query .= ' WHERE category_is_hidden = 0';
|
$query .= sprintf(' WHERE category_is_hidden %s 0', $hidden ? '<>' : '=');
|
||||||
$query .= ' ORDER BY category_created ASC';
|
$query .= ' ORDER BY category_created ASC';
|
||||||
if($hasPagination)
|
if($hasPagination)
|
||||||
$query .= ' LIMIT ? OFFSET ?';
|
$query .= ' LIMIT ? OFFSET ?';
|
||||||
|
@ -74,39 +70,51 @@ class News {
|
||||||
|
|
||||||
$stmt->execute();
|
$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 {
|
public function getCategory(
|
||||||
$query = 'SELECT category_id, category_name, category_description, category_is_hidden, UNIX_TIMESTAMP(category_created) FROM msz_news_categories WHERE category_id = ';
|
?string $categoryId = null,
|
||||||
|
NewsPostInfo|string|null $postInfo = null
|
||||||
|
): NewsCategoryInfo {
|
||||||
|
$hasCategoryId = $categoryId !== null;
|
||||||
|
$hasPostInfo = $postInfo !== null;
|
||||||
|
|
||||||
|
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) {
|
if($postInfo instanceof NewsPostInfo) {
|
||||||
$query .= '?';
|
$query .= ' WHERE category_id = ?';
|
||||||
$param = $postInfo->getCategoryId();
|
$value = $postInfo->getCategoryId();
|
||||||
} else {
|
} else {
|
||||||
$query .= '(SELECT category_id FROM msz_news_posts WHERE post_id = ?)';
|
$query .= ' WHERE category_id = (SELECT category_id FROM msz_news_posts WHERE post_id = ?)';
|
||||||
$param = $postInfo;
|
$value = $postInfo;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$stmt = $this->cache->get($query);
|
$stmt = $this->cache->get($query);
|
||||||
$stmt->addParameter(1, $param);
|
$stmt->addParameter(1, $value);
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
|
|
||||||
$result = $stmt->getResult();
|
$result = $stmt->getResult();
|
||||||
if(!$result->next())
|
if(!$result->next())
|
||||||
throw new RuntimeException('No news category associated with that ID exists.');
|
throw new RuntimeException('News category not found.');
|
||||||
|
|
||||||
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.');
|
|
||||||
|
|
||||||
return new NewsCategoryInfo($result);
|
return new NewsCategoryInfo($result);
|
||||||
}
|
}
|
||||||
|
@ -130,7 +138,7 @@ class News {
|
||||||
$stmt->addParameter(3, $hidden ? 1 : 0);
|
$stmt->addParameter(3, $hidden ? 1 : 0);
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
|
|
||||||
return $this->getCategoryById((string)$this->dbConn->getLastInsertId());
|
return $this->getCategory(categoryId: (string)$this->dbConn->getLastInsertId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function deleteCategory(NewsCategoryInfo|string $infoOrId): void {
|
public function deleteCategory(NewsCategoryInfo|string $infoOrId): void {
|
||||||
|
@ -174,16 +182,26 @@ class News {
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function countAllPosts(
|
public function countPosts(
|
||||||
|
NewsCategoryInfo|string|null $categoryInfo = null,
|
||||||
bool $onlyFeatured = false,
|
bool $onlyFeatured = false,
|
||||||
bool $includeScheduled = false,
|
bool $includeScheduled = false,
|
||||||
bool $includeDeleted = false
|
bool $includeDeleted = false
|
||||||
): int {
|
): int {
|
||||||
|
if($categoryInfo instanceof NewsCategoryInfo)
|
||||||
|
$categoryInfo = $categoryInfo->getId();
|
||||||
|
|
||||||
|
$hasCategoryInfo = $categoryInfo !== null;
|
||||||
|
|
||||||
$args = 0;
|
$args = 0;
|
||||||
$query = 'SELECT COUNT(*) FROM msz_news_posts';
|
$query = 'SELECT COUNT(*) FROM msz_news_posts';
|
||||||
if($onlyFeatured) {
|
if($hasCategoryInfo) {
|
||||||
++$args;
|
++$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) {
|
if(!$includeScheduled) {
|
||||||
$query .= (++$args > 1 ? ' AND' : ' WHERE');
|
$query .= (++$args > 1 ? ' AND' : ' WHERE');
|
||||||
|
@ -194,33 +212,8 @@ class News {
|
||||||
$query .= ' post_deleted IS NULL';
|
$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 = $this->cache->get($query);
|
||||||
|
if($hasCategoryInfo)
|
||||||
$stmt->addParameter(1, $categoryInfo);
|
$stmt->addParameter(1, $categoryInfo);
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
|
|
||||||
|
@ -233,22 +226,34 @@ class News {
|
||||||
return $count;
|
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';
|
public function getPosts(
|
||||||
private const POSTS_SELECT_ORDER = ' ORDER BY post_scheduled DESC';
|
NewsCategoryInfo|string|null $categoryInfo = null,
|
||||||
|
string $searchQuery = null,
|
||||||
public function getAllPosts(
|
|
||||||
bool $onlyFeatured = false,
|
bool $onlyFeatured = false,
|
||||||
bool $includeScheduled = false,
|
bool $includeScheduled = false,
|
||||||
bool $includeDeleted = false,
|
bool $includeDeleted = false,
|
||||||
?Pagination $pagination = null
|
?Pagination $pagination = null
|
||||||
): array {
|
): array {
|
||||||
$args = 0;
|
if($categoryInfo instanceof NewsCategoryInfo)
|
||||||
|
$categoryInfo = $categoryInfo->getId();
|
||||||
|
|
||||||
|
$hasCategoryInfo = $categoryInfo !== null;
|
||||||
|
$hasSearchQuery = $searchQuery !== null;
|
||||||
$hasPagination = $pagination !== null;
|
$hasPagination = $pagination !== null;
|
||||||
|
|
||||||
$query = self::POSTS_SELECT_QUERY;
|
$args = 0;
|
||||||
if($onlyFeatured) {
|
$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;
|
++$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) {
|
if(!$includeScheduled) {
|
||||||
$query .= (++$args > 1 ? ' AND' : ' WHERE');
|
$query .= (++$args > 1 ? ' AND' : ' WHERE');
|
||||||
|
@ -258,79 +263,15 @@ class News {
|
||||||
$query .= (++$args > 1 ? ' AND' : ' WHERE');
|
$query .= (++$args > 1 ? ' AND' : ' WHERE');
|
||||||
$query .= ' post_deleted IS NULL';
|
$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($hasPagination) {
|
|
||||||
$stmt->addParameter(++$args, $pagination->getRange());
|
|
||||||
$stmt->addParameter(++$args, $pagination->getOffset());
|
|
||||||
}
|
|
||||||
|
|
||||||
$stmt->execute();
|
|
||||||
|
|
||||||
return self::readPosts($stmt->getResult());
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
if($hasPagination)
|
||||||
$query .= ' LIMIT ? OFFSET ?';
|
$query .= ' LIMIT ? OFFSET ?';
|
||||||
$stmt = $this->cache->get($query);
|
$stmt = $this->cache->get($query);
|
||||||
|
|
||||||
$args = 0;
|
$args = 0;
|
||||||
|
if($hasCategoryInfo)
|
||||||
$stmt->addParameter(++$args, $categoryInfo);
|
$stmt->addParameter(++$args, $categoryInfo);
|
||||||
if($hasPagination) {
|
if($hasSearchQuery)
|
||||||
$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);
|
$stmt->addParameter(++$args, $searchQuery);
|
||||||
if($hasPagination) {
|
if($hasPagination) {
|
||||||
$stmt->addParameter(++$args, $pagination->getRange());
|
$stmt->addParameter(++$args, $pagination->getRange());
|
||||||
|
@ -339,10 +280,16 @@ class News {
|
||||||
|
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
|
|
||||||
return self::readPosts($stmt->getResult());
|
$result = $stmt->getResult();
|
||||||
|
$posts = [];
|
||||||
|
|
||||||
|
while($result->next())
|
||||||
|
$posts[] = new NewsPostInfo($result);
|
||||||
|
|
||||||
|
return $posts;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 = $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->addParameter(1, $postId);
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
|
@ -386,7 +333,7 @@ class News {
|
||||||
$stmt->addParameter(6, $schedule);
|
$stmt->addParameter(6, $schedule);
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
|
|
||||||
return $this->getPostById((string)$this->dbConn->getLastInsertId());
|
return $this->getPost((string)$this->dbConn->getLastInsertId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function deletePost(NewsPostInfo|string $postInfo): void {
|
public function deletePost(NewsPostInfo|string $postInfo): void {
|
||||||
|
|
|
@ -118,9 +118,11 @@ class NewsRoutes {
|
||||||
|
|
||||||
private function getNewsPostsForView(Pagination $pagination, ?NewsCategoryInfo $categoryInfo = null): array {
|
private function getNewsPostsForView(Pagination $pagination, ?NewsCategoryInfo $categoryInfo = null): array {
|
||||||
$posts = [];
|
$posts = [];
|
||||||
$postInfos = $categoryInfo === null
|
$postInfos = $this->news->getPosts(
|
||||||
? $this->news->getAllPosts(onlyFeatured: true, pagination: $pagination)
|
categoryInfo: $categoryInfo,
|
||||||
: $this->news->getPostsByCategory($categoryInfo, pagination: $pagination);
|
onlyFeatured: $categoryInfo === null,
|
||||||
|
pagination: $pagination
|
||||||
|
);
|
||||||
|
|
||||||
foreach($postInfos as $postInfo) {
|
foreach($postInfos as $postInfo) {
|
||||||
$userId = $postInfo->getUserId();
|
$userId = $postInfo->getUserId();
|
||||||
|
@ -153,10 +155,10 @@ class NewsRoutes {
|
||||||
if(array_key_exists($categoryId, $this->categoryInfos))
|
if(array_key_exists($categoryId, $this->categoryInfos))
|
||||||
$categoryInfo = $this->categoryInfos[$categoryId];
|
$categoryInfo = $this->categoryInfos[$categoryId];
|
||||||
else
|
else
|
||||||
$this->categoryInfos[$categoryId] = $categoryInfo = $this->news->getCategoryByPost($postInfo);
|
$this->categoryInfos[$categoryId] = $categoryInfo = $this->news->getCategory(postInfo: $postInfo);
|
||||||
|
|
||||||
$commentsCount = $postInfo->hasCommentsCategoryId()
|
$commentsCount = $postInfo->hasCommentsCategoryId()
|
||||||
? $this->comments->countPosts($postInfo->getCommentsCategoryId(), includeReplies: true)
|
? $this->comments->countPosts(categoryInfo: $postInfo->getCommentsCategoryId(), deleted: false)
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
$posts[] = [
|
$posts[] = [
|
||||||
|
@ -173,9 +175,11 @@ class NewsRoutes {
|
||||||
|
|
||||||
private function getNewsPostsForFeed(?NewsCategoryInfo $categoryInfo = null): array {
|
private function getNewsPostsForFeed(?NewsCategoryInfo $categoryInfo = null): array {
|
||||||
$posts = [];
|
$posts = [];
|
||||||
$postInfos = $categoryInfo === null
|
$postInfos = $this->news->getPosts(
|
||||||
? $this->news->getAllPosts(onlyFeatured: true, pagination: new Pagination(10))
|
categoryInfo: $categoryInfo,
|
||||||
: $this->news->getPostsByCategory($categoryInfo, pagination: new Pagination(10));
|
onlyFeatured: $categoryInfo === null,
|
||||||
|
pagination: new Pagination(10)
|
||||||
|
);
|
||||||
|
|
||||||
foreach($postInfos as $postInfo) {
|
foreach($postInfos as $postInfo) {
|
||||||
$userId = $postInfo->getUserId();
|
$userId = $postInfo->getUserId();
|
||||||
|
@ -204,9 +208,9 @@ class NewsRoutes {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getIndex() {
|
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())
|
if(!$pagination->hasValidOffset())
|
||||||
return 404;
|
return 404;
|
||||||
|
|
||||||
|
@ -232,7 +236,7 @@ class NewsRoutes {
|
||||||
$type = pathinfo($fileName, PATHINFO_EXTENSION);
|
$type = pathinfo($fileName, PATHINFO_EXTENSION);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$categoryInfo = $this->news->getCategoryById($categoryId);
|
$categoryInfo = $this->news->getCategory(categoryId: $categoryId);
|
||||||
} catch(RuntimeException $ex) {
|
} catch(RuntimeException $ex) {
|
||||||
return 404;
|
return 404;
|
||||||
}
|
}
|
||||||
|
@ -244,7 +248,7 @@ class NewsRoutes {
|
||||||
elseif($type !== '')
|
elseif($type !== '')
|
||||||
return 404;
|
return 404;
|
||||||
|
|
||||||
$pagination = new Pagination($this->news->countPostsByCategory($categoryInfo), 5);
|
$pagination = new Pagination($this->news->countPosts(categoryInfo: $categoryInfo), 5);
|
||||||
if(!$pagination->hasValidOffset())
|
if(!$pagination->hasValidOffset())
|
||||||
return 404;
|
return 404;
|
||||||
|
|
||||||
|
@ -267,7 +271,7 @@ class NewsRoutes {
|
||||||
|
|
||||||
public function getPost($response, $request, string $postId) {
|
public function getPost($response, $request, string $postId) {
|
||||||
try {
|
try {
|
||||||
$postInfo = $this->news->getPostById($postId);
|
$postInfo = $this->news->getPost($postId);
|
||||||
} catch(RuntimeException $ex) {
|
} catch(RuntimeException $ex) {
|
||||||
return 404;
|
return 404;
|
||||||
}
|
}
|
||||||
|
@ -275,11 +279,11 @@ class NewsRoutes {
|
||||||
if(!$postInfo->isPublished() || $postInfo->isDeleted())
|
if(!$postInfo->isPublished() || $postInfo->isDeleted())
|
||||||
return 404;
|
return 404;
|
||||||
|
|
||||||
$categoryInfo = $this->news->getCategoryByPost($postInfo);
|
$categoryInfo = $this->news->getCategory(postInfo: $postInfo);
|
||||||
|
|
||||||
if($postInfo->hasCommentsCategoryId())
|
if($postInfo->hasCommentsCategoryId())
|
||||||
try {
|
try {
|
||||||
$commentsCategory = $this->comments->getCategoryById($postInfo->getCommentsCategoryId());
|
$commentsCategory = $this->comments->getCategory(categoryId: $postInfo->getCommentsCategoryId());
|
||||||
} catch(RuntimeException $ex) {}
|
} catch(RuntimeException $ex) {}
|
||||||
|
|
||||||
if(!isset($commentsCategory)) {
|
if(!isset($commentsCategory)) {
|
||||||
|
|
|
@ -81,13 +81,13 @@ final class SharpChatRoutes {
|
||||||
$response->setHeader('Access-Control-Allow-Origin', '*');
|
$response->setHeader('Access-Control-Allow-Origin', '*');
|
||||||
$response->setHeader('Access-Control-Allow-Methods', 'GET');
|
$response->setHeader('Access-Control-Allow-Methods', 'GET');
|
||||||
|
|
||||||
$emotes = $this->emotes->getAllEmotes(withStrings: true);
|
$emotes = $this->emotes->getEmotes();
|
||||||
$out = [];
|
$out = [];
|
||||||
|
|
||||||
foreach($emotes as $emoteInfo) {
|
foreach($emotes as $emoteInfo) {
|
||||||
$strings = [];
|
$strings = [];
|
||||||
|
|
||||||
foreach($emoteInfo->getStrings() as $stringInfo)
|
foreach($this->emotes->getEmoteStrings($emoteInfo) as $stringInfo)
|
||||||
$strings[] = sprintf(':%s:', $stringInfo->getString());
|
$strings[] = sprintf(':%s:', $stringInfo->getString());
|
||||||
|
|
||||||
$out[] = [
|
$out[] = [
|
||||||
|
|
|
@ -42,9 +42,9 @@
|
||||||
</time>
|
</time>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{% if change_info.tags|length > 0 %}
|
{% if change_tags|length > 0 %}
|
||||||
<ul class="changelog__change__tags">
|
<ul class="changelog__change__tags">
|
||||||
{% for tag in change_info.tags %}
|
{% for tag in change_tags %}
|
||||||
<li class="changelog__change__tag" title="{{ tag.description }}">
|
<li class="changelog__change__tag" title="{{ tag.description }}">
|
||||||
<a href="{{ url('changelog-index', {'tags': tag.id}) }}" class="changelog__change__tag__link">
|
<a href="{{ url('changelog-index', {'tags': tag.id}) }}" class="changelog__change__tag__link">
|
||||||
{{ tag.name }}
|
{{ tag.name }}
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
{% macro changelog_entry(change, is_small, is_manage) %}
|
{% macro changelog_entry(change, is_small, is_manage) %}
|
||||||
{% set user = change.user|default(null) %}
|
{% set user = change.user|default(null) %}
|
||||||
{% set user_colour = change.user_colour|default(null) %}
|
{% set user_colour = change.user_colour|default(null) %}
|
||||||
|
{% set tags = change.tags|default([]) %}
|
||||||
{% if change.change is defined %}
|
{% if change.change is defined %}
|
||||||
{% set change = change.change %}
|
{% set change = change.change %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -74,7 +75,7 @@
|
||||||
|
|
||||||
{% if is_manage %}
|
{% if is_manage %}
|
||||||
<div class="changelog__entry__tags">
|
<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">
|
<a href="{{ is_manage ? url('manage-changelog-tag', {'tag': tag.id}) : url('changelog-index', {'tags': tag.id}) }}" class="changelog__entry__tag">
|
||||||
{{ tag.name }}
|
{{ tag.name }}
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
<label class="manage__tag">
|
<label class="manage__tag">
|
||||||
<div class="manage__tag__background"></div>
|
<div class="manage__tag__background"></div>
|
||||||
<div class="manage__tag__content">
|
<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">
|
<div class="manage__tag__title">
|
||||||
{{ tag.name }}
|
{{ tag.name }}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
<label class="manage__emote__field">
|
<label class="manage__emote__field">
|
||||||
<div class="manage__emote__field__name">Strings</div>
|
<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>
|
</label>
|
||||||
|
|
||||||
<div class="manage__emote__actions">
|
<div class="manage__emote__actions">
|
||||||
|
|
Loading…
Reference in a new issue