--- comment.module	Wed Oct 20 16:14:11 2004
+++ comment.module	Thu Oct 21 20:58:13 2004
@@ -573,88 +573,7 @@ function comment_post($edit) {
         ** Here we are building the thread field.  See the comment
         ** in comment_render().
         */
-
-        if ($edit['pid'] == 0) {
-          /*
-          ** This is a comment with no parent comment (depth 0): we start
-          ** by retrieving the maximum thread level.
-          */
-
-          $max = db_result(db_query('SELECT MAX(thread) FROM {comments} WHERE nid = %d', $edit['nid']));
-
-          // Strip the "/" from the end of the thread.
-          $max = rtrim($max, '/');
-
-          /*
-          ** Next, we increase this value by one.  Note that we can't
-          ** use 1, 2, 3, ... 9, 10, 11 because we order by string and
-          ** 10 would be right after 1.  We use 1, 2, 3, ..., 9, 91,
-          ** 92, 93, ... instead.  Ugly but fast.
-          */
-
-          $decimals = (string)substr($max, 0, strlen($max) - 1);
-          $units = substr($max, -1, 1);
-          if ($units) {
-            $units++;
-          }
-          else {
-            $units = 1;
-          }
-
-          if ($units == 10) {
-            $units = '90';
-          }
-
-          // Finally, build the thread field for this new comment.
-          $thread = "$decimals$units/";
-        }
-        else {
-          /*
-          ** This is comment with a parent comment: we increase
-          ** the part of the thread value at the proper depth.
-          */
-
-          // Get the parent comment:
-          $parent = db_fetch_object(db_query('SELECT * FROM {comments} WHERE cid = %d', $edit['pid']));
-
-          // Strip the "/" from the end of the parent thread.
-          $parent->thread = (string)rtrim((string)$parent->thread, '/');
-
-          // Get the max value in _this_ thread.
-          $max = db_result(db_query("SELECT MAX(thread) FROM {comments} WHERE thread LIKE '%s.%%' AND nid = %d", $parent->thread, $edit['nid']));
-
-          if ($max == '') {
-            // First child of this parent.
-            $thread = "$parent->thread.1/";
-          }
-          else {
-            // Strip the "/" at the end of the thread.
-            $max = rtrim($max, '/');
-
-            // We need to get the value at the correct depth.
-            $parts = explode('.', $max);
-            $parent_depth = count(explode('.', $parent->thread));
-            $last = $parts[$parent_depth];
-
-            /*
-            ** Next, we increase this value by one.  Note that we can't
-            ** use 1, 2, 3, ... 9, 10, 11 because we order by string and
-            ** 10 would be right after 1.  We use 1, 2, 3, ..., 9, 91,
-            ** 92, 93, ... instead.  Ugly but fast.
-            */
-
-            $decimals = (string)substr($last, 0, strlen($last) - 1);
-            $units = substr($last, -1, 1);
-            $units++;
-            if ($units == 10) {
-              $units = '90';
-            }
-
-            // Finally, build the thread field for this new comment.
-            $thread = "$parent->thread.". $decimals.$units .'/';
-          }
-        }
-
+        $thread = comment_thread($edit['nid'], $edit['pid']);
 
         $edit["cid"] = db_next_id("{comments}_cid");
         $edit['timestamp'] = time();
@@ -697,6 +616,96 @@ function comment_post($edit) {
   }
 }
 
+function comment_thread($nid, $pid) {
+  if ($pid == 0) {
+    /*
+    ** This is a comment with no parent comment (depth 0): we start
+    ** by retrieving the maximum thread level.
+    */
+
+    $max = db_result(db_query('SELECT MAX(thread) FROM {comments} WHERE nid = %d', $nid));
+
+    // Strip the "/" from the end of the thread.
+    $max = rtrim($max, '/');
+    if (($dot = strpos($max, '.')) !== FALSE) {
+      $max = substr($max, 0, $dot);
+    }
+
+    /*
+    ** Next, we increase this value by one.  Note that we can't
+    ** use 1, 2, 3, ... 9, 10, 11 because we order by string and
+    ** 10 would be right after 1.  We use 1, 2, 3, ..., 9, 91,
+    ** 92, 93, ... instead.  Ugly but fast.
+    */
+
+    $decimals = (string)substr($max, 0, strlen($max) - 1);
+    $units = substr($max, -1, 1);
+    if ($units) {
+      $units++;
+    }
+    else {
+      $units = 1;
+    }
+
+    if ($units == 10) {
+      $units = '90';
+    }
+
+    // Finally, build the thread field for this new comment.
+    $thread = "$decimals$units/";
+  }
+  else {
+    /*
+    ** This is comment with a parent comment: we increase
+    ** the part of the thread value at the proper depth.
+    */
+
+    // Get the parent comment:
+    $parent = db_fetch_object(db_query('SELECT * FROM {comments} WHERE cid = %d', $pid));
+
+    // Strip the "/" from the end of the parent thread.
+    $parent->thread = (string)rtrim((string)$parent->thread, '/');
+
+    // Get the max value in _this_ thread.
+    $max = db_result(db_query("SELECT MAX(thread) FROM {comments} WHERE thread LIKE '%s.%%' AND nid = %d", $parent->thread, $nid));
+
+    if ($max == '') {
+      // First child of this parent.
+      $thread = "$parent->thread.1/";
+    }
+    else {
+      // Strip the "/" at the end of the thread.
+      $max = rtrim($max, '/');
+      // We need to get the value at the correct depth.
+      $parts = explode('.', $max);
+      $parent_depth = count(explode('.', $parent->thread));
+      $last = $parts[$parent_depth];
+      // We need to get the value at the correct depth.
+      $parts = explode('.', $max);
+      $parent_depth = count(explode('.', $parent->thread));
+      $last = $parts[$parent_depth];
+
+      /*
+      ** Next, we increase this value by one.  Note that we can't
+      ** use 1, 2, 3, ... 9, 10, 11 because we order by string and
+      ** 10 would be right after 1.  We use 1, 2, 3, ..., 9, 91,
+      ** 92, 93, ... instead.  Ugly but fast.
+      */
+
+      $decimals = (string)substr($last, 0, strlen($last) - 1);
+      $units = substr($last, -1, 1);
+      $units++;
+      if ($units == 10) {
+        $units = '90';
+      }
+
+      // Finally, build the thread field for this new comment.
+      $thread = "$parent->thread.". $decimals.$units .'/';
+    }
+  }
+  return $thread;
+}
+
 function comment_links($comment, $return = 1) {
   global $user;
 
@@ -992,7 +1001,7 @@ function comment_delete($cid) {
 
   // We'll only delete if the user has confirmed the
   // deletion using the form in our else clause below.
-  if ($comment->cid && $_POST['op'] == t('Delete')) {
+  if ($comment->cid && $_POST['op'] == t('Delete Thread')) {
     drupal_set_message(t('The comment and all its replies have been deleted.'));
 
     // Delete comment and its replies.
@@ -1005,13 +1014,32 @@ function comment_delete($cid) {
     cache_clear_all();
 
   }
+  else if ($comment->cid && $_POST['op'] == t('Delete Comment')) {
+    drupal_set_message(t('The comment has been deleted.'));
+
+    // Delete comment and its replies.
+    _comment_delete_single($comment);
+
+    _comment_update_node_statistics($comment->nid);
+
+    // Clear the cache so an anonymous user
+    // can see his comment being added.
+    cache_clear_all();
+
+  }
 
   // Print a confirmation.
   else if ($comment->cid) {
-    drupal_set_message(t('Do you want to delete this comment and all its replies?'));
+    $children = db_result(db_query('SELECT COUNT(cid) FROM {comments} WHERE pid = %d', $comment->cid));
+    drupal_set_message($children ?
+      t('Do you want to delete this comment, and optionally all its replies?'):
+      t('Do you want to delete this comment?'));
     $comment->comment = check_output($comment->comment, $comment->format);
     $output  = theme('comment', $comment);
-    $output .= form_submit(t('Delete'));
+    $output .= form_submit(t('Delete Comment'));
+    if ($children) {
+      $output .= form_submit(t('Delete Thread'));
+    }
   }
   else {
     drupal_set_message(t('The comment no longer exists.'));
@@ -1639,6 +1667,42 @@ function theme_comment_post_forbidden() 
     else {
       return t('<a href="%login">login</a> to post comments', array('%login' => url('user/login')));
     }
+  }
+}
+
+function _comment_delete_single($comment) {
+  $cid = $comment->cid;
+  $pid = $comment->pid;
+  // Delete the comment:
+  db_query('DELETE FROM {comments} WHERE cid = %d', $comment->cid);
+  watchdog('special', t('Comment: deleted %subject.', array('%subject' => "<em>$comment->subject</em>")));
+
+  module_invoke_all('comment', 'delete', $comment);
+
+  // Rethread this comment's descendents
+  $result = db_query('SELECT cid, nid, thread FROM {comments} WHERE pid = %d ORDER BY timestamp', $cid);
+  while ($child = db_fetch_object($result)) {
+    $oldthread = $child->thread;
+    $newthread = comment_thread($child->nid, $pid);
+    db_query("UPDATE {comments} SET thread = '%s', pid = %d WHERE cid = %d", $newthread, $pid, $child->cid);
+    _comment_rethread($child->cid, strlen($oldthread)-1, rtrim($newthread,'/'));
+  }
+}
+
+/**
+ * revise the thread field of descendents of a deleted comment
+ *
+ * @param $cid comment whose descendents are rethreaded
+ * @param $oldlength length of the former thread prefix
+ * @param $newprefix revised thread prefix
+ */
+function _comment_rethread($cid, $oldlength, $newprefix) {
+  $result = db_query('SELECT cid, thread FROM {comments} WHERE pid = %d', $cid);
+  while ($child = db_fetch_object($result)) {
+    $suffix = substr($child->thread, $oldlength);
+    $thread = $newprefix . $suffix;
+    db_query("UPDATE {comments} SET thread = '%s' WHERE cid = %d", $thread, $child->cid);
+    _comment_rethread($child->cid, $oldlength, $newprefix);
   }
 }
 
