Index: modules/comment.module
===================================================================
--- modules/comment.module	(revision 5662)
+++ modules/comment.module	(working copy)
@@ -100,10 +100,11 @@
   $items = array();
 
   if ($may_cache) {
-    $access = user_access('administer comments');
+    $access = user_access('edit or delete comments') || user_access('administer comments');
     $items[] = array('path' => 'admin/comment', 'title' => t('comments'),
       'callback' => 'comment_admin_overview', 'access' => $access);
 
+    $access = user_access('administer comments');
     // Tabs:
     $items[] = array('path' => 'admin/comment/list', 'title' => t('list'),
       'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
@@ -149,7 +150,7 @@
  * Implementation of hook_perm().
  */
 function comment_perm() {
-  return array('access comments', 'post comments', 'administer comments', 'post comments without approval');
+  return array('access comments', 'post comments', 'administer comments', 'edit or delete comments', 'post comments without approval');
 }
 
 /**
@@ -157,16 +158,36 @@
  *
  * Generates a block with the most recent comments.
  */
-function comment_block($op = 'list', $delta = 0) {
+function comment_block($op = 'list', $delta = 0, $edit = array()) {
   if ($op == 'list') {
     $blocks[0]['info'] = t('Recent comments');
     return $blocks;
   }
+  else if ($op == 'configure') {
+    $form['showtimes'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Show times next to comment titles'),
+      '#default_value' => variable_get('comment_block_showtimes', TRUE),
+    );
+    $form['count'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Number of comments to display'),
+      '#default_value' => variable_get('comment_block_count', 10),
+    ); 
+    return $form;
+  }
+  else if ($op == 'save') {
+    variable_set('comment_block_showtimes', $edit['showtimes']);
+    $text_value = $edit['count'];
+    settype($edit['count'], 'integer');
+    if ($edit['count'] > 0 && $edit['count'] == $text_value)
+      variable_set('comment_block_count', $edit['count']);
+  }
   else if ($op == 'view' && user_access('access comments')) {
-    $result = db_query_range(db_rewrite_sql('SELECT c.nid, c.* FROM {comments} c INNER JOIN {node} n ON n.nid = c.nid WHERE n.status = 1 AND c.status = %d ORDER BY c.timestamp DESC', 'c'), COMMENT_PUBLISHED, 0, 10);
+    $result = db_query_range(db_rewrite_sql('SELECT c.nid, c.* FROM {comments} c INNER JOIN {node} n ON n.nid = c.nid WHERE n.status = 1 AND c.status = %d ORDER BY c.timestamp DESC', 'c'), COMMENT_PUBLISHED, 0, variable_get('comment_block_count', 10));
     $items = array();
     while ($comment = db_fetch_object($result)) {
-      $items[] = l($comment->subject, 'node/'. $comment->nid, NULL, NULL, 'comment-'. $comment->cid) .'<br />'. t('%time ago', array('%time' => format_interval(time() - $comment->timestamp)));
+      $items[] = l($comment->subject, 'node/'. $comment->nid, NULL, NULL, 'comment-'. $comment->cid) . (variable_get('comment_block_showtimes', TRUE) ? '<br />'. t('%time ago', array('%time' => format_interval(time() - $comment->timestamp))) : '');
     }
 
     $block['subject'] = t('Recent comments');
@@ -244,7 +265,7 @@
       return array('comment');
 
     case 'form':
-      if (user_access('administer comments')) {
+      if (user_access('edit or delete comments') || user_access('administer comments')) {
         $selected = isset($node->comment) ? $node->comment : variable_get("comment_$node->type", COMMENT_NODE_READ_WRITE);
         $form['user_comments'] = array('#type' => 'fieldset', '#title' => t('User Comments'), '#collapsible' => TRUE, '#collapsed' => TRUE);
         $form['user_comments']['comment'] = array('#type' => 'radios', '#parents' => array('comment'), '#default_value' => $selected, '#options' => array(t('Disabled'), t('Read only'), t('Read/Write')));
@@ -255,7 +276,7 @@
     case 'load':
       return db_fetch_array(db_query("SELECT last_comment_timestamp, last_comment_name, comment_count FROM {node_comment_statistics} WHERE nid = %d", $node->nid));
     case 'validate':
-      if (!user_access('administer comments')) {
+      if (!user_access('edit or delete comments') || !user_access('administer comments')) {
         // Force default for normal users:
         $node->comment = variable_get("comment_$node->type", COMMENT_NODE_READ_WRITE);
       }
@@ -300,6 +321,10 @@
 
     return $form;
   }
+  else if ($type == 'insert') {
+    $user->sort = variable_get('comment_default_order', COMMENT_ORDER_NEWEST_FIRST);
+    $user->mode = variable_get('comment_default_mode', COMMENT_MODE_THREADED_EXPANDED);
+  }
 }
 
 /**
@@ -350,6 +375,13 @@
     '#description' => t('Position of the comment controls box.  The comment controls let the user change the default display mode and display order of comments.'),
   );
 
+  $form['viewing_options']['comment_replylink'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Show reply link on comments'),
+    '#default_value' => variable_get('comment_replylink', TRUE),
+    '#description' => t('Whether or not to show the reply link on comments (which allows users to create threads)'),
+  );
+
   $form['posting_settings'] = array(
     '#type' => 'fieldset',
     '#title' => t('Comment posting settings'),
@@ -408,7 +440,7 @@
   global $user;
 
   if ($op == 'edit') {
-    return ($user->uid && $user->uid == $comment->uid && comment_num_replies($comment->cid) == 0) || user_access('administer comments');
+    return ($user->uid && $user->uid == $comment->uid && comment_num_replies($comment->cid) == 0) || user_access('edit or delete comments') || user_access('administer comments');
   }
 }
 
@@ -490,7 +522,7 @@
   comment_invoke_comment($edit, 'validate');
 
   // only admins can change these fields
-  if (!user_access('administer comments')) {
+  if (!user_access('edit or delete comments') || !user_access('administer comments')) {
     $edit['uid'] = $user->uid;
     $edit['timestamp'] = time();
     $edit['status'] = user_access('post comments without approval') ? 0 : 1;
@@ -520,17 +552,6 @@
     }
   }
 
-  // Validate the comment's subject.  If not specified, extract
-  // one from the comment's body.
-  if (trim($edit['subject']) == '') {
-    // The body may be in any format, so we:
-    // 1) Filter it into HTML
-    // 2) Strip out all HTML tags
-    // 3) Convert entities back to plain-text.
-  // Note: format is checked by check_markup().
-    $edit['subject'] = truncate_utf8(decode_entities(strip_tags(check_markup($edit['comment'], $edit['format']))), 29, TRUE);
-  }
-
   // Validate the comment's body.
   if ($edit['comment'] == '') {
     form_set_error('comment', t('The body of your comment is empty.'));
@@ -598,8 +619,18 @@
       }
 
       if ($edit['cid']) {
+        $sqlparts = array('status = \'%s\'' => 'status', 'timestamp = %d' => 'timestamp', 'subject = \'%s\'' => 'subject', 'comment = \'%s\'' => 'comment', 'format = \'%s\'' => 'format', 'uid = %d' => 'uid', 'name = \'%s\'' => 'name');
+        $sqlfields = array();
+        $sqlvalues = array();
+        foreach ($sqlparts as $sql => $arrayindex) {
+          if (isset($edit[$arrayindex])) {
+            $sqlfields[] = $sql;
+            $sqlvalues[] = $edit[$arrayindex];
+          }
+        }
         // Update the comment in the database.
-        db_query("UPDATE {comments} SET status = '%s', timestamp = %d, subject = '%s', comment = '%s', format = '%s', uid = %d, name = '%s' WHERE cid = %d", $edit['status'], $edit['timestamp'], $edit['subject'], $edit['comment'], $edit['format'], $edit['uid'], $edit['name'], $edit['cid']);
+        $sqlvalues[] = $edit['cid'];
+        db_query("UPDATE {comments} SET " . implode (', ', $sqlfields) . " WHERE cid = %d", $sqlvalues);
 
         _comment_update_node_statistics($edit['nid']);
 
@@ -745,16 +776,21 @@
   }
 
   if (node_comment_mode($comment->nid) == COMMENT_NODE_READ_WRITE) {
-    if (user_access('administer comments') && user_access('access administration pages')) {
+    if (user_access('edit or delete comments') || (user_access('administer comments') && user_access('access administration pages'))) {
       $links[] = l(t('delete'), "comment/delete/$comment->cid");
       $links[] = l(t('edit'), "comment/edit/$comment->cid");
-      $links[] = l(t('reply'), "comment/reply/$comment->nid/$comment->cid");
+
+      if (variable_get('comment_replylink', TRUE)) {
+        $links[] = l(t('reply'), "comment/reply/$comment->nid/$comment->cid");
+      }
     }
     else if (user_access('post comments')) {
       if (comment_access('edit', $comment)) {
         $links[] = l(t('edit'), "comment/edit/$comment->cid");
       }
-      $links[] = l(t('reply'), "comment/reply/$comment->nid/$comment->cid");
+      if (variable_get('comment_replylink', TRUE)) {
+        $links[] = l(t('reply'), "comment/reply/$comment->nid/$comment->cid");
+      }
     }
     else {
       $links[] = theme('comment_post_forbidden');
@@ -1231,6 +1267,17 @@
 
 function comment_form_execute($form_id, $form_values) {
 
+  // Validate the comment's subject.  If not specified, extract
+  // one from the comment's body.
+  if (trim($form_values['subject']) == '') {
+    // The body may be in any format, so we:
+    // 1) Filter it into HTML
+    // 2) Strip out all HTML tags
+    // 3) Convert entities back to plain-text.
+  // Note: format is checked by check_markup().
+    $form_values['subject'] = truncate_utf8(decode_entities(strip_tags(check_markup($form_values['comment'], $form_values['format']))), 29, TRUE);
+  }
+
   $op = isset($_POST['op']) ? $_POST['op'] : '';
   $nid = $form_values['nid'];
 
@@ -1252,7 +1299,9 @@
 */
 
 function theme_comment_form($form) {
-  return form_render($form);
+  $output = "<a id=\"comment-form\"></a>\n";
+  $output .= form_render($form);
+  return $output;
 }
 
 function theme_comment_preview($comment, $links = array(), $visible = 1) {
@@ -1397,10 +1446,10 @@
   }
   else {
     if (variable_get('user_register', 1)) {
-      return t('<a href="%login">login</a> or <a href="%register">register</a> to post comments', array('%login' => url('user/login'), '%register' => url('user/register')));
+      return t('<a href="%login">login</a> or <a href="%register">register</a> to post comments', array('%login' => url('user/login?destination='.$_GET['q']), '%register' => url('user/register?destination='.$_GET['q'])));
     }
     else {
-      return t('<a href="%login">login</a> to post comments', array('%login' => url('user/login')));
+      return t('<a href="%login">login</a> to post comments', array('%login' => url('user/login?destination='.$_GET['q'])));
     }
   }
 }
