parameter->setDefault('parentId=0&commentPage=0&commentsNum=0&allowComment=1'); } /** * 评论回调函数 * * @access private * @return void */ private function threadedCommentsCallback() { $singleCommentOptions = $this->_singleCommentOptions; if (function_exists('threadedComments')) { return threadedComments($this, $singleCommentOptions); } $commentClass = ''; if ($this->authorId) { if ($this->authorId == $this->ownerId) { $commentClass .= ' comment-by-author'; } else { $commentClass .= ' comment-by-user'; } } ?>
  • gravatar($singleCommentOptions->avatarSize, $singleCommentOptions->defaultAvatar); ?> beforeAuthor(); $this->author(); $singleCommentOptions->afterAuthor(); ?>
    status) { ?> commentStatus(); ?>
    content(); ?>
    reply($singleCommentOptions->replyWord); ?>
    children) { ?>
    threadedComments(); ?>
  • options->commentsPageBreak) { $pageRow = array('permalink' => $this->parentContent['pathinfo'], 'commentPage' => $this->_currentPage); return Typecho_Router::url('comment_page', $pageRow, $this->options->index) . '#' . $this->theId; } return $this->parentContent['permalink'] . '#' . $this->theId; } /** * 子评论 * * @access protected * @return array */ protected function ___children() { return $this->options->commentsThreaded && !$this->isTopLevel && isset($this->_threadedComments[$this->coid]) ? $this->_threadedComments[$this->coid] : array(); } /** * 是否到达顶层 * * @access protected * @return boolean */ protected function ___isTopLevel() { return $this->levels > $this->options->commentsMaxNestingLevels - 2; } /** * 重载内容获取 * * @access protected * @return void */ protected function ___parentContent() { return $this->parameter->parentContent; } /** * 输出文章评论数 * * @access public * @param string $string 评论数格式化数据 * @return void */ public function num() { $args = func_get_args(); if (!$args) { $args[] = '%d'; } $num = intval($this->_total); echo sprintf(isset($args[$num]) ? $args[$num] : array_pop($args), $num); } /** * 执行函数 * * @access public * @return void */ public function execute() { if (!$this->parameter->parentId) { return; } $commentsAuthor = Typecho_Cookie::get('__typecho_remember_author'); $commentsMail = Typecho_Cookie::get('__typecho_remember_mail'); $select = $this->select()->where('table.comments.cid = ?', $this->parameter->parentId) ->where('table.comments.status = ? OR (table.comments.author = ? AND table.comments.mail = ? AND table.comments.status = ?)', 'approved', $commentsAuthor, $commentsMail, 'waiting'); $threadedSelect = NULL; if ($this->options->commentsShowCommentOnly) { $select->where('table.comments.type = ?', 'comment'); } $select->order('table.comments.coid', 'ASC'); $this->db->fetchAll($select, array($this, 'push')); /** 需要输出的评论列表 */ $outputComments = array(); /** 如果开启评论回复 */ 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->row = current($this->stack); $this->length = count($this->stack); } reset($this->stack); } /** * 将每行的值压入堆栈 * * @access public * @param array $value 每行的值 * @return array */ public function push(array $value) { $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 $template 展现配置信息 * @return void */ public function pageNav($prev = '«', $next = '»', $splitPage = 3, $splitWord = '...', $template = '') { if ($this->options->commentsPageBreak && $this->_total > $this->options->commentsPageSize) { $default = array( 'wrapTag' => 'ol', 'wrapClass' => 'page-navigator' ); if (is_string($template)) { parse_str($template, $config); } else { $config = $template; } $template = array_merge($default, $config); $pageRow = $this->parameter->parentContent; $pageRow['permalink'] = $pageRow['pathinfo']; $query = Typecho_Router::url('comment_page', $pageRow, $this->options->index); /** 使用盒状分页 */ $nav = new Typecho_Widget_Helper_PageNavigator_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 ''; } } /** * 递归输出评论 * * @access protected * @return void */ public function threadedComments() { $children = $this->children; if ($children) { //缓存变量便于还原 $tmp = $this->row; $this->sequence ++; //在子评论之前输出 echo $this->_singleCommentOptions->before; foreach ($children as $child) { $this->row = $child; $this->threadedCommentsCallback(); $this->row = $tmp; } //在子评论之后输出 echo $this->_singleCommentOptions->after; $this->sequence --; } } /** * 列出评论 * * @access private * @param mixed $singleCommentOptions 单个评论自定义选项 * @return void */ public function listComments($singleCommentOptions = NULL) { //初始化一些变量 $this->_singleCommentOptions = Typecho_Config::factory($singleCommentOptions); $this->_singleCommentOptions->setDefault(array( 'before' => '
      ', 'after' => '
    ', 'beforeAuthor' => '', 'afterAuthor' => '', 'beforeDate' => '', 'afterDate' => '', 'dateFormat' => $this->options->commentDateFormat, 'replyWord' => _t('回复'), 'commentStatus' => _t('您的评论正等待审核!'), 'avatarSize' => 32, 'defaultAvatar' => NULL )); $this->pluginHandle()->trigger($plugged)->listComments($this->_singleCommentOptions, $this); if (!$plugged) { if ($this->have()) { echo $this->_singleCommentOptions->before; while ($this->next()) { $this->threadedCommentsCallback(); } echo $this->_singleCommentOptions->after; } } } /** * 重载alt函数,以适应多级评论 * * @access public * @return void */ public function alt() { $args = func_get_args(); $num = func_num_args(); $sequence = $this->levels <= 0 ? $this->sequence : $this->order; $split = $sequence % $num; echo $args[(0 == $split ? $num : $split) -1]; } /** * 根据深度余数输出 * * @access public * @param string $param 需要输出的值 * @return void */ public function levelsAlt() { $args = func_get_args(); $num = func_num_args(); $split = $this->levels % $num; echo $args[(0 == $split ? $num : $split) -1]; } /** * 评论回复链接 * * @access public * @param string $word 回复链接文字 * @return void */ public function reply($word = '') { if ($this->options->commentsThreaded && !$this->isTopLevel && $this->parameter->allowComment) { $word = empty($word) ? _t('回复') : $word; $this->pluginHandle()->trigger($plugged)->reply($word, $this); if (!$plugged) { echo '' . $word . ''; } } } /** * 取消评论回复链接 * * @access public * @param string $word 取消回复链接文字 * @return void */ public function cancelReply($word = '') { if ($this->options->commentsThreaded) { $word = empty($word) ? _t('取消回复') : $word; $this->pluginHandle()->trigger($plugged)->cancelReply($word, $this); if (!$plugged) { $replyId = $this->request->filter('int')->replyTo; echo ''; } } } }