setDefault([ 'parentId' => 0, 'respondId' => '', 'commentPage' => 0, 'commentsNum' => 0, 'allowComment' => 1, 'parentContent' => null, ]); } /** * 输出文章评论数 * * @param ...$args */ public function num(...$args) { if (empty($args)) { $args[] = '%d'; } $num = $this->total; echo sprintf($args[$num] ?? array_pop($args), $num); } /** * 执行函数 * * @access public * @return void */ public function execute() { if (!$this->parameter->parentId) { return; } $unapprovedCommentId = intval(Cookie::get('__typecho_unapproved_comment', 0)); $select = $this->select()->where('cid = ?', $this->parameter->parentId) ->where( 'status = ? OR (coid = ? AND status <> ?)', 'approved', $unapprovedCommentId, 'approved' ); if ($this->options->commentsShowCommentOnly) { $select->where('table.comments.type = ?', 'comment'); } $select->order('table.comments.coid', 'ASC'); $this->db->fetchAll($select, [$this, 'push']); /** 需要输出的评论列表 */ $outputComments = []; /** 如果开启评论回复 */ if ($this->options->commentsThreaded) { foreach ($this->stack as $coid => &$comment) { /** 取出父节点 */ $parent = $comment['parent']; /** 如果存在父节点 */ if (0 != $parent && isset($this->stack[$parent])) { /** 如果当前节点深度大于最大深度, 则将其挂接在父节点上 */ if ($comment['levels'] >= $this->options->commentsMaxNestingLevels) { $comment['levels'] = $this->stack[$parent]['levels']; $parent = $this->stack[$parent]['parent']; // 上上层节点 $comment['parent'] = $parent; } /** 计算子节点顺序 */ $comment['order'] = isset($this->threadedComments[$parent]) ? count($this->threadedComments[$parent]) + 1 : 1; /** 如果是子节点 */ $this->threadedComments[$parent][$coid] = $comment; } else { $outputComments[$coid] = $comment; } } $this->stack = $outputComments; } /** 评论排序 */ if ('DESC' == $this->options->commentsOrder) { $this->stack = array_reverse($this->stack, true); $this->threadedComments = array_map('array_reverse', $this->threadedComments); } /** 评论总数 */ $this->total = count($this->stack); /** 对评论进行分页 */ if ($this->options->commentsPageBreak) { if ('last' == $this->options->commentsPageDisplay && !$this->parameter->commentPage) { $this->currentPage = ceil($this->total / $this->options->commentsPageSize); } else { $this->currentPage = $this->parameter->commentPage ? $this->parameter->commentPage : 1; } /** 截取评论 */ $this->stack = array_slice( $this->stack, ($this->currentPage - 1) * $this->options->commentsPageSize, $this->options->commentsPageSize ); } /** 评论置位 */ $this->length = count($this->stack); $this->row = $this->length > 0 ? current($this->stack) : []; reset($this->stack); } /** * 将每行的值压入堆栈 * * @param array $value 每行的值 * @return array */ public function push(array $value): array { $value = $this->filter($value); /** 计算深度 */ if (0 != $value['parent'] && isset($this->stack[$value['parent']]['levels'])) { $value['levels'] = $this->stack[$value['parent']]['levels'] + 1; } else { $value['levels'] = 0; } /** 重载push函数,使用coid作为数组键值,便于索引 */ $this->stack[$value['coid']] = $value; $this->length ++; return $value; } /** * 输出分页 * * @access public * @param string $prev 上一页文字 * @param string $next 下一页文字 * @param int $splitPage 分割范围 * @param string $splitWord 分割字符 * @param string|array $template 展现配置信息 * @return void * @throws Exception */ public function pageNav( string $prev = '«', string $next = '»', int $splitPage = 3, string $splitWord = '...', $template = '' ) { if ($this->options->commentsPageBreak) { $default = [ 'wrapTag' => 'ol', 'wrapClass' => 'page-navigator' ]; if (is_string($template)) { parse_str($template, $config); } else { $config = $template ?: []; } $template = array_merge($default, $config); $query = Router::url('comment_page', [ 'permalink' => $this->parameter->parentContent->path, 'commentPage' => '{commentPage}' ], $this->options->index); self::pluginHandle()->trigger($hasNav)->call( 'pageNav', $this->currentPage, $this->total, $this->options->commentsPageSize, $prev, $next, $splitPage, $splitWord, $template, $query ); if (!$hasNav && $this->total > $this->options->commentsPageSize) { /** 使用盒状分页 */ $nav = new Box($this->total, $this->currentPage, $this->options->commentsPageSize, $query); $nav->setPageHolder('commentPage'); $nav->setAnchor('comments'); echo '<' . $template['wrapTag'] . (empty($template['wrapClass']) ? '' : ' class="' . $template['wrapClass'] . '"') . '>'; $nav->render($prev, $next, $splitPage, $splitWord, $template); echo '' . $template['wrapTag'] . '>'; } } } /** * 列出评论 * * @param mixed $singleCommentOptions 单个评论自定义选项 */ public function listComments($singleCommentOptions = null) { //初始化一些变量 $this->singleCommentOptions = Config::factory($singleCommentOptions); $this->singleCommentOptions->setDefault([ 'before' => '