Index: modules/comment/comment.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v
retrieving revision 1.616
diff -u -r1.616 comment.module
--- modules/comment/comment.module	10 Jan 2008 15:03:53 -0000	1.616
+++ modules/comment/comment.module	14 Jan 2008 11:03:23 -0000
@@ -607,8 +607,7 @@
       break;
 
     case 'delete':
-      db_query('DELETE FROM {comments} WHERE nid = %d', $node->nid);
-      db_query('DELETE FROM {node_comment_statistics} WHERE nid = %d', $node->nid);
+      comment_delete_node_comments($node); 
       break;
 
     case 'update index':
@@ -634,6 +633,99 @@
 }
 
 /**
+ * Delete the comments of the given node.
+ *
+ * NOTE: use batch processing to prevent timeout when deleting 
+ * a large number of comments.
+ *
+ * @param $node
+ *   The node to delete comments from.
+ */
+function comment_delete_node_comments($node) {
+  // We use batch processing to prevent timeout when deleting a large number of comments.
+  $total = comment_num_all($node->nid);
+  if ($total > 10) {
+    $batch = array(
+      'operations' => array(
+        // In this first batch operation the comments are proccesed and the hook_comment is invoked.
+        array('_comment_delete_node_comments_batch_process', array($node)),
+        // In this other operation the records are removed from the database.
+        array('_comment_remove_comments', array($node))
+      ),
+      'finished' => '_comment_delete_node_comments_batch_finished',
+      'title' => t('Deleting node comments'),
+      // We use a single multi-pass operation, so the default
+      // 'Remaining x of y operations' message will be confusing here.
+      'progress_message' => '',
+      'error_message' => t('Errors deleting comments belonging to this post.'),
+    );
+    batch_set($batch);
+  }
+  else {
+    $comments = db_query('SELECT c.*, u.name AS registered_name, u.uid FROM {comments} c INNER JOIN {users} u ON u.uid = c.uid WHERE c.nid = %d ORDER BY c.cid DESC', $node->nid);
+    while ($comment = db_fetch_object($comments)) {
+      $comment->name = $comment->uid ? $comment->registered_name : $comment->name;
+      comment_invoke_comment($comment, 'delete');
+    }
+    _comment_remove_comments($node);
+    drupal_set_message(t('Comments belonging to this post have been deleted.'));
+  }
+}
+
+/**
+ * Helper function to remove the comments from the database
+ *
+ * @param $node
+ *   The node to delete comments from.
+ */
+function _comment_remove_comments($node) {
+  db_query('DELETE FROM {comments} WHERE nid = %d', $node->nid);
+  db_query('DELETE FROM {node_comment_statistics} WHERE nid = %d', $node->nid);
+}
+
+/**
+ * Comment deletion batch operation.
+ */
+function _comment_delete_node_comments_batch_process($node, &$context) {
+  if (!isset($context['sandbox']['progress'])) {
+    $context['sandbox']['progress'] = 0;
+    $context['sandbox']['max'] = comment_num_all($node->nid);
+    $context['sandbox']['node'] = $node;
+  }
+  $node = $context['sandbox']['node'];
+
+  // Process comments by groups of 10.
+  $limit = 10;
+  $comments = db_query_range('SELECT c.*, u.name AS registered_name, u.uid FROM {comments} c INNER JOIN {users} u ON u.uid = c.uid WHERE c.nid = %d ORDER BY c.cid DESC', $node->nid, $context['sandbox']['progress'], $limit);
+  while ($comment = db_fetch_object($comments)) {
+    $comment->name = $comment->uid ? $comment->registered_name : $comment->name;
+    comment_invoke_comment($comment, 'delete');
+    $context['sandbox']['progress']++;
+  }
+
+  // Inform the batch engine that we are not finished,
+  // and provide a completion estimate.
+  if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
+    $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
+  }
+}
+
+/**
+ * Node comments deletion Batch 'finished' callback.
+ */
+function _comment_delete_node_comments_batch_finished($success, $results, $operations) {
+  if ($success) {
+    drupal_set_message(t('The comments belonging to this post have been deleted.'));
+  }
+  else {
+    drupal_set_message(t('An error occurred and processing did not complete.'), 'error');
+    $message = format_plural(count($results), '1 item successfully processed:', '@count items successfully processed:');
+    $message .= theme('item_list', $results);
+    drupal_set_message($message);
+  }
+}
+
+/**
  * Implementation of hook_user().
  */
 function comment_user($type, $edit, &$user, $category = NULL) {
