From f49564db23e6b60aad396752be0e4d9de109b61e Mon Sep 17 00:00:00 2001 From: joyqi Date: Wed, 6 Apr 2022 18:26:15 +0800 Subject: [PATCH] Add feed widget --- var/Widget/Archive.php | 3 +- var/Widget/Feed.php | 129 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 var/Widget/Feed.php diff --git a/var/Widget/Archive.php b/var/Widget/Archive.php index 6f70b23e..540f6701 100644 --- a/var/Widget/Archive.php +++ b/var/Widget/Archive.php @@ -1012,7 +1012,8 @@ class Archive extends Contents $linkText = empty($title) ? $content['title'] : $title; $linkClass = empty($tagClass) ? '' : 'class="' . $tagClass . '" '; - $link = '' . $linkText . ''; + $link = '' . $linkText . ''; printf($format, $link); } else { diff --git a/var/Widget/Feed.php b/var/Widget/Feed.php new file mode 100644 index 00000000..a6d22884 --- /dev/null +++ b/var/Widget/Feed.php @@ -0,0 +1,129 @@ +setDefault([ + 'pageSize' => 10, + ]); + } + + /** + * @throws Exception + */ + public function execute() + { + $feedPath = $this->request->feed; + $feedType = FeedGenerator::RSS2; + $feedContentType = 'application/rss+xml'; + $currentFeedUrl = $this->options->feedUrl; + $isComments = false; + + /** 判断聚合类型 */ + switch (true) { + case preg_match("/^\/rss(\/|$)/", $feedPath): + /** 如果是RSS1标准 */ + $feedPath = substr($feedPath, 4); + $feedType = FeedGenerator::RSS1; + $currentFeedUrl = $this->options->feedRssUrl; + $feedContentType = 'application/rdf+xml'; + break; + case preg_match("/^\/atom(\/|$)/", $feedPath): + /** 如果是ATOM标准 */ + $feedPath = substr($feedPath, 5); + $feedType = FeedGenerator::ATOM1; + $currentFeedUrl = $this->options->feedAtomUrl; + $feedContentType = 'application/atom+xml'; + break; + default: + break; + } + + $feed = new FeedGenerator( + Common::VERSION, + $feedType, + $this->options->charset, + _t('zh-CN') + ); + + if (preg_match("/^\/comments\/?$/", $feedPath)) { + $isComments = true; + $currentFeedUrl = Common::url('/comments/', $currentFeedUrl); + $feed->setBaseUrl($this->options->siteUrl); + $feed->setSubTitle($this->options->description); + } else { + $archive = Router::match($feedPath, [ + 'pageSize' => $this->parameter->pageSize, + 'isFeed' => true + ]); + + if (!($archive instanceof Archive)) { + throw new WidgetException(_t('聚合页不存在'), 404); + } + + $path = parse_url($archive->getArchiveUrl(), PHP_URL_PATH); + $currentFeedUrl = Common::url($path, $currentFeedUrl); + $feed->setBaseUrl($archive->getArchiveUrl()); + $feed->setSubTitle($archive->getDescription()); + } + + $this->checkPermalink($currentFeedUrl); + $feed->setFeedUrl($currentFeedUrl); + $this->render($feed, $feedContentType, $isComments, $archive ?? null); + } + + /** + * @param FeedGenerator $feed + * @param string $contentType + * @param bool $isComments + * @param Archive|null $archive + */ + public function render( + FeedGenerator $feed, + string $contentType, + bool $isComments, + ?Archive $archive + ) { + if ($isComments || $archive->is('single')) { + $feed->setTitle(_t( + '%s 的评论', + $this->options->title . ($isComments ? '' : ' - ' . $archive->getArchiveTitle()) + )); + } else { + $feed->setTitle($this->options->title + . ($archive->getArchiveTitle() ? ' - ' . $archive->getArchiveTitle() : '')); + } + } + + /** + * @param string $feedUrl + */ + private function checkPermalink(string $feedUrl) + { + if ($feedUrl != $this->request->getRequestUri()) { + $this->response->redirect($feedUrl, true); + } + } +}