? overlay_subtabs_invisible.png
Index: privatemsg.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/privatemsg/privatemsg.install,v
retrieving revision 1.5.2.4.2.11.2.11.2.9
diff -u -p -r1.5.2.4.2.11.2.11.2.9 privatemsg.install
--- privatemsg.install	12 Jul 2010 08:08:45 -0000	1.5.2.4.2.11.2.11.2.9
+++ privatemsg.install	20 Jul 2010 10:32:03 -0000
@@ -101,6 +101,14 @@ function privatemsg_schema() {
         'not null'      => TRUE,
         'unsigned'      => TRUE,
       ),
+      'has_tokens'     => array(
+        'description'   => 'Indicates if the message has tokens',
+        'type'          => 'int',
+        'size'          => 'small',
+        'not null'      => TRUE,
+        'unsigned'      => TRUE,
+        'default'       => 0,
+      ),
     ),
     'primary key'     => array('mid'),
     'indexes'         => array(
@@ -141,3 +149,14 @@ function privatemsg_uninstall() {
   variable_del('privatemsg_no_messages_notification');
   variable_del('privatemsg_display_on_comments');
 }
+
+function privatemsg_update_7000() {
+  db_add_field('pm_message', 'has_tokens', array(
+    'description'   => 'Indicates if the message has tokens',
+    'type'          => 'int',
+    'size'          => 'small',
+    'not null'      => TRUE,
+    'unsigned'      => TRUE,
+    'default'       => 0,
+  ));
+}
\ No newline at end of file
Index: privatemsg.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/privatemsg/privatemsg.module,v
retrieving revision 1.70.2.30.2.91.2.64.2.78
diff -u -p -r1.70.2.30.2.91.2.64.2.78 privatemsg.module
--- privatemsg.module	18 Jul 2010 21:03:42 -0000	1.70.2.30.2.91.2.64.2.78
+++ privatemsg.module	20 Jul 2010 10:32:05 -0000
@@ -48,6 +48,10 @@ function privatemsg_permission() {
       'title' => t('Allow disabling privatemsg'),
       'description' => t("Allows user to disable privatemsg so that they can't recieve any private messages.")
     ),
+    'use tokens in privatemsg' => array(
+      'title' => t('Use tokens in private messages'),
+      'description' => t("Allows user to use available tokens when sending private messages.")
+    ),
   );
 }
 
@@ -505,6 +509,9 @@ function privatemsg_thread_load($thread_
         $thread['user'] = $account;
         $message = current($thread['messages']);
         $thread['subject'] = $message->subject;
+        if ($message->has_tokens) {
+          $thread['subject'] = token_replace($thread['subject'], array('privatemsg_message' => $message));
+        }
       }
       $threads[$account->uid][$thread_id] = $thread;
     }
@@ -676,6 +683,10 @@ function privatemsg_preprocess_privatems
     ),
   );
 
+  if ($message->has_tokens) {
+    $message->content['body']['#markup'] = token_replace($message->content['body']['#markup'], array('privatemsg_message' => $message));
+  }
+
   // Build fields content.
   field_attach_prepare_view('privatemsg_message', array($vars['mid'] => $message), 'message');
   $message->content += field_attach_view('privatemsg_message', $message, 'message');
@@ -907,6 +918,7 @@ function privatemsg_sql_list($account, $
   $query->addField('pmi', 'thread_id');
   $query->addExpression('MIN(pm.subject)', 'subject');
   $query->addExpression('MAX(pm.timestamp)', 'last_updated');
+  $query->addExpression('MAX(pm.has_tokens)', 'has_tokens');
   $query->addExpression('SUM(pmi.is_new)', 'is_new');
 
   // Load enabled columns
@@ -951,7 +963,7 @@ function privatemsg_sql_list($account, $
  */
 function privatemsg_sql_load($pmids, $account = NULL) {
   $query = db_select('pm_message', 'pm')
-    ->fields('pm', array('mid', 'author', 'subject', 'body', 'timestamp', 'format'))
+    ->fields('pm', array('mid', 'author', 'subject', 'body', 'timestamp', 'format', 'has_tokens'))
     ->fields('pmi', array('is_new', 'thread_id'))
     ->condition('pmi.mid', $pmids)
     ->orderBy('pm.timestamp', 'ASC')
@@ -1621,6 +1633,9 @@ function _privatemsg_validate_message(&$
     }
   }
 
+  // Verify if message has tokens and user is allowed to use them.
+  $message->has_tokens = privatemsg_user_access('use tokens in privatemsg', $message->author) && count(token_scan($message->subject . $message->body));
+
   $messages += module_invoke_all('privatemsg_message_validate', $message, $form);
   // Check if there are errors in $messages or if $form is TRUE, there are form errors.
   $success = empty($messages['error']) || ($form && count((array)form_get_errors()) > 0);
@@ -1671,6 +1686,7 @@ function _privatemsg_send($message) {
     $args['body'] = $message->body;
     $args['format'] = $message->format;
     $args['timestamp'] = $message->timestamp;
+    $args['has_tokens'] = $message->has_tokens;
     $mid = db_insert('pm_message')
       ->fields($args)
       ->execute();
@@ -2518,4 +2534,115 @@ function privatemsg_field_extra_fields()
     )
   );
   return $extra;
+}
+
+function privatemsg_token_info() {
+  $type = array(
+    'name' => t('Private message'),
+    'description' => t('Tokens related to private messages.'),
+    'needs-data' => 'privatemsg_message',
+  );
+
+  // Core tokens for nodes.
+  $message['mid'] = array(
+    'name' => t("Message ID"),
+    'description' => t("The unique ID of the message."),
+  );
+  $message['subject'] = array(
+    'name' => t("Subject"),
+    'description' => t("The subject of the message."),
+  );
+
+  // Chained tokens for nodes.
+  $message['sent'] = array(
+    'name' => t("Date created"),
+    'description' => t("The date the message was sent."),
+    'type' => 'date',
+  );
+  $message['author'] = array(
+    'name' => t("Author"),
+    'description' => t("The author of the message."),
+    'type' => 'user',
+  );
+  $message['recipient'] = array(
+    'name' => t("Recipient"),
+    'description' => t("The recipient of the message. Tokens are only replaced when the user viewing the message is a recipient."),
+    'type' => 'user',
+  );
+
+  return array(
+    'types' => array('privatemsg_message' => $type),
+    'tokens' => array('privatemsg_message' => $message),
+  );
+}
+
+function privatemsg_tokens($type, $tokens, array $data = array(), array $options = array()) {
+  global $user;
+  if (isset($options['language'])) {
+    $url_options['language'] = $options['language'];
+    $language_code = $options['language']->language;
+  }
+  else {
+    $language_code = NULL;
+  }
+  $sanitize = !empty($options['sanitize']);
+  $replacements = array();
+  if ($type == 'privatemsg_message' && !empty($data['privatemsg_message'])) {
+    $message = $data['privatemsg_message'];
+
+    foreach ($tokens as $name => $original) {
+      switch ($name) {
+        // Simple key values on the node.
+        case 'mid':
+          $replacements[$original] = $message->mid;
+          break;
+
+        case 'subject':
+          $replacements[$original] = $sanitize ? check_plain($message->subject) : $message->subject;
+          break;
+
+        // Default values for the chained tokens handled below.
+        case 'author':
+          $name = $message->author->name;
+          $replacements[$original] = $sanitize ? filter_xss($name) : $name;
+          break;
+
+        case 'recipient':
+          // Verify that the current user is not the author and a recipient of
+          // the message.
+          $sql = "SELECT 1 FROM {pm_index} WHERE recipient = :uid AND type IN ('hidden', 'user') AND mid = :mid";
+          $args = array(':uid' => $user->uid, ':mid' => $message->mid);
+          if ($user->uid != $message->author->uid && db_query($sql, $args)->fetchField()) {
+            $name = $user->name;
+            $replacements[$original] = $sanitize ? filter_xss($name) : $name;
+            break;
+          }
+
+        case 'sent':
+          $replacements[$original] = format_date($message->timestamp, 'medium', '', NULL, $language_code);
+          break;
+      }
+    }
+
+    if ($author_tokens = token_find_with_prefix($tokens, 'author')) {
+      $replacements += token_generate('user', $author_tokens, array('user' => $message->author), $options);
+    }
+
+    if ($recipient_tokens = token_find_with_prefix($tokens, 'recipient')) {
+
+      // Verify that the current user is not the author and a recipient of
+      // the message.
+      $sql = "SELECT 1 FROM {pm_index} WHERE recipient = :uid AND type IN ('hidden', 'user') AND mid = :mid";
+      $args = array(':uid' => $user->uid, ':mid' => $message->mid);
+      if ($user->uid != $message->author->uid && db_query($sql, $args)->fetchField()) {
+        $replacements += token_generate('user', $recipient_tokens, array('user' => $user), $options);
+      }
+    }
+
+    if ($sent_tokens = token_find_with_prefix($tokens, 'sent')) {
+      $replacements += token_generate('date', $sent_tokens, array('date' => $message->timestamp), $options);
+    }
+  }
+
+  return $replacements;
 }
\ No newline at end of file
Index: privatemsg.pages.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/privatemsg/privatemsg.pages.inc,v
retrieving revision 1.1.2.17
diff -u -p -r1.1.2.17 privatemsg.pages.inc
--- privatemsg.pages.inc	18 Jul 2010 21:03:42 -0000	1.1.2.17
+++ privatemsg.pages.inc	20 Jul 2010 10:32:05 -0000
@@ -353,6 +353,13 @@ function privatemsg_new($form, &$form_st
     '#resizable'          => TRUE,
     '#format'             => isset($format) ? $format : NULL,
   );
+  if (privatemsg_user_access('use tokens in privatemsg') && module_exists('token')) {
+    $form['token'] = array(
+      '#theme' => 'token_tree',
+      '#weight' => 99,
+      '#token_types' => array('privatemsg_message'),
+    );
+  }
   $form['actions'] = array('#type' => 'actions');
   $form['actions']['preview'] = array(
     '#type'               => 'submit',
Index: privatemsg.theme.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/privatemsg/privatemsg.theme.inc,v
retrieving revision 1.1.2.7.2.9
diff -u -p -r1.1.2.7.2.9 privatemsg.theme.inc
--- privatemsg.theme.inc	12 Jul 2010 08:08:45 -0000	1.1.2.7.2.9
+++ privatemsg.theme.inc	20 Jul 2010 10:32:05 -0000
@@ -99,7 +99,12 @@ function theme_privatemsg_list_field__su
     $is_new = theme('mark', array('type' => MARK_NEW));
     $options['fragment'] = 'new';
   }
-  $field['data'] = l($thread['subject'], 'messages/view/' . $thread['thread_id'], $options) . $is_new;
+  $subject = $thread['subject'];
+  if ($thread['has_tokens']) {
+    $message = privatemsg_message_load($thread['thread_id']);
+    $subject = token_replace($subject, array('privatemsg_message' => $message));
+  }
+  $field['data'] = l($subject, 'messages/view/' . $thread['thread_id'], $options) . $is_new;
   $field['class'][] = 'privatemsg-list-subject';
   return $field;
 }
