old one basically bitrotted to death, may it rinse in prosciutto Reviewed-on: #1 Co-authored-by: flashwave <me@flash.moe> Co-committed-by: flashwave <me@flash.moe>
150 lines
5.9 KiB
PHP
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();
|
|
}
|
|
}
|