Index: privatemsg.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/privatemsg/privatemsg.module,v
retrieving revision 1.70.2.30.2.91.2.44
diff -u -r1.70.2.30.2.91.2.44 privatemsg.module
--- privatemsg.module	26 Apr 2009 22:16:08 -0000	1.70.2.30.2.91.2.44
+++ privatemsg.module	23 May 2009 02:06:53 -0000
@@ -179,6 +179,15 @@
     'access arguments' => array('read privatemsg'),
     'type'             => MENU_CALLBACK,
   );
+  $items['user/%/messages'] = array(
+    'title' => 'Messages',
+    'page callback'    => 'drupal_get_form',
+    'page arguments'   => array('privatemsg_list', 'list', 1),
+    'access callback'  => 'privatemsg_user_tab_access',
+    'access arguments' => array(1),
+    'type' => MENU_LOCAL_TASK,
+  );
+
   return $items;
 }
 
@@ -209,6 +218,31 @@
   return TRUE;
 }
 
+/**
+ * Function to check if a user can access the messages tab on a user page.
+ *
+ * @param $uid
+ *   the user's id for whom the permission is being checked.
+ */
+function privatemsg_user_tab_access($uid) {
+  global $user;
+  $account = $user;
+  
+  // Disallow anonymous access, regardless of permissions.
+  if (!$account->uid) {
+    return FALSE;
+  }
+  // If a user is viewing own account, allow access.
+  if ($account->uid == $uid && privatemsg_user_access('read privatemsg', $account)) {
+    return TRUE;
+  }
+  // If a user has permission to view other user's messages, then allow access.
+  if (privatemsg_user_access('read all private messages', $account)) {
+    return TRUE;
+  }
+  return FALSE;
+}
+
 
 /**
  * Check access to the view messages page.
@@ -256,11 +290,23 @@
       global $user;
       $account = drupal_clone($user);
     }
+    // Load the list of participants.
+    $query = _privatemsg_assemble_query('participants', $thread_id);
+    $participants = db_query($query['query']);
+    while ($result = db_fetch_array($participants)) {
+      $thread['participants'][$result['uid']] = user_load($result['uid']);
+    }
+    $read_all = FALSE;
+    if (!array_key_exists($account->uid, $thread['participants']) && privatemsg_user_access('read all private messages', $account)) {
+      // User has permission to read all messages AND is not a participant of the current thread.
+      $read_all = TRUE;
+    }
+
     // load messages returned by the messages query with _privatemsg_load().
-    $query = _privatemsg_assemble_query('messages', array($thread_id), $account);
+    $query = _privatemsg_assemble_query('messages', array($thread_id), $account, FALSE, $read_all);
     $conversation = db_query($query['query']);
     while ($result = db_fetch_array($conversation)) {
-      if ($message = _privatemsg_load($result['mid'], $account)) {
+      if ($message = _privatemsg_load($result['mid'])) {
         $thread['messages'][$result['mid']] = $message;
       }
     }
@@ -274,12 +320,6 @@
     $message = current($thread['messages']);
     $thread['subject'] = $message['subject'];
 
-    // Load the list of participants.
-    $query = _privatemsg_assemble_query('participants', $thread_id);
-    $participants = db_query($query['query']);
-    while ($result = db_fetch_array($participants)) {
-      $thread['participants'][$result['uid']] = user_load($result['uid']);
-    }
     return $thread;
   }
   return FALSE;
@@ -793,11 +833,15 @@
  */
 
 /**
- * Query function for load.
+ * Query definition to load a message.
+ *
+ * @param $fragments
+ *   Query fragments array.
+ * @param $pmid
+ *   the id of the message.
  */
-function privatemsg_sql_load(&$fragments, $pmid, $account) {
-//  drupal_set_message('<pre>'. print_r(func_get_args(), 1) . '</pre>');
-  $fragments['primary_table'] = '{pm_message} pm'; // Our primary table
+function privatemsg_sql_load(&$fragments, $pmid) {
+  $fragments['primary_table'] = '{pm_message} pm';
 
   $fragments['select'][]      = "pm.mid";
   $fragments['select'][]      = "pm.author";
@@ -809,29 +853,34 @@
   $fragments['inner_join'][]  = 'INNER JOIN {pm_index} pmi ON pm.mid = pmi.mid';
   $fragments['where'][]       = 'pmi.mid = %d';
   $fragments['query_args']['where'][]  = $pmid;
-  $fragments['where'][]       = 'pmi.uid = %d';
-  $fragments['query_args']['where'][]  = $account->uid;
 }
+
 /**
  * Query definition to load messages of one or multiple threads.
  *
  * @param $fragments
- *  Query fragments array.
+ *   Query fragments array.
  * @param $threads
- *  Array with one or multiple thread id's.
+ *   Array with one or multiple thread id's.
  * @param $account
- *  User object for which the messages are being loaded.
+ *   User object for which the messages are being loaded.
  * @param $load_all
- *  Deleted messages are only loaded if this is set to TRUE.
+ *   Deleted messages are only loaded if this is set to TRUE.
+ * @param $read_all
+ *   Messages are not filtered to the user if this is set to TRUE.
  */
-function privatemsg_sql_messages(&$fragments, $threads, $account, $load_all = FALSE) {
+function privatemsg_sql_messages(&$fragments, $threads, $account, $load_all = FALSE, $read_all = FALSE) {
   $fragments['primary_table'] = '{pm_index} pmi';
 
   $fragments['select'][]      = 'DISTINCT(pmi.mid) as mid';
   $fragments['where'][]       = 'pmi.thread_id IN ('. db_placeholders($threads) .')';
   $fragments['query_args']['where']   += $threads;
-  $fragments['where'][]       = 'pmi.uid = %d';
-  $fragments['query_args']['where'][]  = $account->uid;
+
+  if (!$read_all) {
+    // Only load the user's messages.
+    $fragments['where'][]     = 'pmi.uid = %d';
+    $fragments['query_args']['where'][]  = $account->uid;
+  }
   if (!$load_all) {
     $fragments['where'][]       = 'pmi.deleted = 0';
   }
@@ -1080,6 +1129,17 @@
   );
 }
 
+function privatemsg_delete_submit($form, &$form_state) {
+  global $user;
+  $account = drupal_clone($user);
+  
+  if ($form_state['values']['confirm']) {
+    privatemsg_message_change_delete($form_state['values']['pmid'], 1, $account);
+    drupal_set_message(t('Message has been deleted'));
+  }
+  $form_state['redirect'] = 'messages';
+}
+
 /**
  * Delete or restore a message.
  *
@@ -1088,18 +1148,20 @@
  * @param $delete
  *   Either deletes or restores the thread (1 => delete, 0 => restore)
  * @param $account
- *   User acccount for which the message should be deleted.
+ *   User acccount for which the delete action should e carried out - Set to NULL to delete for all users.
  *
  * @ingroup api
  */
 function privatemsg_message_change_delete($pmid, $delete, $account = NULL) {
-  if (is_null($account)) {
-    global $user;
-    $account = drupal_clone($user);
-  }
-  $message = _privatemsg_load($pmid, $account);
+  $message = _privatemsg_load($pmid);
 
-  db_query('UPDATE {pm_index} SET deleted = %d WHERE mid = %d AND uid = %d', $delete, $pmid, $account->uid);
+  if ($account){
+    db_query('UPDATE {pm_index} SET deleted = %d WHERE mid = %d AND uid = %d', $delete, $pmid, $account->uid);
+  }
+  else {
+    // Mark deleted for all users.
+    db_query('UPDATE {pm_index} SET deleted = %d WHERE mid = %d', $delete, $pmid);
+  }
 
   $result = db_query("SELECT MIN(deleted) AS deleted_by_all FROM {pm_index} WHERE mid = %d", $pmid);
   $deleted = db_fetch_array($result);
@@ -1112,13 +1174,6 @@
   module_invoke_all('privatemsg_message_delete', $message, $deleted_by_all);
 }
 
-function privatemsg_delete_submit($form, &$form_state) {
-  if ($form_state['values']['confirm']) {
-    privatemsg_message_change_delete($form_state['values']['pmid'], 1);
-    drupal_set_message(t('Message has been deleted'));
-  }
-  $form_state['redirect'] = 'messages';
-}
 /**
  * Send a new message.
  *
@@ -1208,7 +1263,7 @@
 
   // 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, $message['author']);
+  $first_message = _privatemsg_load($thread_id);
   if (!$first_message) {
     return array(t('Thread %thread_id not found, unable to answer', array('%thread_id' => $thread_id)));
   }
@@ -1374,23 +1429,14 @@
  *
  * @param $pmid
  *   Message id, pm.mid field
- * @param $account
- *   For which account the message should be loaded.
- *   Defaults to the current user.
  *
  * @ingroup api
  */
-function _privatemsg_load($pmid, $account = NULL) {
-  if (empty($account)) {
-    global $user;
-    $account = drupal_clone($user);
-  }
-
-  $query = _privatemsg_assemble_query('load', $pmid, $account);
+function _privatemsg_load($pmid) {
+  $query = _privatemsg_assemble_query('load', $pmid);
 
   $result = db_query($query['query']);
   $message = db_fetch_array($result);
-  $message['user'] = $account;
   // Load author of message.
   $message['author'] = user_load($message['author']);
   $returned = module_invoke_all('privatemsg_message_load', $message);

