Index: comment.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment.module,v
retrieving revision 1.342
diff -u -F^f -r1.342 comment.module
--- comment.module	18 Mar 2005 07:07:04 -0000	1.342
+++ comment.module	20 Mar 2005 22:43:53 -0000
@@ -89,9 +89,7 @@ function comment_menu($may_cache) {
     $access = user_access('administer comments');
     $items[] = array('path' => 'admin/comment', 'title' => t('comments'),
       'callback' => 'comment_admin_overview', 'access' => $access);
-    $items[] = array('path' => 'admin/comment/edit', 'title' => t('edit comment'),
-      'callback' => 'comment_admin_edit', 'access' => $access, 'type' => MENU_CALLBACK);
-    $items[] = array('path' => 'admin/comment/delete', 'title' => t('delete comment'),
+    $items[] = array('path' => 'comment/delete', 'title' => t('delete comment'),
       'callback' => 'comment_delete', 'access' => $access, 'type' => MENU_CALLBACK);
 
     // Tabs:
@@ -339,7 +337,7 @@ function comment_access($op, $comment) {
   global $user;
 
   if ($op == 'edit') {
-    return $user->uid && $user->uid == $comment->uid && comment_num_replies($comment->cid) == 0;
+    return ($user->uid && $user->uid == $comment->uid && comment_num_replies($comment->cid) == 0) || user_access('administer comments');
   }
 }
 
@@ -354,7 +352,7 @@ function comment_edit($cid) {
   $comment = drupal_unpack($comment);
   $comment->name = $comment->uid ? $comment->registered_name : $comment->name;
   if (comment_access('edit', $comment)) {
-    print theme('page', comment_preview(object2array($comment)));
+    print theme('page', theme('comment_preview', object2array($comment)));
   }
   else {
     drupal_access_denied();
@@ -371,14 +369,19 @@ function comment_reply($nid, $pid = NULL
   // are we posting or previewing a reply?
   if ($_POST['op'] == t('Post comment')) {
     $edit = $_POST['edit'];
-    $edit = comment_validate_form($edit);
+    $edit = comment_validate($edit);
     drupal_set_title(t('Post comment'));
-    print theme('page', comment_post($edit));
-    return;
+    if (!$cid = comment_save($edit)) {
+      // comment could not be posted. show edit form with errors
+      print theme('page', comment_preview($edit));
+    }
+    else {
+      drupal_goto("node/$nid#comment-$cid");
+    }
   }
   else if ($_POST['op'] == t('Preview comment')) {
     $edit = $_POST['edit'];
-    $edit = comment_validate_form($edit);
+    $edit = comment_validate($edit);
     drupal_set_title(t('Preview comment'));
     print theme('page', comment_preview($edit));
     return;
@@ -402,26 +405,56 @@ function comment_reply($nid, $pid = NULL
 
     // should we show the reply box?
     if (node_comment_mode($nid) != 2) {
-      $output .= theme('box', t('Reply'), t("This discussion is closed: you can't post new comments."));
+      drupal_set_message(t("This discussion is closed: you can't post new comments."), 'error');
     }
     else if (user_access('post comments')) {
       $output .= theme('comment_form', array('pid' => $pid, 'nid' => $nid), t('Reply'));
     }
     else {
-      $output .= theme('box', t('Reply'), t('You are not authorized to post comments.'));
+      drupal_set_message(t('You are not authorized to post comments.'), 'error');
     }
   }
   else {
-    $output .= theme('box', t('Reply'), t('You are not authorized to view comments.'));
+    drupal_set_message(t('You are not authorized to view comments.'), 'error');
   }
 
-  drupal_set_title(t('Add new comment'));
+  drupal_set_title(t('Reply to a comment'));
   print theme('page', $output);
 }
 
-function comment_validate_form($edit) {
+function comment_validate($edit) {
   global $user;
 
+  // only admins can change these fields
+  if (!user_access('administer comments')) {
+    $edit['uid'] = $user->uid;
+    $edit['timestamp'] = time();
+    $edit['status'] = user_access('post comments without approval') ? 0 : 1;
+  }
+  else {
+    if (strtotime($edit['date']) != -1) {
+      $edit['timestamp'] = strtotime($edit['date']);
+    }
+    else {
+      form_set_error('date', t('You have to specify a valid date.'));
+    }
+
+    if ($edit['account'] && $edit['uid']) {
+      // if a registred user posted the comment, we assume you only want to transfer authorship
+      // to another registered user. Name changes are freely allowed on anon comments.
+      if ($account = user_load(array('name' => $edit['author']))) {
+        $edit['uid'] = $account->uid;
+      }
+      else {
+        form_set_error('author', t('You have to specify a valid author.'));
+      }
+    }
+    else {
+      $edit['uid'] = 0;
+      $edit['name'] = $edit['author'];
+    }
+  }
+
   // Validate the comment's subject.  If not specified, extract
   // one from the comment's body.
   $edit['subject'] = strip_tags($edit['subject']);
@@ -470,7 +503,6 @@ function comment_validate_form($edit) {
       }
     }
   }
-
   return $edit;
 }
 
@@ -478,20 +510,27 @@ function comment_preview($edit) {
   global $user;
 
   $output = '';
-
   $comment = new StdClass();
   foreach ($edit as $key => $value) {
     $comment->$key = $value;
   }
 
   // Attach the user and time information.
-  $comment->uid = $user->uid;
-  $comment->timestamp = time();
-  $comment->name = $user->name ? $user->name : $comment->name;
+  if ($edit['author']) {
+    $account = user_load(array('name' => $edit['author']));
+  }
+  elseif ($user->uid){
+    $account = $user;
+  }
+  if ($account) {
+    $comment->uid = $account->uid;
+    $comment->name = $account->name;
+  }
+  $comment->timestamp = $edit['timestamp'] ? $edit['timestamp'] : time();
 
   // Preview the comment.
-  $output .= theme('comment_view', $comment, theme('links', module_invoke_all('link', 'comment', $comment, 1)));
-  $output .= theme('comment_form', $edit, t('Reply'));
+  $output .= theme('comment_view', $comment);
+  $output .= theme('comment_form', $edit);
 
   if ($edit['pid']) {
     $comment = db_fetch_object(db_query('SELECT c.*, u.uid, u.name AS registered_name, u.picture, u.data FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = %d AND c.status = 0', $edit['pid']));
@@ -507,10 +546,19 @@ function comment_preview($edit) {
   return $output;
 }
 
-function comment_post($edit) {
+/**
+ * Accepts a submission of new or changed comment content.
+ *
+ * @param $edit
+ *   A comment array.
+ *
+ * @return
+ *   If the comment is successfully saved the comment ID is returned.  If the comment
+ *   is not saved, FALSE is returned.
+ */
+function comment_save($edit) {
   global $user;
-
-  if (user_access('post comments') && node_comment_mode($edit['nid']) == 2) {
+  if (user_access('post comments') && (user_access('administer comments') || node_comment_mode($edit['nid']) == 2)) {
     if (!form_get_errors()) {
       // Check for duplicate comments.  Note that we have to use the
       // validated/filtered data to perform such check.
@@ -520,10 +568,8 @@ function comment_post($edit) {
       }
 
       if ($edit['cid']) {
-        // Update the comment in the database.  Note that the update
-        // query will fail if the comment isn't owned by the current
-        // user.
-        db_query("UPDATE {comments} SET subject = '%s', comment = '%s', format = '%s' WHERE cid = %d AND uid = %d", $edit['subject'], $edit['comment'], $edit['format'], $edit['cid'], $user->uid);
+        // Update the comment in the database.
+        db_query("UPDATE {comments} SET status = '%s', timestamp = '%d', subject = '%s', comment = '%s', format = '%s', uid = %d WHERE cid = %d", $edit['status'], $edit['timestamp'], $edit['subject'], $edit['comment'], $edit['format'], $edit['uid'], $edit['cid']);
 
         _comment_update_node_statistics($edit['nid']);
 
@@ -535,7 +581,6 @@ function comment_post($edit) {
       }
       else {
         // Add the comment to database.
-        $status = user_access('post comments without approval') ? 0 : 1;
         $roles = variable_get('comment_roles', array());
         $score = 0;
 
@@ -617,7 +662,6 @@ function comment_post($edit) {
           }
         }
 
-
         $edit['cid'] = db_next_id('{comments}_cid');
         $edit['timestamp'] = time();
 
@@ -625,8 +669,7 @@ function comment_post($edit) {
           $edit['name'] = $user->name;
         }
 
-
-        db_query("INSERT INTO {comments} (cid, nid, pid, uid, subject, comment, format, hostname, timestamp, status, score, users, thread, name, mail, homepage) VALUES (%d, %d, %d, %d, '%s', '%s', %d, '%s', %d, %d, %d, '%s', '%s', '%s', '%s', '%s')", $edit['cid'], $edit['nid'], $edit['pid'], $edit['uid'], $edit['subject'], $edit['comment'], $edit['format'], $_SERVER['REMOTE_ADDR'], $edit['timestamp'], $status, $score, $users, $thread, $edit['name'], $edit['mail'], $edit['homepage']);
+        db_query("INSERT INTO {comments} (cid, nid, pid, uid, subject, comment, format, hostname, timestamp, status, score, users, thread, name, mail, homepage) VALUES (%d, %d, %d, %d, '%s', '%s', %d, '%s', %d, %d, %d, '%s', '%s', '%s', '%s', '%s')", $edit['cid'], $edit['nid'], $edit['pid'], $edit['uid'], $edit['subject'], $edit['comment'], $edit['format'], $_SERVER['REMOTE_ADDR'], $edit['timestamp'], $edit['status'], $score, $users, $thread, $edit['name'], $edit['mail'], $edit['homepage']);
 
         _comment_update_node_statistics($edit['nid']);
 
@@ -640,22 +683,21 @@ function comment_post($edit) {
       // Clear the cache so an anonymous user can see his comment being added.
       cache_clear_all();
 
-      // Explain the approval queue if necessary, and then
-      // redirect the user to the node he's commenting on.
-      if ($status == 1) {
+      // Explain the approval queue if necessary
+      if ($edit['status'] == 1) {
         drupal_set_message(t('Your comment has been queued for moderation by site administrators and will be published after approval.'));
-        drupal_goto('node/'. $edit['nid']);
-      }
-      else {
-        drupal_goto('node/'. $edit['nid'] .'#comment-'. $edit['cid']);
       }
+      return $edit['cid'];
     }
     else {
-      print theme('page', comment_preview($edit));
+      return FALSE;
     }
   }
   else {
-    watchdog('content', t('Comment: unauthorized comment submitted or comment submitted to a closed node %subject.', array('%subject' => '<em>'. $edit['subject'] .'</em>')), WATCHDOG_WARNING);
+    $txt = t('Comment: unauthorized comment submitted or comment submitted to a closed node %subject.', array('%subject' => '<em>'. $edit['subject'] .'</em>'));
+    watchdog('content', $txt, WATCHDOG_WARNING);
+    drupal_set_message($txt, 'error');
+    return FALSE;
   }
 }
 
@@ -671,8 +713,8 @@ function comment_links($comment, $return
 
   if (node_comment_mode($comment->nid) == 2) {
     if (user_access('administer comments') && user_access('access administration pages')) {
-      $links[] = l(t('delete'), "admin/comment/delete/$comment->cid");
-      $links[] = l(t('edit'), "admin/comment/edit/$comment->cid");
+      $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");
     }
     else if (user_access('post comments')) {
@@ -903,44 +945,6 @@ function comment_render($node, $cid = 0)
 }
 
 /**
- * Menu callback; edit a comment from the administrative interface.
- */
-function comment_admin_edit($cid) {
-  // Comment edits need to be saved.
-  if ($_POST['op'] == t('Submit')) {
-    $edit = $_POST['edit'];
-    comment_save($edit['cid'], $edit);
-    drupal_goto('admin/comment');
-  }
-
-  // If we're not saving our changes above, we're editing it.
-  $result = db_query('SELECT c.*, u.name AS registered_name, u.uid FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = %d', $cid);
-  $comment = db_fetch_object($result);
-  $comment->name = $comment->uid ? $comment->registered_name : $comment->name;
-  $comment = drupal_unpack($comment);
-
-  if ($comment) {
-    if (!$comment->uid) {
-      // If comment from non-registered user, allow admin to modify anonymous fields.
-      $form .= form_textfield(t('Name'), 'name', $comment->name ? $comment->name : variable_get('anonymous', 'Anonymous') , 20, 60);
-      $form .= form_textfield(t('E-mail'), 'mail', $comment->mail, 20, 64);
-      $form .= form_textfield(t('Homepage'), 'homepage', $comment->homepage, 20, 255);
-    }
-    else {
-      // Otherwise, just display the author's name.
-      $form .= form_item(t('Author'), format_name($comment));
-    }
-    $form .= form_textfield(t('Subject'), 'subject', $comment->subject, 70, 128);
-    $form .= form_textarea(t('Comment'), 'comment', $comment->comment, 70, 15, '');
-    $form .= filter_form('format', $comment->format);
-    $form .= form_radios(t('Status'), 'status', $comment->status, array(t('Published'), t('Not published')));
-    $form .= form_hidden('cid', $cid);
-    $form .= form_submit(t('Submit'));
-    print theme('page', form($form));
-  }
-}
-
-/**
  * Menu callback; delete a comment.
  */
 function comment_delete($cid) {
@@ -983,17 +987,6 @@ function comment_delete($cid) {
   print theme('page', $output);
 }
 
-function comment_save($id, $edit) {
-  db_query("UPDATE {comments} SET subject = '%s', comment = '%s', status = %d, format = '%s', name = '%s', mail = '%s', homepage = '%s' WHERE cid = %d", $edit['subject'], $edit['comment'], $edit['status'], $edit['format'], $edit['name'], $edit['mail'], $edit['homepage'], $id);
-  watchdog('content', t('Comment: modified %subject.', array('%subject' => '<em>'. $edit['subject'] .'</em>')));
-  drupal_set_message(t('The comment has been saved.'));
-
-  _comment_update_node_statistics($edit['nid']);
-
-  // Allow modules to respond to the updating of a comment.
-  module_invoke_all('comment', 'update', $edit);
-}
-
 /**
  * Menu callback; present an administrative comment listing.
  */
@@ -1020,8 +1013,8 @@ function comment_admin_overview($type = 
         format_name($comment),
         ($comment->status == 0 ? t('Published') : t('Not published')),
         format_date($comment->timestamp, 'small'),
-        l(t('edit'), "admin/comment/edit/$comment->cid", array(), $destination),
-        l(t('delete'), "admin/comment/delete/$comment->cid", array(), $destination)
+        l(t('edit'), "comment/edit/$comment->cid", array(), $destination),
+        l(t('delete'), "comment/delete/$comment->cid", array(), $destination)
       );
   }
 
@@ -1376,14 +1369,25 @@ function comment_already_moderated($uid,
 ** overridden by themes.
 */
 
-function theme_comment_form($edit, $title) {
+function theme_comment_form($edit, $title = NULL) {
   global $user;
 
   $form .= "<a id=\"comment-form\"></a>\n";
 
   // contact information:
   if ($user->uid) {
-    $form .= form_item(t('Your name'), format_name($user));
+    if ($edit['cid'] && user_access('administer comments')) {
+      $form .= '<div class="admin">';
+      $output = form_textfield(t('Authored by'), 'author', $edit['author'] ? $edit['author'] : $edit['name'] ? $edit['name'] : $edit['registered_name'], 20, 60, NULL, NULL, TRUE);
+      $output .= form_textfield(t('Authored on'), 'date', $edit['date'] ? $edit['date'] : format_date($edit['timestamp'], 'custom', 'Y-m-d H:i O'), 20, 25, NULL, NULL, TRUE);
+      $output .= form_radios(t('Status'), 'status', $edit['status'], array(t('Published'), t('Not published')));
+      $output .= '<div class="authored">';
+      $form .= form_group(t('Administration'), $output);
+      $form .= "</div>\n";
+    }
+    else {
+      $form .= form_item(t('Your name'), format_name($user));
+    }
   }
   else if (variable_get('comment_anonymous', 0) == 1) {
     $form .= form_textfield(t('Your name'), 'name', $edit['name'] ? $edit['name'] : variable_get('anonymous', 'Anonymous') , 20, 60);
@@ -1396,18 +1400,11 @@ function theme_comment_form($edit, $titl
     $form .= form_textfield(t('Homepage'), 'homepage', $edit['homepage'], 20, 255);
   }
 
-  // subject field:
   if (variable_get('comment_subject_field', 1)) {
     $form .= form_textfield(t('Subject'), 'subject', $edit['subject'], 50, 64);
   }
-
-  // comment field:
   $form .= form_textarea(t('Comment'), 'comment', $edit['comment'] ? $edit['comment'] : $user->signature, 70, 10, '', NULL, TRUE);
-
-  // format selector
   $form .= filter_form('format', $edit['format']);
-
-  // preview button:
   $form .= form_hidden('cid', $edit['cid']);
   $form .= form_hidden('pid', $edit['pid']);
   $form .= form_hidden('nid', $edit['nid']);
