From 8ab5a1a303ecf2e1d68a89dc187206b3b30beefe Mon Sep 17 00:00:00 2001
From: Sascha Grossenbacher <saschagros+test@gmail.com>
Date: Sat, 5 Mar 2011 11:57:25 +0100
Subject: [PATCH] #967164 by te-brian, Berdir: Added initial patch and cleaned up code and UI.

---
 pm_email_notify/pm_email_notify.admin.inc |   46 ++++--
 pm_email_notify/pm_email_notify.install   |   60 +++++++-
 pm_email_notify/pm_email_notify.module    |  257 +++++++++++++++++++++++++----
 privatemsg.api.php                        |    6 +-
 privatemsg.module                         |   60 +++++--
 5 files changed, 364 insertions(+), 65 deletions(-)

diff --git a/pm_email_notify/pm_email_notify.admin.inc b/pm_email_notify/pm_email_notify.admin.inc
index f5de49b..1617098 100644
--- a/pm_email_notify/pm_email_notify.admin.inc
+++ b/pm_email_notify/pm_email_notify.admin.inc
@@ -16,39 +16,53 @@ function pm_email_notify_admin_settings_form() {
     '#collapsible' => FALSE,
     '#collapsed' => FALSE,
   );
-  $form['pm_email']['pm_email_notify_default'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Notify users of new private messages by default'),
-    '#default_value' => variable_get('pm_email_notify_default', TRUE),
+  $form['pm_email']['pm_email_notify_default_level'] = array(
+    '#type' => 'radios',
+    '#title' => t('Default e-mail notification level'),
+    '#options' => array(
+      PM_EMAIL_NOTIFY_LEVEL_DISABLED => t('Never send a notification'),
+      PM_EMAIL_NOTIFY_LEVEL_THREAD => t('Only send a notification when a new discussion thread is created'),
+      PM_EMAIL_NOTIFY_LEVEL_UNREAD_ONCE => t("Only send a notification when the user has not already received a notification since he last viewed a discussion thread."),
+      PM_EMAIL_NOTIFY_LEVEL_ALL => t('Always send a notification'),
+    ),
+    '#default_value' => variable_get('pm_email_notify_default_level', PM_EMAIL_NOTIFY_LEVEL_ALL),
+    '#description' => t('Choose when e-mail notifications will be sent by the system. Users with the appropriate permission may override this setting on the account edit page.'),
     '#weight' => 0,
   );
+  $form['pm_email']['pm_email_notify_only_user'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Only send e-mail notifications to individual users who are addressed directly'),
+    '#default_value' => variable_get('pm_email_notify_only_user', FALSE),
+    '#weight' => 5,
+  );
 
-  $form['pm_email']['pm_email_notify_desc'] = array(
-    '#type' => 'markup',
-    '#value' => t('Customize the email messages sent to users upon receipt of a new private message. <br />Available variables are: !author, !author_uid, !pm_subject, !pm_body, !thread, !site, !login_url, !uri, !uri_brief, !message (URL) and !settings (URL). <br />To translate these messages use the i18nstrings.module and translate them trough the <a href="!translate_url">Translate interface</a> ("Privatemsg Email Notification" text group).', array('!translate_url' => url('admin/build/translate/search'))),
-    '#weight' => 1,
+  $form['pm_email']['pm_email_template'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('E-mail customizations'),
+    '#weight' => 15,
+    '#description' => t('Customize the e-mail notification sent to users. Available variables are: !author, !author_uid, !pm_subject, !pm_body, !thread, !site, !login_url, !uri, !uri_brief, !message (URL) and !settings (URL).</p><p>To translate these messages use the i18nstrings.module and translate them trough the <a href="!translate_url">Translate interface</a> ("Privatemsg Email Notification" text group).</p>', array('!translate_url' => url('admin/build/translate/search'))),
   );
 
-  $form['pm_email']['pm_email_notify_from'] = array(
+  $form['pm_email']['pm_email_template']['pm_email_notify_from'] = array(
     '#type' => 'textfield',
     '#title' => t('From e-mail address for notifications'),
     '#default_value' => variable_get('pm_email_notify_from',''),
-    '#weight' => 2,
+    '#weight' => 10,
     '#description' => t('This is the e-mail address that notifications will come from. Leave blank to use the site default.'),
   );
 
-  $form['pm_email']['pm_email_notify_subject'] = array(
+  $form['pm_email']['pm_email_template']['pm_email_notify_subject'] = array(
     '#type' => 'textfield',
-    '#title' => t('Subject of notification messages'),
+    '#title' => t('Subject'),
     '#default_value' => _pm_email_notify_text('subject', NULL, FALSE),
-    '#weight' => 2,
+    '#weight' => 5,
   );
 
-  $form['pm_email']['pm_email_notify_body'] = array(
+  $form['pm_email']['pm_email_template']['pm_email_notify_body'] = array(
     '#type' => 'textarea',
-    '#title' => t('Body of notification messages'),
+    '#title' => t('Body'),
     '#default_value' => _pm_email_notify_text('body', NULL, FALSE),
-    '#weight' => 3,
+    '#weight' => 10,
   );
   return system_settings_form($form);
 }
\ No newline at end of file
diff --git a/pm_email_notify/pm_email_notify.install b/pm_email_notify/pm_email_notify.install
index 408d843..435bc56 100644
--- a/pm_email_notify/pm_email_notify.install
+++ b/pm_email_notify/pm_email_notify.install
@@ -18,12 +18,19 @@ function pm_email_notify_schema() {
         'not null'      => TRUE,
         'unsigned'      => TRUE,
       ),
-      'email_notify_is_enabled' => array(
-        'description'   => 'Email Notification Status (Enabled=1, Disabled=0)',
+      'email_notify_level' => array(
+        'description'   => 'Email Notification Level',
         'type'          => 'int',
         'not null'      => TRUE,
         'unsigned'      => TRUE,
       ),
+      'email_notify_only_user' => array(
+        'description'   => 'Email Notification \'only user\' setting.',
+        'type'          => 'int',
+        'size'          => 'tiny',
+        'not null'      => TRUE,
+        'unsigned'      => TRUE,
+      ),
     ),
     'unique keys' => array(
       'user_id' => array('user_id')
@@ -50,3 +57,52 @@ function pm_email_notify_uninstall() {
   variable_del('pm_email_notify_from');
   drupal_uninstall_schema('pm_email_notify');
 }
+
+/**
+ * Change the 'email_notify_is_enabled' field to 'email_notify_level'.
+ */
+function pm_email_notify_update_6201() {
+  $ret = array();
+
+  // Change the field.
+  $spec = array(
+    'description'   => 'Email Notification Level',
+    'type'          => 'int',
+    'not null'      => TRUE,
+    'unsigned'      => TRUE,
+  );
+  db_change_field($ret, 'pm_email_notify', 'email_notify_is_enabled', 'email_notify_level', $spec);
+
+  // Update existing user settings.
+  db_query("UPDATE {pm_email_notify} SET email_notify_level = %d WHERE email_notify_level = 1", PM_EMAIL_NOTIFY_LEVEL_ALL);
+
+  // Update the site-wide default setting.
+  if (variable_get('pm_email_notify_default', TRUE)) {
+    variable_set('pm_email_notify_default_level', PM_EMAIL_NOTIFY_LEVEL_ALL);
+  }
+  else {
+    variable_set('pm_email_notify_default_level', PM_EMAIL_NOTIFY_LEVEL_DISABLED);
+  }
+  variable_del('pm_email_notify_default');
+
+  return $ret;
+}
+
+/**
+ * Add the 'email_notify_only_user' field.
+ */
+function pm_email_notify_update_6202() {
+  $ret = array();
+  $spec = array(
+    'description'   => 'Email Notification \'only user\' setting.',
+    'type'          => 'int',
+    'size'          => 'tiny',
+    'not null'      => TRUE,
+    'unsigned'      => TRUE,
+  );
+  db_add_field($ret, 'pm_email_notify', 'email_notify_only_user', $spec);
+  return $ret;
+}
+
+
+
diff --git a/pm_email_notify/pm_email_notify.module b/pm_email_notify/pm_email_notify.module
index e3c2e39..bb1cead 100644
--- a/pm_email_notify/pm_email_notify.module
+++ b/pm_email_notify/pm_email_notify.module
@@ -6,6 +6,33 @@
  */
 
 /**
+ * Disable e-mail notifications.
+ */
+define('PM_EMAIL_NOTIFY_LEVEL_DISABLED', 0);
+
+/**
+ * Enable e-mail notifications only for new threads.
+ */
+define('PM_EMAIL_NOTIFY_LEVEL_THREAD', 4);
+
+/**
+ * Enable e-mail notifications only once until a user visits a threads.
+ */
+define('PM_EMAIL_NOTIFY_LEVEL_UNREAD_ONCE', 8);
+
+/**
+ * Enable e-mail notifications for all messages.
+ */
+define('PM_EMAIL_NOTIFY_LEVEL_ALL', 12);
+
+/**
+ * Implements hook_perm().
+ */
+function pm_email_notify_perm() {
+  return array('set privatemsg e-mail notification level', 'change privatemsg e-mail notification for indirect messages');
+}
+
+/**
  * Implements hook_menu().
  */
 function pm_email_notify_menu() {
@@ -23,46 +50,185 @@ function pm_email_notify_menu() {
 }
 
 /**
- * Retrieve notification setting of a user.
+ * Retrieve notification level of a user.
+ *
+ * This function retrieves user's pm notification level from database,
+ * if user preference doesn't exist - it uses default value instead.
+ *
+ * @param $uid
+ *   User ID.
+ *
+ * @return
+ *   Returns a PM_EMAIL_NOTIFY_LEVEL_* constant indicating the notification
+ *   level of the requested user.
+ */
+function _pm_email_notify_user_level($uid) {
+  static $levels = array();
+  // Cache the user's level in case this method is executed in
+  // batched operation.
+  if (!isset($levels[$uid])) {
+    $levels[$uid] = db_result(db_query('SELECT email_notify_level FROM {pm_email_notify} WHERE user_id = %d', $uid));
+    if ($levels[$uid] === FALSE) {
+      // db_result() returns FALSE if result was not found.
+      $levels[$uid] = variable_get('pm_email_notify_default_level', PM_EMAIL_NOTIFY_LEVEL_ALL);
+    }
+  }
+  return $levels[$uid];
+}
+
+/**
+ * Check if user should only be notified if he has been addressed directly.
+ *
+ * @param $uid
+ *   User ID.
+ *
+ * @param
+ *   TRUE if notifications should only be sent for directly addressed
+ *   recipients.
+ */
+function _pm_email_notify_only_user($uid = NULL) {
+  static $cache;
+
+  // The default setting should be honored if it is set.
+  if ($uid) {
+    if (!isset($cache[$uid])) {
+      $cache[$uid] = db_result(db_query("SELECT email_notify_only_user FROM {pm_email_notify} WHERE user_id = %d", $uid));
+      if ($cache[$uid] === FALSE) {
+        $cache[$uid] = variable_get('pm_email_notify_only_user', FALSE);
+      }
+    }
+    $only_user = $cache[$uid];
+  }
+
+  return $only_user;
+}
+
+/**
+ * Retrieve notification setting of a user and check if they should receive
+ * an e-mail notification for a message.
  *
- * This function retrieves user's pm notification preference from database,
- * if user preference doesn't exist - it uses default value instead
+ * Note: This function tries to return as quickly as possible, to avoid extra
+ * processing in batch executions.
  *
  * @param $uid
  *   User uid
+ * @param $message
+ *   Message.
  */
-function _pm_email_notify_is_enabled($uid) {
+function _pm_email_notify_send_check($uid, $message) {
   static $notifications = array();
-  // Cache the result set in case this method is executed in batched operation which will perform many unnecessary repeated selects for the same user
-  if ( !isset($notifications[$uid]) ) {
-    $mail_notification = db_result(db_query('SELECT email_notify_is_enabled FROM {pm_email_notify} WHERE user_id = %d', $uid));
-    if ($mail_notification === FALSE) {
-      // db_result() returns FALSE if result was not found.
-      $mail_notification = variable_get('pm_email_notify_default', TRUE);
+  static $threads = array();
+
+  $mid = $message['mid'];
+  $thread_id = $message['thread_id'];
+  $level = _pm_email_notify_user_level($uid);
+
+  // If the user has notifications disabled, we can skip the rest.
+  if ($level == PM_EMAIL_NOTIFY_LEVEL_DISABLED) {
+    return FALSE;
+  }
+
+  // If the user has all notifications enabled, we can skip the rest.
+  if ($level == PM_EMAIL_NOTIFY_LEVEL_ALL) {
+    return TRUE;
+  }
+
+  // Cache the result set in case this method is executed in batched operation
+  // which will perform many unnecessary repeated processing.
+  if (!isset($notifications[$uid][$mid])) {
+    // Prime the setting to false.
+    $notifications[$uid][$mid] = FALSE;
+
+    if ($level == PM_EMAIL_NOTIFY_LEVEL_THREAD) {
+      // Is this the origin of a thread?
+      $notifications[$uid][$mid] = ($mid == $thread_id);
+    }
+    elseif ($level == PM_EMAIL_NOTIFY_LEVEL_UNREAD_ONCE) {
+      // Is this the origin of a thread?
+      if ($mid == $thread_id) {
+        $notifications[$uid][$mid] = TRUE;
+        return $notifications[$uid][$mid];
+      }
+
+      // Fetch the thread's original message.
+      if (!isset($threads[$thread_id])) {
+        $result = db_query("SELECT * FROM {pm_message} WHERE mid = %d", $thread_id);
+        $threads[$thread_id] = db_fetch_array($result);
+      }
+
+      // Is this user the thread author?
+      if ($uid == $threads[$thread_id]['author']) {
+        $notifications[$uid][$mid] = TRUE;
+        return $notifications[$uid][$mid];
+      }
+
+      // Fetch an array of users who have replied to this thread.
+      if (!isset($threads[$thread_id]['replied'])) {
+        $threads[$thread_id]['replied'] = array();
+        $result = db_query("SELECT pm.author FROM {pm_message} pm INNER JOIN {pm_index} pmi ON pm.mid = pmi.mid WHERE pmi.thread_id = %d", $thread_id);
+        while($recipient = db_fetch_object($result)) {
+          $threads[$thread_id]['replied'][$recipient->author] = $recipient->author;
+        }
+      }
+
+      // Has this user replied to this thread?
+      if (isset($threads[$thread_id]['replied']) && in_array($uid, $threads[$thread_id]['replied'])) {
+        $notifications[$uid][$mid] = TRUE;
+      }
     }
-    $notifications[$uid] = $mail_notification;
   }
-  return $notifications[$uid];
+
+  return $notifications[$uid][$mid];
 }
 
 /**
  * Implements hook_privatemsg_message_insert().
  */
-function pm_email_notify_privatemsg_message_insert($message) {
-  foreach ($message['recipients'] as $recipient) {
-    // check if recipient enabled email notifications
-    if (isset($recipient->uid) && _pm_email_notify_is_enabled($recipient->uid)) {
-      // send them a new pm notification email if they did
-      $params['recipient'] = $recipient;
-      $params['message'] = $message;
-      $from = variable_get('pm_email_notify_from', '');
-      drupal_mail('pm_email_notify', 'notice', $recipient->mail, user_preferred_language($recipient), $params, !empty($from) ? $form : NULL);
+ function pm_email_notify_privatemsg_message_insert($message) {
+   foreach ($message['recipients'] as $recipient) {
+    pm_email_notify_send_mail($recipient, $message);
+  }
+}
+
+/**
+ * Implements hook_privatemsg_message_recipient_changed().
+ *
+ * Notifies users who were added to a message about new Private Messages
+ * via Email.
+ */
+function pm_email_notify_privatemsg_message_recipient_changed($mid, $thread_id, $recipient_id, $type, $added) {
+  $types = array('user');
+
+  // Only send mail if the recipient was added.
+  if ($added) {
+    if ($message = privatemsg_message_load($mid)) {
+      // Check if we should send an email to 'hidden' recipients.
+      if (!_pm_email_notify_only_user($recipient_id)) {
+        $types[] = 'hidden';
+      }
+      if (in_array($type, $types) && _pm_email_notify_send_check($recipient_id) && ($recipient = privatemsg_user_load($recipient_id))) {
+        pm_email_notify_send_mail($recipient, $message);
+      }
     }
   }
 }
 
 /**
- * Implements hook_mail().
+ * Send a pm notification email to a recipient.
+ */
+function pm_email_notify_send_mail($recipient, $message) {
+  // check if recipient enabled email notifications
+  if (isset($recipient->uid) && !empty($recipient->mail) && _pm_email_notify_send_check($recipient->uid, $message)) {
+    // send them a new pm notification email if they did
+    $params['recipient'] = $recipient;
+    $params['message'] = $message;
+    $from = variable_get('pm_email_notify_from', '');
+    drupal_mail('pm_email_notify', 'notice', $recipient->mail, user_preferred_language($recipient), $params, !empty($from) ? $form : NULL);
+  }
+}
+
+/**
+* Implements hook_mail().
  */
 function pm_email_notify_mail($key, &$message, $params) {
   $language = $message['language'];
@@ -148,27 +314,58 @@ function pm_email_notify_user($op, &$edit, &$account, $category = NULL) {
   switch ($op) {
     case 'form':
       if ($category == 'account' && privatemsg_user_access('read privatemsg')) {
-        $form['privatemsg']['pm_send_notifications'] = array(
+        if (privatemsg_user_access('set privatemsg e-mail notification level')) {
+          $form['privatemsg']['pm_email_notify_level'] = array(
+            '#type' => 'radios',
+            '#title' => t('Send me an e-mail notification...'),
+            '#options' => array(
+              PM_EMAIL_NOTIFY_LEVEL_DISABLED => t('Never.'),
+              PM_EMAIL_NOTIFY_LEVEL_THREAD => t('Only for a new conversation'),
+              PM_EMAIL_NOTIFY_LEVEL_UNREAD_ONCE => t("Only once for a conversation until I've read the messages"),
+              PM_EMAIL_NOTIFY_LEVEL_ALL => t('Every time I receive a message'),
+            ),
+            '#default_value' => _pm_email_notify_user_level($account->uid),
+          );
+        }
+        else {
+          // If the user does not have permissions to customize the notification
+          // level, still allow him to disable or enable notifications using the
+          // default level.
+          $form['privatemsg']['pm_email_notify_level'] = array(
+            '#type' => 'checkbox',
+            '#title' => t('Receive email notification for incoming private messages'),
+            '#default_value' => (bool)_pm_email_notify_user_level($account->uid),
+          );
+        }
+        $form['privatemsg']['pm_email_only_user'] = array(
           '#type' => 'checkbox',
-          '#title' => t('Receive email notification for incoming private messages'),
-          '#default_value' => _pm_email_notify_is_enabled($account->uid),
+          '#title' => t("Don't send me e-mail notifications for mass messages."),
+          '#default_value' => _pm_email_notify_only_user($account->uid),
+          '#access' => privatemsg_user_access('change privatemsg e-mail notification for indirect messages'),
         );
       }
       return $form;
 
     case 'submit':
-      if (isset($edit['pm_send_notifications']) && privatemsg_user_access('read privatemsg')) {
-        $pm_email_enabled = $edit['pm_send_notifications'];
-        unset($edit['pm_send_notifications']);
+      if (isset($edit['pm_email_notify_level']) && privatemsg_user_access('read privatemsg')) {
+        $email_notify_level = $edit['pm_email_notify_level'];
+        if (!privatemsg_user_access('set privatemsg e-mail notification level')) {
+          // If the user is not allowed to set the notification level, use the
+          // default if he wants notifications.
+          $email_notify_level *= (int)variable_get('pm_email_notify_default_level', PM_EMAIL_NOTIFY_LEVEL_ALL);
+        }
+        $email_only_user = $edit['pm_email_only_user'];
+        unset($edit['pm_email_notify_level']);
+        unset($edit['pm_email_only_user']);
         // Update database entry with user preference.
         $exists = db_result(db_query("SELECT 1 FROM {pm_email_notify} WHERE user_id = %d", $account->uid));
         if ($exists) {
           // If there is an existing entry, update.
-          db_query("UPDATE {pm_email_notify} SET email_notify_is_enabled = %d WHERE user_id = %d", $pm_email_enabled, $account->uid);
+          db_query("UPDATE {pm_email_notify} SET email_notify_level = %d, email_notify_only_user = %d WHERE user_id = %d", $email_notify_level, $email_notify_only_user, $account->uid);
         }
         else {
           // If not, create a new one.
-          db_query("INSERT INTO {pm_email_notify} (email_notify_is_enabled, user_id) VALUES (%d, %d)", $pm_email_enabled, $account->uid);
+          db_query("INSERT INTO {pm_email_notify} (email_notify_level, email_notify_only_user, user_id) VALUES (%d, %d, %d)", $email_notify_level, $email_notify_only_user, $account->uid);
         }
       }
       break;
diff --git a/privatemsg.api.php b/privatemsg.api.php
index 0922740..8fa36ac 100644
--- a/privatemsg.api.php
+++ b/privatemsg.api.php
@@ -370,14 +370,14 @@ function hook_privatemsg_message_insert($message) {
  *   Id of the message.
  * @param $thread_id
  *   Id of the thread the message belongs to.
- * @param $recipient
+ * @param $recipient_id
  *   Recipient id, a user id if type is user or hidden.
  * @param $type
  *   Type of the recipient.
  * @param $added
  *   TRUE if the recipient is added, FALSE if he is removed.
  */
-function hook_privatemsg_message_recipient_changed($mid, $thread_id, $recipient, $type, $added) {
+function hook_privatemsg_message_recipient_changed($mid, $thread_id, $recipient_id, $type, $added) {
   if ($added && ($type == 'user' || $type == 'hidden')) {
     privatemsg_filter_add_tags(array($thread_id), variable_get('privatemsg_filter_inbox_tag', ''), (object)array('uid' => $recipient));
   }
@@ -669,4 +669,4 @@ function hook_privatemsg_recipient_type_info_alter(&$types) {
 
 /**
  * @}
- */
\ No newline at end of file
+ */
diff --git a/privatemsg.module b/privatemsg.module
index 3b09803..368be8e 100644
--- a/privatemsg.module
+++ b/privatemsg.module
@@ -1868,11 +1868,13 @@ function privatemsg_get_link($recipients, $account = array(), $subject = NULL) {
  * @param $account
  *   For which account the message should be loaded.
  *   Defaults to the current user.
+ * @param $reset
+ *   Reset the static cache.
  *
  * @ingroup api
  */
-function privatemsg_message_load($pmid, $account = NULL) {
-  $messages = privatemsg_message_load_multiple(array($pmid), $account);
+function privatemsg_message_load($pmid, $account = NULL, $reset = FALSE) {
+  $messages = privatemsg_message_load_multiple(array($pmid), $account, $reset);
   return current($messages);
 }
 
@@ -1884,30 +1886,60 @@ function privatemsg_message_load($pmid, $account = NULL) {
  * @param $account
  *   For which account the message should be loaded.
  *   Defaults to the current user.
+ * @param $reset
+ *   Reset the static cache.
  *
  * @ingroup api
  */
-function privatemsg_message_load_multiple($pmids, $account = NULL) {
+function privatemsg_message_load_multiple($pmids, $account = NULL, $reset = FALSE) {
+  static $cache = array();
+  if ($reset) {
+    $cache = array();
+  }
+
   // Avoid SQL error that would happen with an empty pm.mid IN () clause.
   if (empty($pmids)) {
     return array();
   }
 
-  $query = _privatemsg_assemble_query('load', $pmids, $account);
-  $result = db_query($query['query']);
+  // If account is null, we need the current user's uid for caching.
+  if (isset($account->uid)) {
+    $uid = $account->uid;
+  }
+  else {
+    $uid = $GLOBALS['user']->uid;
+  }
+
+  // Collect cached messages and remove any pmids that were found.
   $messages = array();
-  while ($message = db_fetch_array($result)) {
-    // Load author of message.
-    if (!($message['author'] = privatemsg_user_load($message['author']))) {
-      // If user does not exist, load anonymous user.
-      $message['author'] = privatemsg_user_load(0);
+  foreach ($pmids as $key => $pmid) {
+    if (isset($cache[$uid][$pmid])) {
+      $messages[$pmid] = $cache[$uid][$pmid];
+      unset($pmids[$key]);
     }
-    $returned = module_invoke_all('privatemsg_message_load', $message);
-    if (!empty($returned)) {
-      $message = array_merge_recursive($returned, $message);
+  }
+
+  // Load any remaining uncached messages.
+  if (!empty($pmids)) {
+    $query = _privatemsg_assemble_query('load', $pmids, $account);
+    $result = db_query($query['query']);
+    while ($message = db_fetch_array($result)) {
+      // Load author of message.
+      if (!($message['author'] = privatemsg_user_load($message['author']))) {
+        // If user does not exist, load anonymous user.
+        $message['author'] = privatemsg_user_load(0);
+      }
+      $returned = module_invoke_all('privatemsg_message_load', $message);
+      if (!empty($returned)) {
+        $message = array_merge_recursive($returned, $message);
+      }
+
+      // Add to cache and to current result set.
+      $cache[$uid][$message['mid']] = $message;
+      $messages[$message['mid']] = $message;
     }
-    $messages[$message['mid']] = $message;
   }
+
   return $messages;
 }
 
-- 
1.7.4.1

