Revision: 1444
Author: magike.net
Date: Wed Jun  9 22:08:08 2010
Log: 更新算法,修正评论分页以及父子关系的bug
后台回复评论自动增...@标记
http://code.google.com/p/typecho/source/detail?r=1444

Modified:
  /trunk/admin/css/typecho.source.css
  /trunk/admin/manage-comments.php
  /trunk/var/Widget/Abstract/Comments.php
  /trunk/var/Widget/Archive.php
  /trunk/var/Widget/Comments/Archive.php

=======================================
--- /trunk/admin/css/typecho.source.css Mon May 24 23:51:56 2010
+++ /trunk/admin/css/typecho.source.css Wed Jun  9 22:08:08 2010
@@ -1502,8 +1502,17 @@

  ul.typecho-list-notable li .reply-message {
        margin: 10px;
-       border-left: 5px solid #D3DBB3;
+       background: #FBFDF2;
        padding: 0 10px;
+
+       border: 1px solid #DEE4C5;
+
+    -moz-border-radius: 4px;
+    -webkit-border-radius: 4px;
+    -khtml-border-radius: 4px;
+
+    /* hope IE support border radius, God save me! */
+    border-radius: 4px;
  }

  ul.typecho-list-notable li .loading {
=======================================
--- /trunk/admin/manage-comments.php    Mon May 24 23:51:56 2010
+++ /trunk/admin/manage-comments.php    Wed Jun  9 22:08:08 2010
@@ -88,7 +88,7 @@

                                  <div class="comment-meta">
                                      <span class="<?php  
$comments->type(); ?>"></span>
-                                    <?php $comments->author(true); ?>
+                                    <span class="comment-author"><?php  
$comments->author(true); ?></span>
                                      <?php if($comments->mail): ?>
                                       |
                                      <a href="mailto:<?php  
$comments->mail(); ?>"><?php $comments->mail(); ?></a>
@@ -125,8 +125,10 @@
                                      <?php endif; ?>
                                       |
                                      <a href="#<?php  
$comments->theId(); ?>" rel="<?php  
$options->index('/action/comments-edit?do=get&coid=' .  
$comments->coid); ?>" class="ajax operate-edit"><?php _e('编辑'); ?></a>
+                                    <?php if('approved' ==  
$comments->status && 'comment' == $comments->type): ?>
                                       |
                                      <a href="#<?php  
$comments->theId(); ?>" rel="<?php  
$options->index('/action/comments-edit?do=reply&coid=' .  
$comments->coid); ?>" class="ajax operate-reply"><?php _e('回复'); ?></a>
+                                    <?php endif; ?>
                                       |
                                      <a lang="<?php _e('你确认要删除%s的评论 
吗?', htmlspecialchars($comments->author)); ?>" href="<?php  
$options->index('/action/comments-edit?do=delete&coid=' .  
$comments->coid); ?>" class="ajax operate-delete"><?php _e('删除'); ?></a>
                                  </div>
@@ -325,6 +327,12 @@
                          });

                           
form.inject(this.getParent('li').getElement('.line'), 'after');
+
+                        var ta = form.getElement('textarea');
+                        ta.set('value', '<a href="#' +  
this.getParent('li').get('id') + '">@'
+                            +  
this.getParent('li').getElement('.comment-author a').get('html')  
+ "</a>\n");
+                        ta.focus();
+
                          form.getElement('#reply-' +  
coid).addEvent('click', (function () {
                              if ('' ==  
this.getParent('li').getElement('.reply-form  
textarea[name=text]').get('value')) {
                                  alert('<?php _e('必须填写内容'); ?>');
=======================================
--- /trunk/var/Widget/Abstract/Comments.php     Sun May  9 20:54:55 2010
+++ /trunk/var/Widget/Abstract/Comments.php     Wed Jun  9 22:08:08 2010
@@ -50,28 +50,45 @@
      protected function ___permalink()
      {

-        if ($this->options->commentsPageBreak) {
+        if ($this->options->commentsPageBreak && 'approved' ==  
$this->status) {

              $coid = $this->coid;
              $parent = $this->parent;

              while ($parent > 0 && $this->options->commentsThreaded) {
                  $coid = $parent;
-                $parent =  
$this->db->fetchObject($this->db->select('parent')->from('table.comments')
-                ->where('coid = ? AND status = ?',  
$parent, 'approved'))->parent;
-            }
-
-
-            $select  = $this->db->select(array('COUNT(coid)' => 'num'))
-            ->from('table.comments')->where('cid = ? AND parent = ? AND  
status = ?',
-                $this->parentContent['cid'], 0, 'approved')
+                $parentRows =  
$this->db->fetchRow($this->db->select('parent')->from('table.comments')
+                ->where('coid = ? AND status = ?', $parent, 'approved'));
+
+                if (!empty($parentRows)) {
+                    $parent = $parentRows['parent'];
+                } else {
+                    break;
+                }
+            }
+
+            $select  = $this->db->select('coid', 'parent')
+            ->from('table.comments')->where('cid = ? AND status = ?',  
$this->parentContent['cid'], 'approved')
              ->where('coid ' . ('DESC' ==  
$this->options->commentsOrder ? '>=' : '<=') . ' ?', $coid);

              if ($this->options->commentsShowCommentOnly) {
                  $select->where('type = ?', 'comment');
              }
-
-            $currentPage = ceil($this->db->fetchObject($select)->num /  
$this->options->commentsPageSize);
+
+            $comments = $this->db->fetchAll($select);
+
+            $commentsMap = array();
+            $total = 0;
+
+            foreach ($comments as $comment) {
+                $commentsMap[$comment['coid']] = $comment['parent'];
+
+                if (0 == $comment['parent'] | 
| !isset($commentsMap[$comment['parent']])) {
+                    $total ++;
+                }
+            }
+
+            $currentPage = ceil($total / $this->options->commentsPageSize);

              $pageRow = array('permalink' =>  
$this->parentContent['pathinfo'], 'commentPage' => $currentPage);
              return Typecho_Router::url('comment_page',
=======================================
--- /trunk/var/Widget/Archive.php       Mon Mar 15 22:51:24 2010
+++ /trunk/var/Widget/Archive.php       Wed Jun  9 22:08:08 2010
@@ -1274,8 +1274,8 @@
       */
      public function comments()
      {
-        $parameter = array('parentId' => $this->hidden ? 0 :  
$this->cid, 'parentContent' => $this->row, 'respondId' => $this->respondId,
-        'commentPage' =>  
$this->request->filter('int')->commentPage, 'commentsNum' =>  
$this->commentsNum);
+        $parameter = array('parentId' => $this->hidden ? 0 :  
$this->cid, 'parentContent' => $this->row,
+        'respondId' => $this->respondId, 'commentPage' => max(1,  
$this->request->filter('int')->commentPage));

          return $this->widget('Widget_Comments_Archive', $parameter);
      }
=======================================
--- /trunk/var/Widget/Comments/Archive.php      Tue Jun  8 23:40:36 2010
+++ /trunk/var/Widget/Comments/Archive.php      Wed Jun  9 22:08:08 2010
@@ -19,14 +19,6 @@
   */
  class Widget_Comments_Archive extends Widget_Abstract_Comments
  {
-    /**
-     * 分页计算对象
-     *
-     * @access private
-     * @var Typecho_Db_Query
-     */
-    private $_countSql;
-
      /**
       * 当前页
       *
@@ -49,15 +41,7 @@
       * @access private
       * @var array
       */
-    private $_threadedComments;
-
-    /**
-     * 递归深度
-     *
-     * @access private
-     * @var integer
-     */
-    private $_levels = 0;
+    private $_threadedComments = array();

      /**
       * 多级评论回调函数
@@ -66,14 +50,6 @@
       * @var mixed
       */
      private $_customThreadedCommentsCallback = false;
-
-    /**
-     * 用于分割的评论id
-     *
-     * @access private
-     * @var integer
-     */
-    private $_splitCommentId = 0;

      /**
       * 构造函数,初始化组件
@@ -117,10 +93,10 @@
              }
          }

-        $commentLevelClass = $this->_levels > 0 ? ' comment-child' : '  
comment-parent';
+        $commentLevelClass = $this->levels > 0 ? ' comment-child' : '  
comment-parent';
  ?>
  <li id="<?php $this->theId(); ?>" class="comment-body<?php
-    if ($this->_levels > 0) {
+    if ($this->levels > 0) {
          echo ' comment-child';
          $this->levelsAlt(' comment-level-odd', ' comment-level-even');
      } else {
@@ -182,17 +158,6 @@
          return $this->options->commentsThreaded && !$this->isTopLevel &&  
isset($this->_threadedComments[$this->coid])
              ? $this->_threadedComments[$this->coid] : array();
      }
-
-    /**
-     * 楼层数
-     *
-     * @access protected
-     * @return integer
-     */
-    protected function ___levels()
-    {
-        return $this->_levels + 1;
-    }

      /**
       * 是否到达顶层
@@ -202,7 +167,7 @@
       */
      protected function ___isTopLevel()
      {
-        return $this->_levels > $this->options->commentsMaxNestingLevels -  
2;
+        return $this->levels > $this->options->commentsMaxNestingLevels -  
2;
      }

      /**
@@ -225,11 +190,6 @@
       */
      public function num()
      {
-        if (false === $this->_total) {
-            $this->_total = !$this->options->commentsThreaded  
&& !$this->options->commentsShowCommentOnly
-            ? $this->parameter->commentsNum :  
$this->size($this->_countSql);
-        }
-
          $args = func_get_args();
          if (!$args) {
              $args[] = '%d';
@@ -260,65 +220,69 @@
              $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) {
-            $threadedSelect = clone $select;
-            $select->where('table.comments.parent = ?', 0);
-        }
-
-        $this->_countSql = clone $select;
-
+
+            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) {
-            $this->_total = !$this->options->commentsThreaded  
&& !$this->options->commentsShowCommentOnly
-            ? $this->parameter->commentsNum :  
$this->size($this->_countSql);
-
              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;
              }
-
-            $select->page($this->_currentPage,  
$this->options->commentsPageSize);
-        }
-
-        $select->order('table.comments.coid',  
$this->options->commentsOrder);
-        $this->db->fetchAll($select, array($this, 'push'));
-
-        $commentsLevel = array();
-        $commentFilpMap = array();  // 反向查询表
-
-        if ($threadedSelect) {
-            $threadedSelect->where('table.comments.parent <> ? AND  
table.comments.coid > ?', 0, $this->_splitCommentId)
-            ->order('table.comments.coid', $this->options->commentsOrder);
-            $threadedComments = $this->db->fetchAll($threadedSelect,  
array($this, 'filter'));
-
-            foreach ($threadedComments as $comment) {
-                /** fix issue 459 */
-                $commentFilpMap[$comment['coid']] = $comment['parent'];
-
-                $commentsLevel[$comment['coid']] =  
isset($commentsLevel[$comment['parent']]) ?  
$commentsLevel[$comment['parent']] + 1 : 1;
-                if ($commentsLevel[$comment['coid']] <  
$this->options->commentsMaxNestingLevels) {
-                    /** 计算顺序 */
-                    $comment['order'] =  
isset($this->_threadedComments[$comment['parent']])
-                        ?  
count($this->_threadedComments[$comment['parent']]) + 1 : 1;
-
-                     
$this->_threadedComments[$comment['parent']][$comment['coid']] = $comment;
-                } else {
-                    $grandParent =  
isset($commentFilpMap[$comment['parent']]) ?  
$commentFilpMap[$comment['parent']] : 0;     // 上上层节点
-
-                    /** 更新父节点 */
-                    $comment['parent'] = $grandParent;
-
-                    /** 计算顺序 */
-                    $comment['order'] =  
isset($this->_threadedComments[$grandParent])
-                        ? count($this->_threadedComments[$grandParent]) +  
1 : 1;
-
-                    /** 直接挂接到上一层节点 */
-                     
$this->_threadedComments[$grandParent][$comment['coid']] = $comment;
-
-                    /** 更新反向查询表 */
-                    $commentFilpMap[$comment['coid']] = $grandParent;
-                }
-            }
+
+            /** 截取评论 */
+            $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);
          }
      }

@@ -332,18 +296,17 @@
      public function push(array $value)
      {
          $value = $this->filter($value);
-
-        // 取出本页最小值
-        if ('DESC' == $this->options->commentsOrder || 0 ==  
$this->_splitCommentId) {
-            $this->_splitCommentId = $value['coid'];
+
+        /** 计算深度 */
+        if (0 != $value['parent'] &&  
isset($this->stack[$value['parent']]['levels'])) {
+            $value['levels'] = $this->stack[$value['parent']]['levels'] +  
1;
+        } else {
+            $value['levels'] = 0;
          }

-        //将行数据按顺序置位
-        $this->row = $value;
-        $this->length ++;
-
-        //重载push函数,使用coid作为数组键值,便于索引
+        /** 重载push函数,使用coid作为数组键值,便于索引 */
          $this->stack[$value['coid']] = $value;
+
          return $value;
      }

@@ -388,7 +351,6 @@
          if ($children) {
              //缓存变量便于还原
              $tmp = $this->row;
-            $this->_levels ++;
              $this->sequence ++;

              //在子评论之前输出
@@ -404,7 +366,6 @@
              $singleCommentOptions->after;

              $this->sequence --;
-            $this->_levels --;
          }
      }

@@ -454,7 +415,7 @@
          $args = func_get_args();
          $num = func_num_args();

-        $sequence = $this->_levels <= 0 ? $this->sequence : $this->order;
+        $sequence = $this->levels <= 0 ? $this->sequence : $this->order;

          $split = $sequence % $num;
          echo $args[(0 == $split ? $num : $split) -1];
@@ -471,7 +432,7 @@
      {
          $args = func_get_args();
          $num = func_num_args();
-        $split = $this->_levels % $num;
+        $split = $this->levels % $num;
          echo $args[(0 == $split ? $num : $split) -1];
      }

_______________________________________________
announce mailing list
[email protected]
http://lists.typecho.org/mailman/listinfo/announce

回复