diff --git a/install.php b/install.php index 06b05ee6..362cee78 100644 --- a/install.php +++ b/install.php @@ -205,8 +205,8 @@ function install_get_default_routers(): array 'comment_page' => [ 'url' => '[permalink:string]/comment-page-[commentPage:digital]', - 'widget' => '\Widget\Archive', - 'action' => 'render', + 'widget' => '\Widget\CommentPage', + 'action' => 'action', ], 'feed' => [ diff --git a/var/Typecho/Router.php b/var/Typecho/Router.php index 35a013da..8b4d8f6d 100644 --- a/var/Typecho/Router.php +++ b/var/Typecho/Router.php @@ -15,7 +15,6 @@ class Router /** * 当前路由名称 * - * @access public * @var string */ public static $current; @@ -23,24 +22,34 @@ class Router /** * 已经解析完毕的路由表配置 * - * @access private - * @var mixed + * @var array */ private static $routingTable = []; /** - * 解析路径 + * 是否已经匹配过,防止递归匹配 * - * @access public + * @var bool + */ + private static $matched = false; + + /** + * 解析路径 * * @param string|null $pathInfo 全路径 * @param mixed $parameter 输入参数 - * + * @param bool $once 是否只匹配一次 * @return false|Widget * @throws \Exception */ - public static function match(?string $pathInfo, $parameter = null) + public static function match(?string $pathInfo, $parameter = null, bool $once = true) { + if ($once && self::$matched) { + throw new RouterException("Path '{$pathInfo}' not found", 404); + } + + self::$matched = true; + foreach (self::$routingTable as $key => $route) { if (preg_match($route['regx'], $pathInfo, $matches)) { self::$current = $key; @@ -122,7 +131,6 @@ class Router * @param string $name 路由配置表名称 * @param array|null $value 路由填充值 * @param string|null $prefix 最终合成路径的前缀 - * * @return string */ public static function url(string $name, ?array $value = null, ?string $prefix = null): string @@ -141,10 +149,7 @@ class Router /** * 设置路由器默认配置 * - * @access public - * * @param mixed $routes 配置信息 - * * @return void */ public static function setRoutes($routes) @@ -162,9 +167,6 @@ class Router * 获取路由信息 * * @param string $routeName 路由名称 - * - * @static - * @access public * @return mixed */ public static function get(string $routeName) diff --git a/var/Widget/Archive.php b/var/Widget/Archive.php index b454ff27..9a93caad 100644 --- a/var/Widget/Archive.php +++ b/var/Widget/Archive.php @@ -187,7 +187,8 @@ class Archive extends Contents 'pageSize' => $this->options->pageSize, 'type' => null, 'checkPermalink' => true, - 'preview' => false + 'preview' => false, + 'commentPage' => 0 ]); /** 用于判断是路由调用还是外部调用 */ @@ -512,7 +513,6 @@ class Archive extends Contents 'page' => 'singleHandle', 'post' => 'singleHandle', 'attachment' => 'singleHandle', - 'comment_page' => 'singleHandle', 'category' => 'categoryHandle', 'category_page' => 'categoryHandle', 'tag' => 'tagHandle', @@ -794,7 +794,7 @@ class Archive extends Contents 'parentId' => $this->hidden ? 0 : $this->cid, 'parentContent' => $this->row, 'respondId' => $this->respondId, - 'commentPage' => $this->request->filter('int')->commentPage, + 'commentPage' => $this->parameter->commentPage, 'allowComment' => $this->allow('comment') ]; @@ -1358,41 +1358,6 @@ class Archive extends Contents return $commentUrl; } - /** - * 导入对象 - * - * @param Archive $widget 需要导入的对象 - */ - private function import(Archive $widget) - { - $currentProperties = get_object_vars($this); - - foreach ($currentProperties as $name => $value) { - if (false !== strpos('|request|response|parameter|feed|feedType|currentFeedUrl|', '|' . $name . '|')) { - continue; - } - - if (isset($widget->{$name})) { - $this->{$name} = $widget->{$name}; - } else { - $method = ucfirst($name); - $setMethod = 'set' . $method; - $getMethod = 'get' . $method; - - if ( - method_exists($this, $setMethod) - && method_exists($widget, $getMethod) - ) { - $value = $widget->{$getMethod}(); - - if ($value !== null) { - $this->{$setMethod}($widget->{$getMethod}()); - } - } - } - } - } - /** * 检查链接是否正确 * @@ -1404,7 +1369,7 @@ class Archive extends Contents $type = $this->parameter->type; if ( - in_array($type, ['index', 'comment_page', 404]) + in_array($type, ['index', 404]) || $this->makeSinglePageAsFrontPage // 自定义首页不处理 || !$this->parameter->checkPermalink ) { // 强制关闭 @@ -1500,17 +1465,6 @@ class Archive extends Contents */ private function singleHandle(Query $select, bool &$hasPushed) { - if ('comment_page' == $this->parameter->type) { - $params = []; - $matched = Router::match($this->request->permalink); - - if ($matched && $matched instanceof Archive && $matched->is('single')) { - $this->import($matched); - $hasPushed = true; - return; - } - } - /** 将这两个设置提前是为了保证在调用query的plugin时可以在插件中使用is判断初步归档类型 */ /** 如果需要更细判断,则可以使用singleHandle来实现 */ $this->archiveSingle = true; diff --git a/var/Widget/CommentPage.php b/var/Widget/CommentPage.php new file mode 100644 index 00000000..be6bd1b2 --- /dev/null +++ b/var/Widget/CommentPage.php @@ -0,0 +1,50 @@ +<?php + +namespace Widget; + +use Exception; +use Typecho\Router; +use Typecho\Widget\Exception as WidgetException; + +/** + * Comment Page Widget + */ +class CommentPage extends Base implements ActionInterface +{ + /** + * Perform comment page action + * + * @throws Exception + */ + public function action() + { + $page = abs($this->request->filter('int')->get('commentPage')); + + $archive = Router::match($this->request->permalink, [ + 'checkPermalink' => false, + 'commentPage' => $page + ]); + + if (!($archive instanceof Archive) || !$archive->is('single')) { + throw new WidgetException(_t('请求的地址不存在'), 404); + } + + $currentCommentUrl = Router::url('comment_page', [ + 'permalink' => $archive->pathinfo, + 'commentPage' => $page + ], $this->options->index); + + $this->checkPermalink($currentCommentUrl); + $archive->render(); + } + + /** + * @param string $commentUrl + */ + private function checkPermalink(string $commentUrl) + { + if ($commentUrl != $this->request->getRequestUrl()) { + $this->response->redirect($commentUrl, true); + } + } +} diff --git a/var/Widget/XmlRpc.php b/var/Widget/XmlRpc.php index 3bd06b18..b1153fd0 100644 --- a/var/Widget/XmlRpc.php +++ b/var/Widget/XmlRpc.php @@ -181,7 +181,7 @@ class XmlRpc extends Contents implements ActionInterface, Hook 'link' => $page->permalink, 'permaLink' => $page->permalink, 'categories' => $page->categories, - 'excerpt' => $page->description, + 'excerpt' => $page->plainExcerpt, 'text_more' => $more, 'mt_allow_comments' => intval($page->allowComment), 'mt_allow_pings' => intval($page->allowPing), @@ -287,7 +287,7 @@ class XmlRpc extends Contents implements ActionInterface, Hook 'link' => $pages->permalink, 'permaLink' => $pages->permalink, 'categories' => $pages->categories, - 'excerpt' => $pages->description, + 'excerpt' => $pages->plainExcerpt, 'text_more' => $more, 'mt_allow_comments' => intval($pages->allowComment), 'mt_allow_pings' => intval($pages->allowPing), @@ -1256,7 +1256,7 @@ class XmlRpc extends Contents implements ActionInterface, Hook 'link' => $post->permalink, 'permaLink' => $post->permalink, 'categories' => $categories, - 'mt_excerpt' => $post->description, + 'mt_excerpt' => $post->plainExcerpt, 'mt_text_more' => $more, 'mt_allow_comments' => intval($post->allowComment), 'mt_allow_pings' => intval($post->allowPing), @@ -1306,7 +1306,7 @@ class XmlRpc extends Contents implements ActionInterface, Hook 'link' => $posts->permalink, 'permaLink' => $posts->permalink, 'categories' => $categories, - 'mt_excerpt' => $posts->description, + 'mt_excerpt' => $posts->plainExcerpt, 'mt_text_more' => $more, 'wp_more_text' => $more, 'mt_allow_comments' => intval($posts->allowComment),