Index: privatemsg.api.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/privatemsg/Attic/privatemsg.api.php,v
retrieving revision 1.1.2.5
diff -u -r1.1.2.5 privatemsg.api.php
--- privatemsg.api.php	8 Jun 2009 13:38:41 -0000	1.1.2.5
+++ privatemsg.api.php	17 Jul 2009 19:53:38 -0000
@@ -150,43 +150,36 @@
 function hook_privatemsg_sql_list_alter(&$fragment, $account) {
 
 }
-/**
- * Display a list of sent messages.
- *
- * @param $fragments
- *   Query fragments
- * @param $account
- *   User object
- */
-function hook_privatemsg_sql_list_sent_alter(&$fragment, $account) {
-
-}
 
 /**
- * Load a single message.
+ * Query definition to load a message.
  *
  * @param $fragments
- *   Query fragments
+ *   Query fragments array.
  * @param $pmid
- *   message id, pm.mid
- * @param $account
- *   User object
+ *   the id of the message.
+  * @param $account
+ *   User object of account for which to load the message.
  */
-function hook_privatemsg_sql_load_alter(&$fragment, $pmid, $account) {
+function privatemsg_sql_load(&$fragments, $pmid, $account) {
 
 }
+
 /**
- * Load all message id's of a thread.
+ * Query definition to load messages of one or multiple threads.
  *
  * @param $fragments
- *   Query fragments
- * @param $thread_id
- *   Thread id, pmi.thread_id is the same as the mid of the first
- *   message of that thread
+ *   Query fragments array.
+ * @param $threads
+ *   Array with one or multiple thread id's.
  * @param $account
- *   User object
+ *   User object for which the messages are being loaded.
+ * @param $load_all
+ *   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 hook_privatemsg_sql_messages_alter(&$fragment, $thread_id, $account) {
+function privatemsg_sql_messages(&$fragments, $threads, $account, $load_all = FALSE, $read_all = FALSE) {
 
 }
 
@@ -294,10 +287,12 @@
  * user.
  * @todo There is no "undelete" hook
  *
- * @param $message
- *   Message array
+ * @param $pmid
+ *   ID of the message that has been deleted
+  * @param $deleted_by_all
+ *   Boolean to show whether the message has been deleted by all users or not
  */
-function hook_privatemsg_message_delete($message) {
+function hook_privatemsg_message_delete($pmid, $deleted_by_all) {
 
 }
 
Index: privatemsg.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/privatemsg/privatemsg.module,v
retrieving revision 1.70.2.30.2.91.2.60
diff -u -r1.70.2.30.2.91.2.60 privatemsg.module
--- privatemsg.module	17 Jul 2009 00:32:05 -0000	1.70.2.30.2.91.2.60
+++ privatemsg.module	17 Jul 2009 19:58:09 -0000
@@ -184,6 +184,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;
 }
 
@@ -214,6 +223,30 @@
   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.
@@ -261,8 +294,22 @@
       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.
+      drupal_set_message(t('This conversation is being viewed with escalated priviledges and may not be the same as shown to normal users.'));
+      $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)) {
@@ -279,12 +326,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;
@@ -902,10 +943,16 @@
  */
 
 /**
- * Query function for load.
+ * Query definition to load a message.
+ *
+ * @param $fragments
+ *   Query fragments array.
+ * @param $pmid
+ *   the id of the message.
+  * @param $account
+ *   User object of account for which to load 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
 
   $fragments['select'][]      = "pm.mid";
@@ -921,19 +968,22 @@
   $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';
@@ -941,6 +991,11 @@
   $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';
   }
@@ -1120,14 +1175,21 @@
 }
 
 function privatemsg_delete($form_state, $pmid) {
-  global $user;
 
   $form['pmid'] = array(
     '#type' => 'value',
     '#value' => $pmid,
   );
+  if (privatemsg_user_access('read all private messages')) {
+    $form['delete_options'] = array(
+      '#type' => 'checkbox',
+      '#title' => 'Delete this message for all users?',
+      '#description' => 'Tick the box to delete the message for all users.',
+      '#default_value' => FALSE,
+    );
+  }
   return confirm_form($form,
-    t('Are you sure you want to delete'),
+    t('Are you sure you want to delete this message?'),
     isset($_GET['destination']) ? $_GET['destination'] : 'messages/view/'. $pmid,
     t('This action cannot be undone.'),
     t('Delete'),
@@ -1135,6 +1197,23 @@
   );
 }
 
+function privatemsg_delete_submit($form, &$form_state) {
+  global $user;
+  $account = drupal_clone($user);
+  
+  if ($form_state['values']['confirm']) {
+    if ($form_state['values']['delete_options']) {
+      privatemsg_message_change_delete($form_state['values']['pmid'], 1);
+      drupal_set_message(t('Message has been deleted for all users'));
+    }
+    else {
+      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.
  *
@@ -1143,36 +1222,28 @@
  * @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 be 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);
+  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);
   }
-  $message = _privatemsg_load($pmid, $account);
-
-  db_query('UPDATE {pm_index} SET deleted = %d WHERE mid = %d AND uid = %d', $delete, $pmid, $account->uid);
 
   $result = db_query("SELECT MIN(deleted) AS deleted_by_all FROM {pm_index} WHERE mid = %d", $pmid);
   $deleted = db_fetch_array($result);
 
   $deleted_by_all = FALSE;
-  if ($deleted['deleted_by_all'] == 0) {
+  if ($deleted['deleted_by_all'] > 0) {
     $deleted_by_all = TRUE;
   }
 
-  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';
+  module_invoke_all('privatemsg_message_delete', $pmid, $deleted_by_all);
 }
 
 /**

