Index: privatemsg.module
===================================================================
RCS file: /cvs/drupal/contributions/modules/privatemsg/privatemsg.module,v
retrieving revision 1.70.2.30.2.91.2.4
diff -w -u -p -r1.70.2.30.2.91.2.4 privatemsg.module
--- privatemsg.module	20 Dec 2008 19:48:47 -0000	1.70.2.30.2.91.2.4
+++ privatemsg.module	5 Jan 2009 01:58:11 -0000
@@ -550,11 +550,6 @@ function pm_send_validate($form, &$form_
     $message['thread_id'] = $form_state['values']['thread_id'];
   }
 
-  // Some editors add tags to the body which will fool the formapi into thinking there is content.
-  if (trim(strip_tags($form_state['values']['body'])) == '' && $form['privatemsg']['body']['#required'] == TRUE) {
-    form_set_error('body', t('Blank messages are not allowed.'));
-  }
-
   // Verify that recipient's name syntax is correct.
   $fragments = explode(',', $form_state['values']['recipient']);
   $invalid = array();
@@ -575,18 +570,8 @@ function pm_send_validate($form, &$form_
   // Verify users exist and load their accounts.
   foreach ($valid as $index => $name) {
     if ($recipient = user_load(array('name' => $name))) {
-      // Check for blocked users. Modules blocking the message will return a message if they block, or nothing if they don't.
-      $results = module_invoke_all('privatemsg_block_message', $message['author'], $recipient);
-      if (count($results)) {
-        $invalid[$name] = $name;
-        foreach ($results as $result) {
-          drupal_set_message($result);
-        }
-      }
-      else {
         $message['recipients'][$recipient->uid] = $recipient;
       }
-    }
     else {
       // Here we add more invalid names due to the fact that they don't exist.
       $invalid[$name] = $name;
@@ -606,47 +591,25 @@ function pm_send_validate($form, &$form_
    * 2) Names that remain will be put into a recipients array.
    */
 
+  $errors = _privatemsg_validate_message($message, $message['author'], TRUE);
+  if (!empty($errors)) {
+      foreach ($errors as $error) {
+        form_set_error('body', $error);
+      }
+  }
+
   $form_state['validate_built_message'] = $message;
   if (!empty($invalid)) {
     drupal_set_message(t('The following users will not receive this private message: @invalid', array('@invalid' => implode(", ", $invalid))), 'error');
   }
-  if (empty($message['recipients'])) {
-    form_set_error('error', t('There are no valid recipients.'));
-  }
   $form_state['values']['recipient'] = implode(', ', array_diff($valid, $invalid));
 }
 
 function pm_send($form, &$form_state) {
-  $message = $form_state['validate_built_message'];
-
-  // 1) Save the message body first.
-  $args = array();
-  $args[] = $message['subject'];
-  $args[] = $message['author']->uid;
-  $args[] = $message['body'];
-  $args[] = $message['timestamp'];
-  $query = "INSERT INTO {pm_message} (subject, author, body, timestamp) VALUES ('%s', %d, '%s', %d)";
-  $resuld = db_query($query, $args);
-  $mid = db_last_insert_id('pm_message', 'mid');
-  $message['mid'] = $mid;
-
-  // Thread ID is the same as the mid if it's the first message in the thread.
-  if (!isset($message['thread_id'])) {
-    $message['thread_id'] = $mid;
-  }
-  // 2) Save message to recipients.
-  // Each recipient gets a record in the pm_index table.
-  $query = "INSERT INTO {pm_index} (mid, thread_id, uid, is_new, deleted) VALUES (%d, %d, %d, %d, 0)";
-  foreach ($message['recipients'] as $recipient) {
-    $mid = $message['mid'];
-    $thread_id  = $message['thread_id'];
-    db_query($query, $mid, $thread_id, $recipient->uid, 1);
-  }
-  // Also add a record for tha author to the pm_index table - set  column "new" to 0.
-  db_query($query, $mid, $thread_id, $message['author']->uid, 0);
-
+  if (_privatemsg_send($form_state['validate_built_message'])) {
   drupal_set_message(t('A message has been sent to @recipients.', array('@recipients' => $form_state['values']['recipient'])));
 }
+}
 
 function pm_preview($form, &$form_state) {
 
@@ -822,10 +785,10 @@ function privatemsg_user($op, &$edit, &$
 
   switch ($op) {
     case 'view':
-      if (user_access('write privatemsg') && $user->uid <> $account->uid) {
+      if ($url = privatemsg_get_link($account)) {
         $account->content['privatemsg_send_new_message'] = array(
           '#type'   => 'markup',
-          '#value'  => l(t('Send this user a message'), 'messages/new/'. $account->uid, array('query' => drupal_get_destination())),
+          '#value'  => l(t('Send this user a message'), $url, array('query' => drupal_get_destination())),
           '#weight' => 10,
         );
       }
@@ -1001,3 +964,159 @@ function privatemsg_privatemsg_pm_contro
   return l(t('Delete message'), 'messages/delete/'. $pmid);
 }
 
+
+function privatemsg_new_thread($subject, $body, $recipients, $author = NULL) {
+  if ($author == NULL) {
+    global $user;
+    $author = drupal_clone($user);
+  }
+
+  $message = array();
+  $message['subject'] = $subject;
+  $message['author'] = $author;
+  $message['body'] = $body;
+  $message['timestamp'] = time();
+  $message['recipients'] = $recipients;
+
+  $errors = _privatemsg_validate_message($message, $author);
+  if (!empty($errors)) {
+    return $errors;
+  }
+  else {
+    return _privatemsg_send($message);
+  }
+}
+
+function privatemsg_answer($thread_id, $body, $author = NULL) {
+  if ($author == NULL) {
+    global $user;
+    $author = drupal_clone($user);
+  }
+
+  $message = array();
+  $message['author'] = $author;
+  $message['body'] = $body;
+  $message['timestamp'] = time();
+  $message['thread_id'] = $thread_id;
+
+  // We don't know the subject and the recipients, so we need to load them..
+  // thread_id == mid on the first message of the thread
+  $first_message = _privatemsg_load($thread_id, $author->uid);
+  if (!$first_message) {
+    return array(t('Thread %thread_id not found, unable to answer', array('%thread_id' => $thread_id)));
+  }
+
+
+  $query = _privatemsg_assemble_query('privatemsg_participants', $thread_id);
+  $participants = db_query($query['query']);
+  while ($result = db_fetch_object($participants)) {
+    $recipient = user_load($result->uid);
+      $message['recipients'][$recipient->uid] = $recipient;
+  }
+
+  $message['subject'] = $first_message['subject'];
+
+  $errors = _privatemsg_validate_message($message, $author);
+  if (!empty($errors)) {
+    return $errors;
+  }
+  else {
+    return _privatemsg_send($message);
+  }
+}
+
+function _privatemsg_validate_message($message, $author, $show_warnings = FALSE) {
+
+  $errors = array();
+  if (!user_access('write privatemsg', $author)) {
+    // no need to do further checks in this case...
+    return array(t('User @user is not allowed to write messages', array('@user' => $author->name)));
+  }
+
+  if (empty($message['subject'])) {
+    $errors[] = t('Disallowed to send a message without subject');
+  }
+
+  $trimmed = trim(strip_tags($message['body']));
+  if (empty($trimmed)) {
+    $errors[] = t('Blank messages are not allowed');
+  }
+
+  if (!is_array($message['recipients']) || empty($message['recipients'])) {
+    $errors[] = t('Disallowed to send a message without atleast one recipient');
+  }
+
+  if (is_array($message['recipients'])) {
+    foreach ($message['recipients'] as $uid => $recipient) {
+      $block_results = module_invoke_all('privatemsg_block_message', $author, $recipient);
+      if (count($block_results) > 0) {
+        unset($message['recipients'][$uid]);
+        if ($show_warnings) {
+          foreach ($block_results as $block_result) {
+            drupal_set_message($block_result);
+          }
+        }
+      }
+    }
+  }
+
+  // Check again, give another error message if all recipients are blocked
+  if (empty($message['recipients'])) {
+    $errors[] = t('Disallowed to send message because all recipients are blocked');
+  }
+
+  return $errors += module_invoke_all('privatemsg_message_validate', $message);
+}
+
+function _privatemsg_send($message) {
+
+  drupal_alter('privatemsg_message_presave', $message);
+
+  // 1) Save the message body first.
+  $args = array();
+  $args[] = $message['subject'];
+  $args[] = $message['author']->uid;
+  $args[] = $message['body'];
+  $args[] = $message['timestamp'];
+  $query = "INSERT INTO {pm_message} (subject, author, body, timestamp) VALUES ('%s', %d, '%s', %d)";
+  $resuld = db_query($query, $args);
+  $mid = db_last_insert_id('pm_message', 'mid');
+  $message['mid'] = $mid;
+
+  // Thread ID is the same as the mid if it's the first message in the thread.
+  if (!isset($message['thread_id'])) {
+    $message['thread_id'] = $mid;
+  }
+
+  // 2) Save message to recipients.
+  // Each recipient gets a record in the pm_index table.
+
+  $query = "INSERT INTO {pm_index} (mid, thread_id, uid, is_new, deleted) VALUES (%d, %d, %d, %d, 0)";
+  foreach ($message['recipients'] as $recipient) {
+    $mid = $message['mid'];
+    db_query($query, $mid, $message['thread_id'], $recipient->uid, 1);
+  }
+  // Also add a record for tha author to the pm_index table - set  column "new" to 0.
+  db_query($query, $mid, $message['thread_id'], $message['author']->uid, 0);
+
+  drupal_alter('privatemsg_message_insert', $message);
+
+  return TRUE;
+}
+
+function privatemsg_get_link($recipient, $account = NULL) {
+  if ($account == NULL) {
+    global $user;
+    $account = $user;
+  }
+  if (!user_access('write privatemsg', $account) || $recipient->uid == $account->uid) {
+    return FALSE;
+  }
+
+  if (count(module_invoke_all('privatemsg_block_message', $account, $recipient)) > 0) {
+    return FALSE;
+  }
+
+  return 'messages/new/'. $recipient->uid;
+}
+
