misuzu/src/Changelog/ChangelogRoutes.php
flashwave 7353553de7 Rewrote the comments system. ()
old one basically bitrotted to death, may it rinse in prosciutto

Reviewed-on: 
Co-authored-by: flashwave <me@flash.moe>
Co-committed-by: flashwave <me@flash.moe>
2025-02-20 02:19:32 +00:00

150 lines
5.9 KiB
PHP

<?php
namespace Misuzu\Changelog;
use ErrorException;
use RuntimeException;
use Index\Http\{HttpRequest,HttpResponseBuilder};
use Index\Http\Routing\{HttpGet,RouteHandler,RouteHandlerCommon};
use Index\Syndication\FeedBuilder;
use Index\Urls\{UrlFormat,UrlRegistry,UrlSource,UrlSourceCommon};
use Misuzu\{Pagination,SiteInfo,Template};
use Misuzu\Auth\AuthInfo;
use Misuzu\Comments\CommentsContext;
use Misuzu\Users\UsersContext;
final class ChangelogRoutes implements RouteHandler, UrlSource {
use RouteHandlerCommon, UrlSourceCommon;
public function __construct(
private SiteInfo $siteInfo,
private UrlRegistry $urls,
private ChangelogData $changelog,
private UsersContext $usersCtx,
private CommentsContext $commentsCtx,
private AuthInfo $authInfo,
) {}
#[HttpGet('/changelog')]
#[UrlFormat('changelog-index', '/changelog', ['date' => '<date>', 'user' => '<user>', 'tags' => '<tags>', 'p' => '<page>'])]
public function getIndex(HttpResponseBuilder $response, HttpRequest $request): int|string {
$filterDate = (string)$request->getParam('date');
$filterUser = (string)$request->getParam('user', FILTER_SANITIZE_NUMBER_INT);
$filterTags = (string)$request->getParam('tags');
if(empty($filterDate))
$filterDate = null;
else
try {
$dateParts = explode('-', $filterDate, 3);
$filterDate = gmmktime(12, 0, 0, (int)$dateParts[1], (int)$dateParts[2], (int)$dateParts[0]);
} catch(ErrorException $ex) {
return 404;
}
if(empty($filterUser))
$filterUser = null;
else
try {
$filterUser = $this->usersCtx->getUserInfo($filterUser);
} catch(RuntimeException $ex) {
return 404;
}
if(empty($filterTags))
$filterTags = null;
else {
$filterTags = explode(',', $filterTags);
foreach($filterTags as &$tag)
$tag = trim($tag);
}
$count = $this->changelog->countChanges($filterUser, $filterDate, $filterTags);
$pagination = Pagination::fromRequest($request, $count, 30, 'p');
if(!$pagination->validOffset)
return 404;
$changes = [];
$changeInfos = $this->changelog->getChanges(userInfo: $filterUser, dateTime: $filterDate, tags: $filterTags, pagination: $pagination);
$commentsCategoryName = null;
foreach($changeInfos as $changeInfo) {
$userInfo = $changeInfo->userId !== null ? $this->usersCtx->getUserInfo($changeInfo->userId) : null;
if($commentsCategoryName === null)
$commentsCategoryName = $changeInfo->commentsCategoryName;
$changes[] = [
'change' => $changeInfo,
'user' => $userInfo,
'user_colour' => $this->usersCtx->getUserColour($userInfo),
];
}
if(empty($changes))
return 404;
if(empty($filterDate))
$commentsCategoryName = null;
elseif($commentsCategoryName) // should this be run here?
$this->commentsCtx->categories->ensureCategoryExists($commentsCategoryName);
return Template::renderRaw('changelog.index', [
'changelog_infos' => $changes,
'changelog_date' => $filterDate,
'changelog_user' => $filterUser,
'changelog_tags' => $filterTags,
'changelog_pagination' => $pagination,
'comments_category_name' => $commentsCategoryName,
]);
}
#[HttpGet('/changelog/change/([0-9]+)')]
#[UrlFormat('changelog-change', '/changelog/change/<change>')]
#[UrlFormat('changelog-change-comments', '/changelog/change/<change>', fragment: 'comments')]
public function getChange(HttpResponseBuilder $response, HttpRequest $request, string $changeId): int|string {
try {
$changeInfo = $this->changelog->getChange($changeId);
} catch(RuntimeException $ex) {
return 404;
}
$tagInfos = $this->changelog->getTags(changeInfo: $changeInfo);
$userInfo = $changeInfo->userId !== null ? $this->usersCtx->getUserInfo($changeInfo->userId) : null;
// should this be run here?
$this->commentsCtx->categories->ensureCategoryExists($changeInfo->commentsCategoryName);
return Template::renderRaw('changelog.change', [
'change_info' => $changeInfo,
'change_tags' => $tagInfos,
'change_user_info' => $userInfo,
'change_user_colour' => $this->usersCtx->getUserColour($userInfo),
]);
}
#[HttpGet('/changelog.(xml|rss|atom)')]
#[UrlFormat('changelog-feed', '/changelog.xml')]
public function getFeed(HttpResponseBuilder $response): string {
$response->setContentType('application/rss+xml; charset=utf-8');
$siteName = $this->siteInfo->name;
$siteUrl = $this->siteInfo->url;
$changes = $this->changelog->getChanges(pagination: new Pagination(10));
$feed = new FeedBuilder;
$feed->title = sprintf('%s » Changelog', $siteName);
$feed->description = sprintf('Live feed of changes to %s.', $siteName);
$feed->contentUrl = $siteUrl . $this->urls->format('changelog-index');
$feed->feedUrl = $siteUrl . $this->urls->format('changelog-feed');
foreach($changes as $change)
$feed->createEntry(function($item) use ($change, $siteUrl) {
$item->title = sprintf('%s: %s', $change->actionText, $change->summary);
$item->createdAt = $change->createdTime;
$item->contentUrl = $siteUrl . $this->urls->format('changelog-change', ['change' => $change->id]);
$item->commentsUrl = $siteUrl . $this->urls->format('changelog-change-comments', ['change' => $change->id]);
});
return $feed->toXmlString();
}
}