? overlay_subtabs_invisible.png
Index: privatemsg.api.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/privatemsg/privatemsg.api.php,v
retrieving revision 1.1.2.5.2.3
diff -u -p -r1.1.2.5.2.3 privatemsg.api.php
--- privatemsg.api.php	27 Oct 2009 12:56:16 -0000	1.1.2.5.2.3
+++ privatemsg.api.php	19 Jun 2010 07:55:47 -0000
@@ -307,7 +307,7 @@ function hook_privatemsg_message_validat
 
   $errors = array();
 
-  foreach ($message['recipients'] as $recipient) {
+  foreach ($message->recipients as $recipient) {
     if ($recipient->name == 'blocked user') {
       $_privatemsg_invalid_recipients[] = $recipient->uid;
       $errors[] = t('%name has chosen to not recieve any more messages from you.', array('%name' => $recipient->name));
@@ -328,7 +328,7 @@ function hook_privatemsg_message_presave
   // delete recipients which have been marked as invalid
   global $_privatemsg_invalid_recipients;
   foreach ($_privatemsg_invalid_recipients as $invalid) {
-    unset($message['recipients'][$invalid]);
+    unset($message->recipients[$invalid]);
   }
 }
 /**
@@ -355,7 +355,7 @@ function hook_privatemsg_message_view_al
  *   Message array
  */
 function hook_privatemsg_message_insert($message) {
-  _mymodule_save_data($message['mid']);
+  _mymodule_save_data($message->mid);
 }
 
 /**
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.63
diff -u -p -r1.70.2.30.2.91.2.64.2.63 privatemsg.module
--- privatemsg.module	19 Jun 2010 07:06:48 -0000	1.70.2.30.2.91.2.64.2.63
+++ privatemsg.module	19 Jun 2010 07:55:48 -0000
@@ -483,7 +483,7 @@ function privatemsg_thread_load($thread_
         // General data, assume subject is the same for all messages of that thread.
         $thread['user'] = $account;
         $message = current($thread['messages']);
-        $thread['subject'] = $message['subject'];
+        $thread['subject'] = $message->subject;
       }
       $threads[$account->uid][$thread_id] = $thread;
     }
@@ -580,20 +580,24 @@ function privatemsg_preprocess_privatems
 //  drupal_set_message('<pre>'. print_r($vars,1 ) . '</pre>');
 
   $message = $vars['message'];
-  $vars['mid'] = isset($message['mid']) ? $message['mid'] : NULL;
-  $vars['thread_id'] = isset($message['thread_id']) ? $message['thread_id'] : NULL;
-  $vars['author_picture'] = theme('user_picture', array('account' => $message['author']));
-  $vars['author_name_link'] = theme('username', array('account' => $message['author']));
+  $vars['mid'] = isset($message->mid) ? $message->mid : NULL;
+  $vars['thread_id'] = isset($message->thread_id) ? $message->thread_id : NULL;
+  $vars['author_picture'] = theme('user_picture', array('account' => $message->author));
+  $vars['author_name_link'] = theme('username', array('account' => $message->author));
   /**
    * @todo perhaps make this timestamp configurable via admin UI?
    */
-  $vars['message_timestamp'] = format_date($message['timestamp'], 'small');
-  $vars['message_body'] = check_markup($message['body'], $message['format']);
+  $vars['message_timestamp'] = format_date($message->timestamp, 'small');
+  // Build fields content.
+  field_attach_prepare_view('privatemsg_message', array($vars['mid'] => $message), 'message');
+  $content = drupal_render(field_attach_view('privatemsg_message', $message, 'message'));
+
+  $vars['message_body'] = check_markup($message->body, $message->format) . $content;
   if (isset($vars['mid']) && isset($vars['thread_id']) && privatemsg_user_access('delete privatemsg')) {
     $vars['message_actions'][] = array('title' => t('Delete message'), 'href' => 'messages/delete/' . $vars['thread_id'] . '/' . $vars['mid']);
   }
   $vars['message_anchors'][] = 'privatemsg-mid-' . $vars['mid'];
-  if (!empty($message['is_new'])) {
+  if (!empty($message->is_new)) {
     $vars['message_anchors'][] = 'new';
     $vars['new'] = drupal_ucfirst(t('new'));
   }
@@ -1209,25 +1213,25 @@ function privatemsg_new_thread($recipien
   global $user;
   $author = clone $user;
 
-  $message = array();
-  $message['subject'] = $subject;
-  $message['body'] = $body;
+  $message = (object)$options;
+  $message->subject = $subject;
+  $message->body = $body;
   // Make sure that recipients are keyed by user id and are not added
   // multiple times.
   foreach ($recipients as $recipient) {
-    $message['recipients'][$recipient->uid] = $recipient;
+    $message->recipients[$recipient->uid] = $recipient;
   }
 
-  // Set custom options, if any.
-  if (!empty($options)) {
-    $message += $options;
-  }
   // Apply defaults - this will not overwrite existing keys.
-  $message += array(
-    'author' => $author,
-    'timestamp' => time(),
-    'format' => filter_default_format($author),
-  );
+  if (!isset($message->author)) {
+    $message->author = $author;
+  }
+  if (!isset($message->timestamp)) {
+    $message->timestamp = time();
+  }
+  if (!isset($message->format)) {
+    $message->format = filter_default_format($author);
+  }
 
   $validated = _privatemsg_validate_message($message);
   if ($validated['success']) {
@@ -1274,23 +1278,23 @@ function privatemsg_reply($thread_id, $b
   global $user;
   $author = clone $user;
 
-  $message = array();
-  $message['body'] = $body;
+  $message = (object)$options;
+  $message->body = $body;
 
-  // set custom options, if any
-  if (!empty($options)) {
-    $message += $options;
-  }
-  // apply defaults
-  $message += array(
-    'author' => $author,
-    'timestamp' => time(),
-    'format' => filter_default_format($author),
-  );
+  // Apply defaults - this will not overwrite existing keys.
+  if (!isset($message->author)) {
+    $message->author = $author;
+  }
+  if (!isset($message->timestamp)) {
+    $message->timestamp = time();
+  }
+  if (!isset($message->format)) {
+    $message->format = filter_default_format($author);
+  }
 
   // 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_message_load($thread_id, $message['author']);
+  $first_message = privatemsg_message_load($thread_id, $message->author);
   if (!$first_message) {
     return array(
       'success'  => FALSE,
@@ -1298,16 +1302,14 @@ function privatemsg_reply($thread_id, $b
     );
   }
 
-  $message['thread_id'] = $thread_id;
+  $message->thread_id = $thread_id;
 
-  // Load participants.
-  $message['recipients'] = _privatemsg_load_thread_participants($thread_id);
+  $message->recipients = _privatemsg_load_thread_participants($thread_id);
   // Remove author.
-  if (isset($message['recipients'][$message['author']->uid]) && count($message['recipients']) > 1) {
-    unset($message['recipients'][$message['author']->uid]);
+  if (isset($message->recipients[$message->author->uid]) && count($message->recipients) > 1) {
+    unset($message->recipients[$message->author->uid]);
   }
-  $message['subject'] = $first_message['subject'];
-
+  $message->subject = $first_message->subject;
   $validated = _privatemsg_validate_message($message);
   if ($validated['success']) {
     $validated['message'] = _privatemsg_send($message);
@@ -1317,17 +1319,17 @@ function privatemsg_reply($thread_id, $b
 
 function _privatemsg_validate_message(&$message, $form = FALSE) {
   $messages = array('error' => array(), 'warning' => array());
-  if (!privatemsg_user_access('write privatemsg', $message['author'])) {
+  if (!privatemsg_user_access('write privatemsg', $message->author)) {
     // no need to do further checks in this case...
     if ($form) {
-      form_set_error('author', t('User @user is not allowed to write messages', array('@user' => $message['author']->name)));
+      form_set_error('author', t('User @user is not allowed to write messages', array('@user' => $message->author->name)));
       return array(
         'success'  => FALSE,
         'messages'   => $messages,
       );
     }
     else {
-      $messages['error'][] = t('User @user is not allowed to write messages', array('@user' => $message['author']->name));
+      $messages['error'][] = t('User @user is not allowed to write messages', array('@user' => $message->author->name));
       return array(
          'success'  => FALSE,
          'messages'   => $messages,
@@ -1335,7 +1337,7 @@ function _privatemsg_validate_message(&$
     }
   }
 
-  if (empty($message['subject'])) {
+  if (empty($message->subject)) {
     if ($form) {
       form_set_error('subject', t('Disallowed to send a message without a subject'));
     }
@@ -1345,7 +1347,7 @@ function _privatemsg_validate_message(&$
   }
 
   // Don't allow replies without a body.
-  if (!empty($message['thread_id']) && empty($message['body'])) {
+  if (!empty($message->thread_id) && empty($message->body)) {
     if ($form) {
       form_set_error('body', t('Disallowed to send reply without a message.'));
     }
@@ -1355,16 +1357,16 @@ function _privatemsg_validate_message(&$
   }
 
   // Check if an allowed format is used.
-  if (!filter_access(filter_format_load($message['format']), $message['author'])) {
+  if (!filter_access(filter_format_load($message->format), $message->author)) {
     if ($form) {
       form_set_error('format', t('You are not allowed to use the specified input format.'));
     }
     else {
-      $messages['error'][] = t('User @user is not allowed to use the specified input format.', array('@user' => $message['author']->name));
+      $messages['error'][] = t('User @user is not allowed to use the specified input format.', array('@user' => $message->author->name));
     }
   }
 
-  if (empty($message['recipients']) || !is_array($message['recipients'])) {
+  if (empty($message->recipients) || !is_array($message->recipients)) {
     if ($form) {
       form_set_error('to', t('Disallowed to send a message without at least one valid recipient'));
     }
@@ -1373,9 +1375,9 @@ function _privatemsg_validate_message(&$
     }
   }
 
-  if (!empty($message['recipients']) && is_array($message['recipients'])) {
-    foreach(module_invoke_all('privatemsg_block_message', $message['author'], $message['recipients']) as $blocked) {
-      unset($message['recipients'][$blocked['uid']]);
+  if (!empty($message->recipients) && is_array($message->recipients)) {
+    foreach(module_invoke_all('privatemsg_block_message', $message->author, $message->recipients) as $blocked) {
+      unset($message->recipients[$blocked['uid']]);
       if ($form) {
         drupal_set_message($blocked['message'], 'warning');
       } else {
@@ -1385,7 +1387,7 @@ function _privatemsg_validate_message(&$
   }
 
   // Check again, give another error message if all recipients are blocked
-  if (empty($message['recipients'])) {
+  if (empty($message->recipients)) {
     if ($form) {
       form_set_error('to', t('Disallowed to send message because all recipients are blocked'));
     }
@@ -1418,17 +1420,18 @@ function _privatemsg_send($message) {
   $transaction = db_transaction();
   try {
     drupal_alter('privatemsg_message_presave', $message);
+    field_attach_presave('privatemsg_message', $message);
 
     $query = db_insert('pm_index')->fields(array('mid', 'thread_id', 'uid', 'is_new', 'deleted'));
-    if (isset($message['read_all']) && $message['read_all']) {
+    if (isset($message->read_all) && $message->read_all) {
       // The message was sent in read all mode, add the author as recipient to all
       // existing messages.
-      $query_messages = _privatemsg_assemble_query('messages', array($message['thread_id']), NULL);
+      $query_messages = _privatemsg_assemble_query('messages', array($message->thread_id), NULL);
       foreach ($query_messages->execute()->fetchCol() as $mid) {
         $query->values(array(
           'mid' => $mid,
-          'thread_id' => $message['thread_id'],
-          'uid' => $message['author']->uid,
+          'thread_id' => $message->thread_id,
+          'uid' => $message->author->uid,
           'is_new' => 0,
           'deleted' => 0,
         ));
@@ -1437,27 +1440,27 @@ function _privatemsg_send($message) {
 
     // 1) Save the message body first.
     $args = array();
-    $args['subject'] = $message['subject'];
-    $args['author'] = $message['author']->uid;
-    $args['body'] = $message['body'];
-    $args['format'] = $message['format'];
-    $args['timestamp'] = $message['timestamp'];
+    $args['subject'] = $message->subject;
+    $args['author'] = $message->author->uid;
+    $args['body'] = $message->body;
+    $args['format'] = $message->format;
+    $args['timestamp'] = $message->timestamp;
     $mid = db_insert('pm_message')
       ->fields($args)
       ->execute();
-    $message['mid'] = $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;
+    if (!isset($message->thread_id)) {
+      $message->thread_id = $mid;
     }
 
     // 2) Save message to recipients.
     // Each recipient gets a record in the pm_index table.
-    foreach ($message['recipients'] as $recipient) {
+    foreach ($message->recipients as $recipient) {
       $query->values(array(
         'mid' => $mid,
-        'thread_id' => $message['thread_id'],
+        'thread_id' => $message->thread_id,
         'uid' => $recipient->uid,
         'is_new' => 1,
         'deleted' => 0,
@@ -1466,19 +1469,20 @@ function _privatemsg_send($message) {
 
     // When author is also the recipient, we want to set message to UNREAD.
     // All other times the message is set to READ.
-    $is_new = isset($message['recipients'][$message['author']->uid]) ? 1 : 0;
+    $is_new = isset($message->recipients[$message->author->uid]) ? 1 : 0;
 
     // Also add a record for the author to the pm_index table.
     $query->values(array(
       'mid' => $mid,
-      'thread_id' => $message['thread_id'],
-      'uid' => $message['author']->uid,
+      'thread_id' => $message->thread_id,
+      'uid' => $message->author->uid,
       'is_new' => $is_new,
       'deleted' => 0,
     ));
     $query->execute();
 
     module_invoke_all('privatemsg_message_insert', $message);
+    field_attach_insert('privatemsg_message', $message);
 
   } catch (Exception $exception) {
     $transaction->rollback();
@@ -1577,19 +1581,20 @@ function privatemsg_message_load_multipl
   $result = _privatemsg_assemble_query('load', $pmids, $account)->execute();
 
   $messages = array();
-  while ($message = $result->fetchAssoc()) {
-    $message['user'] = $account;
+  foreach ($result as $message) {
+    $message->user = $account;
     // Load author of message.
-    if (!($message['author'] = user_load($message['author']))) {
+    if (!($message->author = user_load($message->author))) {
       // If user does not exist, load anonymous user.
-      $message['author'] = user_load(0);
+      $message->author = user_load(0);
     }
-    $returned = module_invoke_all('privatemsg_message_load', $message);
     if (!empty($returned)) {
       $message = array_merge_recursive($returned, $message);
     }
-    $messages[$message['mid']] = $message;
+    $messages[$message->mid] = $message;
   }
+  field_attach_load('privatemsg_message', $messages);
+  module_invoke_all('privatemsg_message_load', $messages);
   return $messages;
 }
 
@@ -1600,7 +1605,7 @@ function privatemsg_message_load_multipl
  *   Either be a string ('some_id') or an array('group_name', 'query_id'),
  *   if a string is supplied, group_name defaults to 'privatemsg'.
  *
- * @return
+ * @return SelectQuery
  *    Array with the keys query and count. count can be used to count the
  *    elements which would be returned by query. count can be used together
  *    with pager_query().
@@ -1904,6 +1909,42 @@ function privatemsg_privatemsg_thread_op
 }
 
 /**
+ * Implements hook_entity_info().
+ */
+function privatemsg_entity_info() {
+  return array(
+    'privatemsg_message' => array(
+      'label' => t('Privatemsg'),
+      'base table' => 'pm_message',
+      'fieldable' => TRUE,
+      'entity keys' => array(
+        'id' => 'mid',
+      ),
+      'bundles' => array(
+        'privatemsg_message' => array(
+          'label' => t('Private message'),
+          'admin' => array(
+            'path' => 'admin/config/messaging/privatemsg',
+            'access arguments' => array('administer privatemsg settings'),
+          ),    
+        ),
+      ),
+    ),
+  );
+}
+
+/**
+ * Implements hook_build_modes().
+ */
+function privatemsg_build_modes($obj_type) {
+  $modes = array();
+  if ($obj_type == 'privatemsg_message') {
+    $modes['message'] = t('Message');
+  }
+  return $modes;
+}
+
+/**
  * Implements hook_node_view().
  */
 function privatemsg_node_view($node, $view_mode) {
@@ -1950,4 +1991,4 @@ function privatemsg_views_api() {
     'api' => 2,
     'path' => drupal_get_path('module', 'privatemsg') . '/views',
   );
-}
\ 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.8
diff -u -p -r1.1.2.8 privatemsg.pages.inc
--- privatemsg.pages.inc	17 Jun 2010 20:57:15 -0000	1.1.2.8
+++ privatemsg.pages.inc	19 Jun 2010 07:55:48 -0000
@@ -66,11 +66,11 @@ function _privatemsg_action_form() {
 function privatemsg_delete($form, $form_state, $thread, $message) {
   $form['pmid'] = array(
     '#type' => 'value',
-    '#value' => $message['mid'],
+    '#value' => $message->mid,
   );
   $form['delete_destination'] = array(
     '#type' => 'value',
-    '#value' => count($thread['messages']) > 1 ? 'messages/view/' . $message['thread_id'] : 'messages',
+    '#value' => count($thread['messages']) > 1 ? 'messages/view/' . $message->thread_id : 'messages',
   );
 
   if (privatemsg_user_access('read all private messages')) {
@@ -83,7 +83,7 @@ function privatemsg_delete($form, $form_
   }
   return confirm_form($form,
     t('Are you sure you want to delete this message?'),
-    isset($_GET['destination']) ? $_GET['destination'] : 'messages/view/'. $message['thread_id'],
+    isset($_GET['destination']) ? $_GET['destination'] : 'messages/view/'. $message->thread_id,
     t('This action cannot be undone.'),
     t('Delete'),
     t('Cancel')
@@ -291,16 +291,16 @@ function privatemsg_new($form, &$form_st
     );
     $form['message_header']['message_preview'] = $form_state['privatemsg_preview'];
   }
-  $form['privatemsg'] = array(
+  $form = array(
     '#type'               => 'fieldset',
     '#access'             => privatemsg_user_access('write privatemsg'),
   );
-  $form['privatemsg']['author'] = array(
+  $form['author'] = array(
     '#type' => 'value',
     '#value' => $user,
   );
   if (is_null($thread_id)) {
-    $form['privatemsg']['recipient'] = array(
+    $form['recipient'] = array(
       '#type'               => 'textfield',
       '#title'              => t('To'),
       '#description'        => t('Separate multiple names with commas.'),
@@ -312,7 +312,7 @@ function privatemsg_new($form, &$form_st
       // Do not hardcode #maxlength, make it configurable by number of recipients, not their name length.
     );
   }
-  $form['privatemsg']['subject'] = array(
+  $form['subject'] = array(
     '#type'               => 'textfield',
     '#title'              => t('Subject'),
     '#size'               => 50,
@@ -326,7 +326,7 @@ function privatemsg_new($form, &$form_st
   if (isset($form_state['values']) && array_key_exists('format', $form_state['values'])) {
     $format = $form_state['values']['format'];
   }
-  $form['privatemsg']['body'] = array(
+  $form['body'] = array(
     '#type'               => 'text_format',
     '#title'              => t('Message'),
     '#rows'               => 6,
@@ -335,13 +335,13 @@ function privatemsg_new($form, &$form_st
     '#resizable'          => TRUE,
     '#format'             => isset($format) ? $format : NULL,
   );
-  $form['privatemsg']['preview'] = array(
+  $form['preview'] = array(
     '#type'               => 'submit',
     '#value'              => t('Preview message'),
     '#submit'             => array('privatemsg_new_preview'),
     '#weight'             => 10,
   );
-  $form['privatemsg']['submit'] = array(
+  $form['submit'] = array(
     '#type'               => 'submit',
     '#value'              => t('Send message'),
     '#weight'             => 15,
@@ -356,58 +356,65 @@ function privatemsg_new($form, &$form_st
     $title = t('Clear');
   }
 
-  $form['privatemsg']['cancel'] = array(
+  $form['cancel'] = array(
     '#value'              => l($title, $url, array('attributes' => array('id' => 'edit-cancel'))),
     '#weight'             => 20,
   );
 
   if (!is_null($thread_id)) {
-    $form['privatemsg']['thread_id'] = array(
+    $form['thread_id'] = array(
       '#type' => 'value',
       '#value' => $thread_id,
     );
-    $form['privatemsg']['subject'] = array(
+    $form['subject'] = array(
           '#type' => 'value',
           '#default_value' => $subject,
     );
     $recipients_string_themed = implode(', ', $to_themed);
-    $form['privatemsg']['recipient_display'] = array(
+    $form['recipient_display'] = array(
       '#markup' =>  '<p>'. t('<strong>Reply to thread</strong>:<br /> Recipients: !to', array('!to' => $recipients_string_themed)) .'</p>',
       '#weight' => -10,
     );
     if (empty($recipients_string)) {
       // If there are no valid recipients, unset the message reply form.
-      $form['privatemsg']['#access'] = FALSE;
+      $form['#access'] = FALSE;
     }
   }
-  $form['privatemsg']['read_all'] = array(
+  $form['read_all'] = array(
     '#type'  => 'value',
     '#value' => $read_all,
   );
+  // Attach field widgets.
+  $message = (object) array();
+  if (isset($form_state['validate_built_message'])) {
+    $message = $form_state['validate_built_message'];
+  }
+  field_attach_form('privatemsg_message', $message, $form, $form_state);
   return $form;
 }
 
 function privatemsg_new_validate($form, &$form_state) {
-  // The actual message that is being sent, we create this during validation and pass to submit to send out.
-  $message = $form_state['values'];
-  $message['format']    = $message['body']['format'];
-  $message['body']      = $message['body']['value'];
-  $message['timestamp'] = time();
-
-  $trimed_body = trim(truncate_utf8(strip_tags($message['body']), 50, TRUE, TRUE));
-  if (empty($message['subject']) && !empty($trimed_body)) {
-    $message['subject'] = $trimed_body;
+  // The actual message that is being sent, we create this during validation and
+  // pass to submit to send out.
+  $message = (object)$form_state['values'];
+  $message->format    = $message->body['format'];
+  $message->body      = $message->body['value'];
+  $message->timestamp = time();
+
+  $trimed_body = trim(truncate_utf8(strip_tags($message->body), 50, TRUE, TRUE));
+  if (empty($message->subject) && !empty($trimed_body)) {
+    $message->subject = $trimed_body;
   }
   // Only parse the user string for a new thread.
-  if (!isset($message['thread_id'])) {
-    list($message['recipients'], $invalid) = _privatemsg_parse_userstring($message['recipient']);
+  if (!isset($message->thread_id)) {
+    list($message->recipients, $invalid) = _privatemsg_parse_userstring($message->recipient);
   }
   else {
     // Load participants.
-    $message['recipients'] = _privatemsg_load_thread_participants($message['thread_id']);
+    $message->recipients = _privatemsg_load_thread_participants($message->thread_id);
     // Remove author.
-    if (isset($message['recipients'][$message['author']->uid]) && count($message['recipients']) > 1) {
-      unset($message['recipients'][$message['author']->uid]);
+    if (isset($message->recipients[$message->author->uid]) && count($message->recipients) > 1) {
+      unset($message->recipients[$message->author->uid]);
     }
   }
 
@@ -441,7 +448,7 @@ function privatemsg_new_submit($form, &$
   $status = _privatemsg_send($form_state['validate_built_message']);
   // Load usernames to which the message was sent to.
   $recipient_names = array();
-  foreach ($form_state['validate_built_message']['recipients'] as $recipient) {
+  foreach ($form_state['validate_built_message']->recipients as $recipient) {
     $recipient_names[] = theme('username', array('account' => $recipient));
   }
   if ($status !== FALSE )  {
@@ -470,9 +477,9 @@ function privatemsg_undo_action() {
       }
       call_user_func_array($undo['function'], $undo['args']);
     }
-    // Return back to the site defined by the destination GET param.
-    drupal_goto();
   }
+  // Return back to the site defined by the destination GET param.
+  drupal_goto();
 }
 
 
@@ -560,7 +567,7 @@ function privatemsg_view($thread) {
   $content['messages']['#weight'] = 0;
   foreach ($thread['messages'] as $pmid => $message) {
     // Set message as read and theme it.
-    if (!empty($message['is_new'])) {
+    if (!empty($message->is_new)) {
       privatemsg_message_change_status($pmid, PRIVATEMSG_READ, $thread['user']);
     }
     $content['messages'][$pmid] = array(
Index: privatemsg.test
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/privatemsg/privatemsg.test,v
retrieving revision 1.2.2.1.2.22
diff -u -p -r1.2.2.1.2.22 privatemsg.test
--- privatemsg.test	17 Jun 2010 20:57:15 -0000	1.2.2.1.2.22
+++ privatemsg.test	19 Jun 2010 07:55:49 -0000
@@ -57,14 +57,14 @@ class PrivatemsgTestCase extends DrupalW
     $this->drupalGet('messages');
     $this->assertResponse(200, t('HTTP Response 200: Access to mailbox was authorized to user with "<em>read privatemsg</em>" permission'));
 
-    $this->drupalGet('messages/view/' . $response['message']['thread_id']);
+    $this->drupalGet('messages/view/' . $response['message']->thread_id);
     $this->assertResponse(403, t('HTTP Response 403: Access to thread is blocked for non-recipients.'));
 
     $this->drupalLogin($recipient);
-    $this->drupalGet('messages/view/' . $response['message']['thread_id']);
+    $this->drupalGet('messages/view/' . $response['message']->thread_id);
     $this->assertText($subject, t('Access to thread for recipient allowed.'));
 
-    $this->drupalGet('messages/view/' . $response['message']['thread_id'] + 1);
+    $this->drupalGet('messages/view/' . $response['message']->thread_id + 1);
     $this->assertResponse(404, t('Non-existing thread lead to HTTP Response 404.'));
 
   }
@@ -102,7 +102,7 @@ class PrivatemsgTestCase extends DrupalW
     privatemsg_new_thread(array($recipient), $subject_single, $bodies[23], array('author' => $author));
     $thread = privatemsg_new_thread(array($recipient), $subject, $bodies[0], array('author' => $author));
     for ($i = 1; $i < 23; $i++) {
-      privatemsg_reply($thread['message']['thread_id'], $bodies[$i], array('author' => $author));
+      privatemsg_reply($thread['message']->thread_id, $bodies[$i], array('author' => $author));
     }
 
     $this->drupalLogin($recipient);
@@ -374,7 +374,7 @@ class PrivatemsgTestCase extends DrupalW
 
     // Create a message between the users that we can use to test
     $return = privatemsg_new_thread(array($disableduser), $this->randomName(20), $this->randomName(100), array('author' => $enableduser));
-    $mid = $return['message']['thread_id'];
+    $mid = $return['message']->thread_id;
 
     $this->drupalLogin($disableduser);
     // Now disable $disabledUser.
@@ -386,8 +386,8 @@ class PrivatemsgTestCase extends DrupalW
     $this->drupalGet('messages');
     $this->assertResponse(200, t('HTTP Response 200: Access to reading messages page is allowed.'));
 
-    // Verify that $disableduser can read messages but there is not reply form.
-    $this->drupalGet('messages/'. $return['message']['thread_id']);
+    // Verify that $disableduser can read messages but there is not reply form
+    $this->drupalGet('messages/'. $return['message']->thread_id);
     $this->assertResponse(200, t('HTTP Response 200: Access to message thread page is allowed.'));
     $this->assertNoText(t('Reply to thread'), 'No reply form shown.');
 
@@ -397,9 +397,10 @@ class PrivatemsgTestCase extends DrupalW
 
     // Use a newly loaded user object to test the API calls.
     $disableduser_loaded = user_load($disableduser->uid, TRUE);
+  
+    // Check that $disableduser cannot submit a reply
+    $result = privatemsg_reply($return['message']->thread_id, $this->randomName(100), array('author' => $disableduser_loaded));
 
-    // Check that $disableduser cannot submit a reply.
-    $result = privatemsg_reply($return['message']['thread_id'], $this->randomName(100), array('author' => $disableduser_loaded));
     $this->assertFalse($result['success'], 'Message reply was not sent.');
 
     // Log in as $enableduser and try to send to $disabled user.
@@ -580,23 +581,23 @@ class PrivatemsgTestCase extends DrupalW
 
     // Create message and response.
     $return = privatemsg_new_thread(array($recipient, $recipient2), $subject, $body1, array('author' => $author));
-    privatemsg_reply($return['message']['thread_id'], $body2, array('author' => $recipient));
+    privatemsg_reply($return['message']->thread_id, $body2, array('author' => $recipient));
 
     // Check with user without delete permission.
     $this->drupalLogin($recipient2);
-    $this->drupalGet('messages/view/' . $return['message']['thread_id']);
+    $this->drupalGet('messages/view/' . $return['message']->thread_id);
     $this->assertText($subject, 'Subject is displayed');
     $this->assertText($body1, 'First message is displayed');
     $this->assertText($body2, 'Second message is displayed');
     $this->assertNoText(t('Delete message'), 'Delete message is link is not displayed for user without permission');
 
     // Check if access for that user is denied.
-    $this->drupalGet('messages/delete/' . $return['message']['thread_id'] . '/' . $return['message']['mid']);
+    $this->drupalGet('messages/delete/' . $return['message']->thread_id . '/' . $return['message']->mid);
     $this->assertText(t('Access denied'));
 
     // Check with user with delete access.
     $this->drupalLogin($recipient);
-    $this->drupalGet('messages/view/' . $return['message']['thread_id']);
+    $this->drupalGet('messages/view/' . $return['message']->thread_id);
     $this->assertText(t('Delete message'), 'Delete message is link is displayed for user without permission');
 
     // Click delete link of the second message and cancel.
@@ -628,27 +629,27 @@ class PrivatemsgTestCase extends DrupalW
 
     // Test if the message has not been deleted for other users.
     $this->drupalLogin($recipient2);
-    $this->drupalGet('messages/view/' . $return['message']['thread_id']);
+    $this->drupalGet('messages/view/' . $return['message']->thread_id);
     $this->assertText($body1, 'First message is still displayed');
     $this->assertText($body2,'First message is still displayed');
 
     // Test delete all checkbox.
     $this->drupalLogin($admin);
-    $this->drupalGet('messages/view/' . $return['message']['thread_id']);
+    $this->drupalGet('messages/view/' . $return['message']->thread_id);
     $this->clickLink(t('Delete message'), 1);
     $this->drupalPost(NULL, array('delete_options' => TRUE), t('Delete'));
     $this->assertText(t('Message has been deleted for all users.'), 'Message deleted has been deleted');
 
     // Test if the message has been deleted for all users.
     $this->drupalLogin($recipient2);
-    $this->drupalGet('messages/view/' . $return['message']['thread_id']);
+    $this->drupalGet('messages/view/' . $return['message']->thread_id);
     $this->assertText($body1, 'First message is still displayed');
     $this->assertNoText($body2, 'Second message has been deleted for all users');
 
     // Check that messages of canceled users (user_cancel_delete) are deleted too.
     $edit = array('body[value]' => $this->randomName(100));
     $this->drupalPost(NULL, $edit, t('Send message'));
-    $this->drupalGet('messages/view/' . $return['message']['thread_id']);
+    $this->drupalGet('messages/view/' . $return['message']->thread_id);
     $this->assertText($edit['body[value]'], t('New reply is displayed'));
 
     // Reload user object, don't use the cache.
@@ -670,7 +671,7 @@ class PrivatemsgTestCase extends DrupalW
     $this->loggedInUser = NULL;
 
     $this->drupalLogin($admin);
-    $this->drupalGet('messages/view/' . $return['message']['thread_id']);
+    $this->drupalGet('messages/view/' . $return['message']->thread_id);
     $this->assertText($body1, 'First message is still displayed');
     $this->assertNoText($edit['body[value]'], t('Reply of deleted user is not displayed anymore'));
 
@@ -703,21 +704,21 @@ class PrivatemsgTestCase extends DrupalW
   }
 
  function checkThreadDelete($message) {
-    $this->assertText($message['subject'], t('Message is displayed.'));
+    $this->assertText($message->subject, t('Message is displayed.'));
 
     $delete = array(
-      'list[' . $message['thread_id'] . ']' => 1,
+      'list[' . $message->thread_id . ']' => 1,
     );
     $this->drupalPost(NULL, $delete, t('Delete'));
     $this->assertText(t('Deleted @count thread.', array('@count' => 1)), t('Delete message displayed.'));
-    $this->assertNoText($message['subject'], t('Message is not displayed anymore.'));
+    $this->assertNoText($message->subject, t('Message is not displayed anymore.'));
     $this->assertText(t('No messages available.'), t('No messages available anymore.'));
 
     // Revert delete action.
     $this->clickLink(t('undone'));
 
     $this->assertText(t('Restored @count thread.', array('@count' => 1)), t('Restore message displayed'));
-    $this->assertText($message['subject'], t('Message is displayed again.'));
+    $this->assertText($message->subject, t('Message is displayed again.'));
     $this->assertNoText(t('No messages available.'), t('Messages are available.'));
   }
 
@@ -728,23 +729,78 @@ class PrivatemsgTestCase extends DrupalW
     //we dont really need to do this. i'm adding it just to keep it in front of my eyes so i can memorize it.
     parent::tearDown();
   }
-
 }
 
+/**
+ * Tests for fields integration.
+ */
+class PrivatemsgFieldsTestCase extends DrupalWebTestCase {
+  /**
+   * Implementation of getInfo().
+   */
+  public static function getInfo() {
+    return array
+    (
+      'name' => t('Privatemsg fields.'),
+      'description' => t('Tests integration with fields.'),
+      'group' => t('Privatemsg'),
+    );
+  }
 
+  /**
+   * Implementation of setUp().
+   */
+  function setUp() {
+    parent::setUp('privatemsg');
+  }
 
+  function testSingleField() {
+    $admin = $this->drupalCreateUser(array('administer privatemsg settings', 'write privatemsg', 'read privatemsg'));
+    $user = $this->drupalCreateUser(array('write privatemsg', 'read privatemsg'));
 
+    $this->drupalLogin($admin);
 
+    // Create a new field.
+    $edit = array(
+      '_add_new_field[label]' => $label = $this->randomName(),
+      '_add_new_field[field_name]' => $name = strtolower($this->randomName()),
+      '_add_new_field[type]' => 'text',
+      '_add_new_field[widget_type]' => 'text_textfield',
+    );
+    $this->drupalPost('admin/config/messaging/privatemsg/fields', $edit, t('Save'));
+    $this->drupalPost(NULL, array(), t('Save field settings'));
+    $this->drupalPost(NULL, array(), t('Save settings'));
 
+    // Send message.
+    $message = array(
+      'recipient' => $user->name,
+      'subject' => $this->randomName(),
+      'body[value]'    => $this->randomName(50),
+      'field_' . $name . '[und][0][value]' => $this->randomName(50),
+    );
+    $this->drupalPost('messages/new', $message, t('Send message'));
 
+    // Check message.
+    $this->drupalLogin($user);
+    $this->drupalGet('messages');
+    $this->clickLink($message['subject']);
 
+    $this->assertText($message['body[value]'], t('Message body displayed.'));
+    $this->assertText($message['field_' . $name . '[und][0][value]'], t('Content of new field is displayed.'));
 
+    // Respond.
+    $response = array(
+      'body[value]' => $this->randomName(50),
+      'field_' . $name . '[und][0][value]' => $this->randomName(50),
+    );
+    $this->drupalPost(NULL, $response, t('Send message'));
 
+    // Check response.
+    $this->drupalLogin($admin);
+    $this->drupalGet('messages');
+    $this->clickLink($message['subject']);
 
-
-
-
-
-
-
-
+    $this->assertText($response['body[value]'], t('Message body displayed.'));
+    $this->assertText($response['field_' . $name . '[und][0][value]'], t('Content of new field is displayed.'));
+  }
+}
Index: pm_block_user/pm_block_user.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/privatemsg/pm_block_user/pm_block_user.module,v
retrieving revision 1.1.2.8.2.12
diff -u -p -r1.1.2.8.2.12 pm_block_user.module
--- pm_block_user/pm_block_user.module	19 Apr 2010 17:09:25 -0000	1.1.2.8.2.12
+++ pm_block_user/pm_block_user.module	19 Jun 2010 07:55:49 -0000
@@ -266,18 +266,18 @@ function pm_block_user_privatemsg_messag
   global $user;
 
   // @todo: weird, figure out why it is below #message.
-  $author = $vars['message']['author'];
+  $author = $vars['message']->author;
   if (_pm_block_user_rule_exists($author, $user, PM_BLOCK_USER_DISALLOW_BLOCKING)) {
     return;
   }
-  if (!isset($vars['message']['thread_id'])) {
+  if (!isset($vars['message']->thread_id)) {
     // No thread id, this is probably only a preview
     return;
   }
-  $thread_id = $vars['message']['thread_id'];
+  $thread_id = $vars['message']->thread_id;
 
   if ($user->uid <> $author->uid) {
-    if ($vars['message']['is_blocked']) {
+    if ($vars['message']->is_blocked) {
       $vars['message_actions']['unblock_author'] = array('title' => t('Unblock author'), 'href' => 'messages/block/'. $author->uid, 'query' => array('destination' => 'messages/view/' . $thread_id));
     }
     else {
Index: pm_block_user/pm_block_user.test
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/privatemsg/pm_block_user/pm_block_user.test,v
retrieving revision 1.1.2.6
diff -u -p -r1.1.2.6 pm_block_user.test
--- pm_block_user/pm_block_user.test	6 Jun 2010 15:15:43 -0000	1.1.2.6
+++ pm_block_user/pm_block_user.test	19 Jun 2010 07:55:49 -0000
@@ -29,8 +29,8 @@ class PrivatemsgBlockUserCase extends Dr
 
     // Set up a simple conversation.
     $return = privatemsg_new_thread(array($user2, $user3), $subject = $this->randomName(20), $this->randomString(50), array('author' => $user1));
-    privatemsg_reply($return['message']['thread_id'], $this->randomString(50), array('author' => $user2));
-    privatemsg_reply($return['message']['thread_id'], $this->randomString(50), array('author' => $user3));
+    privatemsg_reply($return['message']->thread_id, $this->randomString(50), array('author' => $user2));
+    privatemsg_reply($return['message']->thread_id, $this->randomString(50), array('author' => $user3));
 
     $this->drupalLogin($user1);
     $this->drupalGet('messages');
Index: pm_email_notify/pm_email_notify.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/privatemsg/pm_email_notify/pm_email_notify.module,v
retrieving revision 1.1.2.3.2.11
diff -u -p -r1.1.2.3.2.11 pm_email_notify.module
--- pm_email_notify/pm_email_notify.module	28 Apr 2010 22:00:32 -0000	1.1.2.3.2.11
+++ pm_email_notify/pm_email_notify.module	19 Jun 2010 07:55:49 -0000
@@ -49,7 +49,7 @@ function _pm_email_notify_is_enabled($ui
  * Implementation of hook_privatemsg_message_insert().
  */
 function pm_email_notify_privatemsg_message_insert($message) {
-  foreach ($message['recipients'] as $recipient) {
+  foreach ($message->recipients as $recipient) {
     // check if recipient enabled email notifications
     if (_pm_email_notify_is_enabled($recipient->uid)) {
       // send them a new pm notification email if they did
@@ -87,12 +87,12 @@ function pm_email_notify_mail($key, &$me
 function _pm_email_notify_token($recipient, $message) {
 
   $tokens = array(
-    '!author' => $message['author']->name,
-    '!pm_subject' => drupal_html_to_text(check_plain($message['subject'])),
-    '!pm_body' => drupal_html_to_text(check_markup($message['body'], $message['format'])),
-    '!thread' => $message['thread_id'],
+    '!author' => $message->author->name,
+    '!thread' => $message->thread_id,
+    '!pm_subject' => drupal_html_to_text(check_plain($message->subject)),
+    '!pm_body' => drupal_html_to_text(check_markup($message->body, $message->format)),
     '!user_uid' => $recipient->uid,
-    '!message' => url('messages/view/' . $message['thread_id'], array('absolute' => TRUE)),
+    '!message' => url('messages/view/' . $message->thread_id, array('absolute' => TRUE)),
     '!settings' => url('user/' . $recipient->uid . '/edit', array('absolute' => TRUE)),
   );
 
Index: privatemsg_filter/privatemsg_filter.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/privatemsg/privatemsg_filter/privatemsg_filter.module,v
retrieving revision 1.1.2.17.2.17
diff -u -p -r1.1.2.17.2.17 privatemsg_filter.module
--- privatemsg_filter/privatemsg_filter.module	5 May 2010 22:15:26 -0000	1.1.2.17.2.17
+++ privatemsg_filter/privatemsg_filter.module	19 Jun 2010 07:55:49 -0000
@@ -848,7 +848,7 @@ function privatemsg_filter_user_cancel($
  * Implements hook_privatemsg_message_insert().
  */
 function privatemsg_filter_privatemsg_message_insert($message) {
-  foreach ($message['recipients'] as $recipient) {
-    privatemsg_filter_add_tags(array($message['thread_id']), variable_get('privatemsg_filter_inbox_tag', ''), $recipient);
+  foreach ($message->recipients as $recipient) {
+    privatemsg_filter_add_tags(array($message->thread_id), variable_get('privatemsg_filter_inbox_tag', ''), $recipient);
   }
 }
Index: privatemsg_filter/privatemsg_filter.test
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/privatemsg/privatemsg_filter/privatemsg_filter.test,v
retrieving revision 1.1.4.11
diff -u -p -r1.1.4.11 privatemsg_filter.test
--- privatemsg_filter/privatemsg_filter.test	5 May 2010 22:15:26 -0000	1.1.4.11
+++ privatemsg_filter/privatemsg_filter.test	19 Jun 2010 07:55:50 -0000
@@ -138,7 +138,7 @@ class PrivatemsgTagsTestCase extends Dru
 
     // Create a new thread through the api.
     $response = privatemsg_new_thread(array($webuser), $this->randomName(10), $this->randomName(20), array('author' => $webuser));
-    $thread_id = $response['message']['thread_id'];
+    $thread_id = $response['message']->thread_id;
 
     $edit = array(
       'tags' => 'Awesome bananas, Banana',
@@ -151,7 +151,7 @@ class PrivatemsgTagsTestCase extends Dru
 
     // Create a another thread through the api.
     $response = privatemsg_new_thread(array($webuser), $this->randomName(10), $this->randomName(20), array('author' => $webuser));
-    $thread_id = $response['message']['thread_id'];
+    $thread_id = $response['message']->thread_id;
 
     $edit = array(
       'tags' => 'Banana, Apple',
@@ -266,7 +266,7 @@ class PrivatemsgTagsTestCase extends Dru
 
     // Create a new thread through the api.
     $response = privatemsg_new_thread(array($webuser), $subject1 = $this->randomName(10), $this->randomName(20), array('author' => $webuser));
-    $thread_id = $response['message']['thread_id'];
+    $thread_id = $response['message']->thread_id;
 
     $edit = array(
       'tags' => 'Awesome bananas, Banana',
@@ -278,7 +278,7 @@ class PrivatemsgTagsTestCase extends Dru
 
     // Create another thread.
     $response = privatemsg_new_thread(array($webuser), $subject2 = $this->randomName(10), $this->randomName(20), array('author' => $webuser));
-    $thread_id2 = $response['message']['thread_id'];
+    $thread_id2 = $response['message']->thread_id;
 
     $this->drupalGet('messages');
     $rows = $this->xpath('//tbody/tr');
Index: tests/privatemsgapi.test
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/privatemsg/tests/privatemsgapi.test,v
retrieving revision 1.1.2.1.2.10
diff -u -p -r1.1.2.1.2.10 privatemsgapi.test
--- tests/privatemsgapi.test	4 Jun 2010 06:31:25 -0000	1.1.2.1.2.10
+++ tests/privatemsgapi.test	19 Jun 2010 07:55:50 -0000
@@ -45,7 +45,7 @@ class PrivatemsgAPITestCase extends Drup
 
     $message = $this->getMessageFromSubject('normal message');
     $this->assertFalse(empty($message), 'Message was saved in database');
-    $this->assertEqual($message['author'], $author->uid, 'Message was sent by author');
+    $this->assertEqual($message->author, $author->uid, 'Message was sent by author');
 
     $resultok2 = privatemsg_new_thread(array($recipient1, $recipient2, $recipient3), 'empty body', '', array('author' => $author));
     $this->assertTrue($resultok2['success'], 'API allowed to send message without body');
@@ -81,7 +81,7 @@ class PrivatemsgAPITestCase extends Drup
   }
 
   function getMessageFromSubject($subject) {
-    return db_query("SELECT * FROM {pm_message} WHERE subject = :subject", array(':subject' => $subject))->fetchAssoc();
+    return db_query("SELECT * FROM {pm_message} WHERE subject = :subject", array(':subject' => $subject))->fetchObject();
   }
 
   function testPrivatemsgApiReply() {
@@ -98,17 +98,17 @@ class PrivatemsgAPITestCase extends Drup
 
     $thread_row = $this->getMessageFromSubject('test reply');
 
-    $resultok = privatemsg_reply($thread_row['mid'], 'Test Body', array('author' => $author));
+    $resultok = privatemsg_reply($thread_row->mid, 'Test Body', array('author' => $author));
     $this->assertTrue($resultok['success'], 'Reply could be sent successfully');
 
-    $resultok = privatemsg_reply($thread_row['mid'], 'Test Body', array('author' => $recipient1));
+    $resultok = privatemsg_reply($thread_row->mid, 'Test Body', array('author' => $recipient1));
     $this->assertTrue($resultok['success'], 'Reply could be sent successfully');
 
-    $resultf1 = privatemsg_reply($thread_row['mid'], '', array('author' => $recipient2));
+    $resultf1 = privatemsg_reply($thread_row->mid, '', array('author' => $recipient2));
     $this->assertFalse($resultf1['success'], 'API denied to send message without body.');
     $this->assertEqual($resultf1['messages']['error'][0], t('Disallowed to send reply without a message.'), 'Correct error returned when replying with an empty body.');
 
-    $resultf2 = privatemsg_reply($thread_row['mid'], 'Test Body', array('author' => $recipient3));
+    $resultf2 = privatemsg_reply($thread_row->mid, 'Test Body', array('author' => $recipient3));
     $errormessage = 'User '. $recipient3->name .' is not allowed to write messages';
     $this->assertEqual($errormessage, $resultf2['messages']['error'][0], 'API denied to send message from user without permission');
 
