Hi,

I'm using the latest Private Messages 7.x and I'm trying to make my private messages threads and thread-list to look like Facebook... with user avatars. Kinda like this:

(I have done it in 5.x and 6.x), but in 7.x the function names (like privatemsg_list_field__participants) are no longer recognized. Below is the code that I put in my template.php for 6.x and it works like a charm (although slows down the pageload time). Would you please be so kind as to review the code below for 6.x and suggest what would be the optimal solution for 7.x

/**
* Theme the participants field.
*
* @see theme_privatemsg_list_field()
*/
function THEME-NAME_privatemsg_list_field__participants($thread) {
  $participants = _privatemsg_generate_user_array($thread['participants'], -4);
  
  // Remove ourselves from the list of participants
  global $user;
  foreach($participants as $key => $participant) {
      if ($participant->uid == $user->uid) {
          unset($participants[$key]);
      }
  }
  
  $field = array();
  $field['data'] = _privatemsg_format_participants($participants, 3, TRUE);
  $field['class'] = 'privatemsg-list-participants';
// 	return $field;
//	  return theme('user_picture', $participant); 
    // select last author uid except the current user.
  $uid = db_query('SELECT pm.author FROM {pm_message} pm INNER JOIN {pm_index} pmi ON pmi.mid = pm.mid AND pmi.thread_id = %d WHERE pm.author <> %d ORDER BY pm.timestamp DESC LIMIT 1', $thread['thread_id'], $user->uid);
  // Only display something if we have an uid.
  $account = user_load($uid);
  if ($uid) {
    return theme('user_picture', $account) . theme('username', $account);
  }
}

/**
* Define the participants column.
*
* @see theme_privatemsg_list_header()
*/
function THEME-NAME_privatemsg_list_header__participants() {
  return array(
    'data'    => t('From / To'),    //<!----- NAME IT HERE
    'key'     => 'participants',
    'class'   => 'privatemsg-header-participants',
    '#weight' => -50,        //<!------ MOVE COLUMN TO LEFT
  );
}

/* expriment to display From as avatars */
function THEME-NAME_privatemsg_username($user) {
return theme('user_picture', $user);  
return theme('username', $user);
}

Please help, as I can see that many people are looking for a solution for this.
Many thanks in advance!

Comments

mototribe’s picture

great idea! I would love to see that too

drupalina’s picture

My latest code looks like this:

<?php
/**
* Theme the participants field.
*
* @see theme_privatemsg_list_field()
*/
function simpler_privatemsg_list_field__participants($variables) {
  $thread = $variables['thread'];
  $participants = _privatemsg_generate_user_array($thread['participants'], -4);
  
  // Remove ourselves from the list of participants
  global $user;
  foreach($participants as $key => $participant) {
      if ($participant->uid == $user->uid) {
          unset($participants[$key]);
      }
  }
  
  $field = array();
  $field['data'] = _privatemsg_format_participants($participants, 3, TRUE);
  $field['class'] = 'privatemsg-list-participants';
// 	return $field;
//	  return theme('user_picture', $participant); 
    // select last author uid except the current user.
  $uid = db_query('SELECT pm.author FROM {pm_message} pm INNER JOIN {pm_index} pmi ON pmi.mid = pm.mid AND pmi.thread_id = %d WHERE pm.author <> %d ORDER BY pm.timestamp DESC LIMIT 1', $thread['thread_id'], $user->uid);
  // Only display something if we have an uid.
  $account = user_load($uid);
  if ($uid) {
    return theme('user_picture', $account) . theme('username', $account);
  }
}
?>

but the problem is still in that line

  $uid = db_query('SELECT pm.author FROM {pm_message} pm INNER JOIN {pm_index} pmi ON pmi.mid = pm.mid AND pmi.thread_id = %d WHERE pm.author <> %d ORDER BY pm.timestamp DESC LIMIT 1', $thread['thread_id'], $user->uid);

which gives errors !!!

Can you help to make this work?

Everything works except for the line at
$uid = db_query('SELECT pm.author FROM {pm_message} pm INNER JOIN {pm_index} pmi ON pmi.mid = pm.mid AND pmi.thread_id = %d WHERE pm.author <> %d ORDER BY pm.timestamp DESC LIMIT 1', $thread['thread_id'], $user->uid);
and gives me a serious error

Recoverable fatal error: Argument 2 passed to db_query() must be an array, string given, called in C:\wamp2\www\site-name\sites\all\themes\simpler\template.php on line 52 and defined in db_query() (line 2313 of C:\wamp2\www\site-name\includes\database\database.inc).

drupalina’s picture

okey got it working with this code:

<?php 
/**
* Theme the participants field.
*
* @see theme_privatemsg_list_field()
*/
function REPLACEYOURTHEMENAME_privatemsg_list_field__participants($variables) {
  $thread = $variables['thread'];
  $participants = _privatemsg_generate_user_array($thread['participants'], -4);
  
  // Remove ourselves from the list of participants
  global $user;
  foreach($participants as $key => $participant) {
      if ($participant->uid == $user->uid) {
          unset($participants[$key]);
      }
  }
  
  $field = array();
  $field['data'] = _privatemsg_format_participants($participants, 3, TRUE);
  $field['class'] = 'privatemsg-list-participants';
//     return $field;
    // select last author uid except the current user.
$uid = db_query('SELECT pm.author FROM {pm_message} pm INNER JOIN {pm_index} pmi ON pmi.mid = pm.mid AND pmi.thread_id = :thread WHERE pm.author <> :author ORDER BY pm.timestamp DESC LIMIT 1', array(':thread' => $thread['thread_id'], 'author' => $user->uid))->fetchField();
  // Only display something if we have an uid.
  $account = user_load($uid);
  if ($uid) {
    return theme('user_picture', array('account' =>$account)) . theme('username', array('account' =>$account)) ;
  }
}
?>

The pictures from the last participant who has replied are appearing.
Although if we have just sent a new message in a new thread, the "To" recipient's picture and username is not appearing... but I'll have to work on that.

drupalina’s picture

Actually me rejoy was premature...

If Mark (sender) sends a message to Tom (recepient) and Tom doesn't reply, then Mark will see no user_picture or username of the Recepient (Tom). In such case, Mark should see Recepient's (Tom's) user_picture and username even if Tom has not replied yet.

Othervise it gives out a very ugly error message:

  • Warning: array_flip() [function.array-flip]: Can only flip STRING and INTEGER values! in DrupalDefaultEntityController->load() (line 178 of C:\wamp2\www\testsite7\includes\entity.inc).
  • Warning: array_flip() [function.array-flip]: Can only flip STRING and INTEGER values! in DrupalDefaultEntityController->cacheGet() (line 354 of C:\wamp2\www\testsite7\includes\entity.inc).
  • Notice: Undefined index: participants in theme_tableselect() (line 3212 of C:\wamp2\www\testsite7\includes\form.inc).

Could the above logic be incorporated into this function when determining the uid ?
If the resulting uid is that of Current user, then display the uid of the Recepient.

tanmayk’s picture

I was also looking for the same but for D7. Here is how I got privatemsg list themed.

function PHPTEMPLATE_privatemsg_list_field__subject($variables) {
  $thread = $variables['thread'];
  $field = array();
  $options = array();
  $is_new = '';
  if (!empty($thread['is_new'])) {
    $is_new = theme('mark', array('type' => MARK_NEW));
    $options['fragment'] = 'new';
  }
  $options['attributes']['class'] = array('privatemsg-list-message-link');
  $subject = $thread['subject'];
  if ($thread['has_tokens']) {
    $message = privatemsg_message_load($thread['thread_id']);
    $subject = privatemsg_token_replace($subject, array('privatemsg_message' => $message), array('sanitize' => TRUE, 'privatemsg-show-span' => FALSE));
  }
  if (!isset($message)) {
    $message = privatemsg_message_load($thread['thread_id']);
  }

  // We will add user picture here.
  $field['data'] = theme('user_picture', array('account' => $message->author));
  // Then we will append the subject.
  $field['data'] .= l($subject, 'messages/view/' . $thread['thread_id'], $options) . $is_new;

  $field['class'][] = 'privatemsg-list-subject';
  return $field;
}

It will display the sender picture before the subject. Now we just need to do some CSS.

.privatemsg-list tr td.privatemsg-list-subject div.user-picture img {
  float: left;
  margin-right: 1em;
}

That is how I did it. Hope that will help someone for D7.

Regards,
Tanmay

Lordkien’s picture

Hi,

My need is to add new columns, modify/remove existing ones and rearrange the columns.

I've read the document but really don't understand much about this module API. The comments in the module told me to hook to privatemsg_list form and add new function to list_header and list_field. But still, I couldn't make it. Can anyone provide me with examples of how to do the aboves (beside modifying existing columns)?

function garland_form_privatemsg_list_alter(&$form, &$form_state) {
	$form['#header']['field_name'] = array(
		'data' => t('new field'),
		'field' => 'new_field',
	);
	
	$form['#data']['thread_id'] = array();
	
	$form['#rows']['thread_id'] = array();
} 

function garland_privatemsg_list_header__new_field() {
	return array(
		'data'    => t('new_field'),
		'field'   => 'new_field',
		'class'   => array('privatemsg-header-new_field'),
		'#weight' => -40,
	);
}

function garland_theme_privatemsg_list_field__new_field() {
	$field['data'] = "1234";
	$field['class'][] = 'privatemsg-list-new_field';
	return $field;
}
ptmkenny’s picture

@Lordkien This thread is about adding user pictures to private message list displays. If you want to change columns, you should open a different issue.

superdorx’s picture

Thanks!

darksleuth’s picture

Thank you - this is great.

Currently going through Drupal 7 tutorials and starting a Zen subtheme - this is the first piece of code I have put into a template.php file - and it works.

Cheers.

Bill Choy’s picture

Thanks ... worked great, except your missing the class on the <td class="privatemsg-list-participants">

  $field = array();
  $field['data'] = _privatemsg_format_participants($participants, 3, TRUE);
  $field['class'] = array('privatemsg-list-participants');
//  return $field;
  // select last author uid except the current user.
  $uid = db_query('SELECT pm.author FROM {pm_message} pm INNER JOIN {pm_index} pmi ON pmi.mid = pm.mid AND pmi.thread_id = :thread WHERE pm.author <> :author ORDER BY pm.timestamp DESC LIMIT 1',
            array(':thread' => $thread['thread_id'], 'author' => $user->uid))->fetchField();

  // Only display something if we have an uid.
  $account = user_load($uid);
  if ($uid && $account) {
    $field['data'] = theme('user_picture', array('account' => $account)) . theme('username', array('account' => $account));
  }
  return $field;
ptmkenny’s picture

Marked http://drupal.org/node/1392448 as a duplicate

Cromian’s picture

Your image showed a delete link in the inbox view. How did you build it?

ptmkenny’s picture

@Cromian: There is a delete link shown by default in the inbox if the user has permission to delete private messages. If you have further questions, you should open a new issue, since a delete link really has nothing to do with the topic of this issue (displaying user pictures).

ptmkenny’s picture

Status: Active » Fixed
momo77’s picture

Rather than the user picture I'd like a picture field from the user profile to be displayed in the list of threads. How would I do that?

In this line:

$field['data'] = theme('user_picture', array('account' => $message->author));

I tried to replace 'user_picture' by my fields machine readable name 'field_image' but that didn't work.

ptmkenny’s picture

@momo77 In that case, you need to pull in the image via Field API. Something like:

$account->field_my_field['und'][0]['value']

But this depends on whether your field allows multiple values (and how you want to handle the case of multiple values if it does). You'll also need to set which image style you want to use to display the image.

One alternative that could be easier is to use your field as the user picture:
http://drupal.stackexchange.com/questions/27005/how-can-i-display-a-pict...

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

prezaeis’s picture

Hi guys, sorry to open this again.
I been reading through this but i cant figure something out, i have disabled the User Avatar on my site and instead added an image field to the user profile (D7) which i want displayed in private messages, whats the best way to do this? i tried the method mentioned in #16 with no luck :(

Any help would be appreciated, im willing to pay

Thank you

ptmkenny’s picture

@prezaeis You have to use the name of your field. field_my_field should be the machine name of your field.

prezaeis’s picture

I did change the name to the one i have setup,
Where does that line need to go? just to make sure im putting it in the correct place

RaulMuroc’s picture

What about have also pictures in the thread of a messages, I mean:

INBOX => /messages
MESSAGE THREAD => /messages/view/message_id

Would be nice also in the 'conversation' itself.

RaulMuroc’s picture

Solution for '/messages', not for '/messages/view/message_id'

Profile2 fields integration:

In your template.php override same function as follows:

/**
* Theme the participants field.
*
* @see theme_privatemsg_list_field()
*/
function REPLACEYOURTHEMENAME_privatemsg_list_field__subject($variables) {
  $thread = $variables['thread'];
    $field = array();
    $options = array();
    $is_new = '';
    if (!empty($thread['is_new'])) {
      $is_new = theme('mark', array('type' => MARK_NEW));
      $options['fragment'] = 'new';
    }
    $options['attributes']['class'] = array('privatemsg-list-message-link');
    $subject = $thread['subject'];

    if ($thread['has_tokens']) {
      $message = privatemsg_message_load($thread['thread_id']);
      $subject = privatemsg_token_replace($subject, array('privatemsg_message' => $message), array('sanitize' => TRUE, 'privatemsg-show-span' => FALSE));
    }
    if (!isset($message)) {
      $message = privatemsg_message_load($thread['thread_id']);
    }
    
   //** We will add user picture here */
   
   // Retrieve current recipient/user id
   $aux = explode('_', $thread['participants']);
   $user_id = $aux['1'];
   unset($aux);
   
   // Retrieve each value needed to theme the image: rute to the image, height, width and alternate text if no image found
   $profile_values = profile2_load_by_user($user_id);
   $picture_name = $profile_values['main']->your_field['und'][0]['filename'];
   $picture_uri = $profile_values['main']->your_field['und'][0]['uri'];
   $exploded_uri = explode('//', $picture_uri);
   $route_to_pic = $exploded_uri['1'];
   $picture_path = 'your/path/to/public/directoy/with/pictures/' . $route_to_pic;
   $picture_width = 80;
   $picture_height = 80;
   $picture_alt_text = $profile_values['main']->your_field['und'][0]['alt'];
   
   // Append the picture to html to be rendered
   $field['data'] = theme_image(array('path' => $picture_path, 'width' => $picture_width, 'height' => $picture_height, 'alt' => $picture_alt_text));
   
    // Then we will append the subject.
    $field['data'] .= l($subject, 'messages/view/' . $thread['thread_id'], $options) . $is_new;
    $field['class'][] = 'privatemsg-list-subject';
    return $field;
}
jeffmatt’s picture

Hello guys! I need help.

My motherlanguage is german and i have some problems to understand this post.

I´ve tried to put a user pic onto the messages/list and messages/sent page

I read every thread but still have no clue how i can make it work.

I tried to put the codes into the privatemsg.theme.inc : (???)

#5
#22

I'm not really used to PHP and normaly don't touch the template files.

so I'm a little confused about the lines;

function REPLACEYOURTHEMENAME

or

PHPTEMPLATE_privatemsg_list_field

Do I have to put the code in the privatemsg.theme.inc code or somewhere else?

Original code privatemsg.theme.inc :

<?php

/**
 * @file
 * Theme functions for privatemsg.
 */

/**
 * @defgroup theming Theming documentation
 *
 * It is possible to theme every aspect of privatemsg with theme functions.
 *
 * For the thread list, so called theme patterns are used to allow flexible
 * theming of the table and its columns (including columns added by other
 * modules).
 *
 * Three requirements have to be fulfilled so a new column, with data, is
 * displayed in the private message list:
 *  - A field needs to be returned by the list query, see @link sql Query Builder @endlink.
 *  - A header theme pattern needs to exist for the field.
 *  - A field theme pattern needs to exist for the field.
 *
 * For each field in the query, Privatemsg will try to call a theme pattern for
 * the header. That theme function can return a table header definition and
 * has the following structure: theme_privatemsg_list_header_fieldname.
 * @see theme_privatemsg_list_header()
 *
 * Privatemsg will then do the same for each row, with the field theme pattern.
 * That theme function should return a table field compatible structure, either
 * just a string or an array. The theme function has to have the following
 * name: theme_privatemsg_list_field_fieldname.
 * @see theme_privatemsg_list_field()
 *
 * To override an already existing theme function, use the following structure:
 * themename_privatemsg_list_field_fieldname. It is not necessary to
 * overwrite the header theme function unless that information needs to be
 * changed too.
 *
 * Modules can use the hook_form_alter() hook to alter the data. The form with
 * id "privatemsg_list" will contain the header, raw and themed field data in
 * the following form:
 * @code
 * $form['#headers']['field_name'] = $header // Array with the header definition;
 * $form['#data']['thread_id'] = $data // Raw data of that thread
 * $form['#rows']['thread_id'] = $row // Themed fields of that thread
 * @endcode
 *
 * Note that the information in #data can be used to populate #rows, but it will
 * not be used by the default theme function theme_privatemsg_list().
 *
 */

/**
 * @addtogroup theming
 * @{
 */

/**
 * Default theme function for field theme.
 *
 * To hide all fields that don't have an explicit theme pattern defined, this
 * theme doesn't return anything.
 *
 * @param $thread
 *   Thread row returned by the list query.
 *
 * @return
 *   A theme_table() compatible field definition.
 */
function theme_privatemsg_list_field($thread) {
}

/**
 * Theme the participants field.
 *
 * @see theme_privatemsg_list_field()
 */
function theme_privatemsg_list_field__participants($variables) {
  $thread = $variables['thread'];
  $participants = _privatemsg_generate_user_array($thread['participants'], -4);
  $field = array();
  $field['data'] = _privatemsg_format_participants($participants, 3, TRUE);
  $field['class'][] = 'privatemsg-list-participants';
  return $field;
}

/**
 * Theme the subject of the thread.
 *
 * @see theme_privatemsg_list_field()
 */
function theme_privatemsg_list_field__subject($variables) {
  $thread = $variables['thread'];
  $field = array();
  $options = array();
  $is_new = '';
  if (!empty($thread['is_new'])) {
    $is_new = theme('mark', array('type' => MARK_NEW));
    $options['fragment'] = 'new';
  }
  $subject = $thread['subject'];
  if ($thread['has_tokens']) {
    $message = privatemsg_message_load($thread['thread_id']);
    $subject = privatemsg_token_replace($subject, array('privatemsg_message' => $message), array('sanitize' => TRUE, 'privatemsg-show-span' => FALSE));
  }
  $field['data'] = l($subject, 'messages/view/' . $thread['thread_id'], $options) . $is_new;
  $field['class'][] = 'privatemsg-list-subject';
  return $field;
}

/**
 * Theme the replies field.
 *
 * @see theme_privatemsg_list_field()
 */
function theme_privatemsg_list_field__count($variables) {
  $thread = $variables['thread'];
  $field = array();
  $field['data'] = $thread['count'];
  $options = array();
  if (!empty($thread['is_new']) && $thread['is_new'] < $thread['count']) {
    $options['fragment'] = 'new';
    $field['data'] .= '<br />' . l((format_plural($thread['is_new'], '(1 new)', '(@count new)')), 'messages/view/' . $thread['thread_id'], $options);
  }
  $field['class'][] = 'privatemsg-list-count';
  return $field;
}

/**
 * Theme the last updated column.
 *
 * @see theme_privatemsg_list_field()
 */
function theme_privatemsg_list_field__last_updated($variables) {
  $thread = $variables['thread'];
  $field['data'] = privatemsg_format_date($thread['last_updated']);
  $field['class'][] = 'privatemsg-list-date';
  return $field;
}

/**
 * Theme the thread started column.
 *
 * @see theme_privatemsg_list_field()
 */
function theme_privatemsg_list_field__thread_started($variables) {
  $thread = $variables['thread'];
  $field = array();
  $field['data'] = privatemsg_format_date($thread['thread_started']);
  $field['class'][] = 'privatemsg-list-date-started';
  return $field;
}

/**
 * Define the table header for a specific column.
 *
 * This default theme function is used to ignore columns that should not be
 * displayed. Only columns with a specific theme pattern function are displayed.
 *
 * @return
 *   A theme_table() compatible table header definition. Additionally, the key
 *   "key" should be used to specify which row column should be displayed in
 *   this column.
 */
function theme_privatemsg_list_header() {
}

/**
 * Define the subject header.
 *
 * @see theme_privatemsg_list_header()
 */
function theme_privatemsg_list_header__subject() {
  return array(
    'data'    => t('Subject'),
    'field'   => 'subject',
    'class'   => array('privatemsg-header-subject'),
    '#weight' => -40,
  );
}

/**
 * Define the answers column.
 *
 * @see theme_privatemsg_list_header()
 */
function theme_privatemsg_list_header__count() {
  return array(
    'data'    => t('Messages'),
    'class'   => array('privatemsg-header-count'),
    '#weight' => -25,
  );
}

/**
 * Define the participants column.
 *
 * @see theme_privatemsg_list_header()
 */
function theme_privatemsg_list_header__participants() {
  return array(
    'data'    => t('Participants'),
    'class'   => array('privatemsg-header-participants'),
    '#weight' => -30,
  );
}

/**
 * Define the last updated column.
 *
 * @see theme_privatemsg_list_header()
 */
function theme_privatemsg_list_header__last_updated() {
  return array(
    'data'    => t('Last Updated'),
    'field'   => 'last_updated',
    'sort'    => 'desc',
    'class'   => array('privatemsg-header-lastupdated'),
    '#weight' => -20,
  );
}

/**
 * Define the thread started column.
 *
 * @see theme_privatemsg_list_header()
 */
function theme_privatemsg_list_header__thread_started() {
  return array(
    'data'    => t('Started'),
    'field'   => 'thread_started',
    'class'   => array('privatemsg-header-threadstarted'),
    '#weight' => -15,
  );
}

/**
 * Theme a block which displays the number of new messages a user has.
 */
function theme_privatemsg_new_block($count) {
  $count = $count['count'];
  if ($count == 0) {
    $text = t('Click here to go to your messages.');
  }
  else {
    $text = format_plural($count, 'You have a new message! Click here to read it.',
                        'You have @count new messages! Click here to read them.');
  }

  return l($text, 'messages', array('attributes' => array('id' => 'privatemsg-new-link')));
}

/**
 * Used to theme and display user recipients.
 *
 * Wrapper for theme_username() with a few additional options.
 */
function theme_privatemsg_username($variables) {
  $recipient = $variables['recipient'];
  $options = $variables['options'];
  if (!isset($recipient->uid)) {
    $recipient->uid = $recipient->recipient;
  }
  if (!empty($options['plain'])) {
    $name = strip_tags(format_username($recipient));
    if (!empty($options['unique'])) {
      $name .= ' [user]';
    }
    return $name;
  }
  else {
    return theme('username', array('account' => $recipient));
  }
}

/**
 * @}
 */

RaulMuroc’s picture

@Jacky Pinkman, let's go step by step.

You can override functions, that means, you can write over/rewrite an existing functions inside modules with your custom code.

For that you can do module overriding (more for functionality) or template overriding (more for visual stuff).

Here we are doing template overriding.

So you do not have to change privatemsg.theme.inc directly because this file is inside the module "Privatemsg" and if in future you update this module to a newer version your changes will be lost and you will have to re-write again the code.

Best solution so is to write code in a place whatever you update (modules, themes, drupal core...) doesn't affect. Typically this is ../sites/all/themes/REPLACEYOURTHEMENAME/template.php for template overriding.

REPLACEYOURTHEMENAME <-- This means that here you have to write your current used theme, for example, Garland if you are using this theme. The theme is all about visual stuff

PHPTEMPLATE <-- Here you should put as well your theme name.

So, having in mind you have to modify template.php and not privatemsg.theme.inc, watching the whole code in #22 and suposing you are using GARLAND theme, inside template.php will be something similar to:

function garland_privatemsg_list_field__subject($variables) {
  $thread = $variables['thread'];
    $field = array();
       ...

This last means, " ok, in the module privatemsg there is a function called phptemplate_privatemsg_list_field__subject($variables) and this is the function which paints my list of messages so if I wish modify this list to show attached user pictures then I have to modify this function through overriding it."

And that's what we did :) Hope it clarifies a little bit.

My recommendation, get some nice book of drupal to learn about, one that is cool: Drupal 7 themes

Cheers ;)

jweirather’s picture

A couple of thoughts/notes for future readers:

1) Many thanks to everybody on the thread, especially @drupalina #5 and @RaulMuroc #24

2) The code in #5 appears to use the avatar for the author who started the thread, versus the author who sent the most recent message in the thread. This appears to be by design, as showing the most recent author adds query overhead each time the list is loaded. The user who started the thread should be sufficient eye candy and functionality for most (of my) use cases.

3) In 7.x-1.4, the code in #5 worked like a charm for me, adding it to template.php as per #24, and is probably suitable for most users. For reasons I won't delve into, I decided to move the code to a custom "MYMODULE" module (with related settings page) instead of just using template.php, which is a little easier. In order to do to use a custom module instead of template.php, you need to ALSO add a "theme_registry_alter" function to your module file, to tell Drupal what function to use. This is true whenever you want to override _theme_ functions in your custom module instead of the template.php file, because Drupal does not by default look to module files for theme functions(?). I think.

Anyway, mine looked something like this:

(inside of a custom module called MYMODULE.module; replace "MYMODULE" with your module name)

function MYMODULE_theme_registry_alter(&$theme_registry) {
  if (!empty($theme_registry['privatemsg_list_field__subject'])) { // if there is a theme registry setting for 'privatemsg_list_field__subject'
    $theme_registry['privatemsg_list_field__subject']['function'] = 'MYMODULE_privatemsg_list_field__subject'; // then override the default function using my custom function, which is also available in MYMODULE.module file
  }
}

For a short discussion about using template.php versus custom modules, see this thread:
http://drupal.stackexchange.com/questions/42212/custom-module-vs-templat...
Also read comment #24

System Lord’s picture

Dont forget to clear cache!! Ughh what a nightmare. Got #5 working! Thank you for the code!

Now, however, what I need is only the intended recipient's and the sender's user picture to display. Never mine.

Use case: (piggy backing on #25 para 2)
Imagine a dating site's inbox/sent folder. You never see your own user picture whether you start the thread or not. When I send a new message to a recipient I need their user picture to be displayed in the /messages. Also, when I receive a new message from anyone I need their user picture displayed in the /messages/sent.

I also need "Subject" to be changed to "To" and "From" respectively. I don't have "Subject" available to users. Actually, I really don't need anything displayed. I could hit it with "visibility:hidden" But, this may be for another discussion than here.

Apologies...
Moved to: https://www.drupal.org/node/2402063

Triumphent’s picture

How do you add an image style to the code in #5?

tanmayk’s picture

@Triumphent
You can change below line to get image using image style:
$field['data'] = theme('user_picture', array('account' => $message->author));

Instead of above line, get path to user picture image & use theme_image_style.

Triumphent’s picture

@tanmayk: Thank you.

hockey2112’s picture

@RaulMuroc, #21 worked for me. It displays the image in the Subject column, but I'd prefer to move it over to the Participants column where it displays the user's name. How would I do that?

Or... how can I add the user's name alongside the photo in the Subject line?

hockey2112’s picture

How would I grab another field from the user account and print it in the inbox? I created a custom image field (field_user_picture) on the account itself (/admin/config/people/accounts/fields), and I would now like to print that and use that as the inbox thumbnail.

Thanks!

hockey2112’s picture

In an effort to display the Profile2 image in the Participants column instead of the Subject column, I added the following to my template.php:

/**
 * Theme the participants field.
 */
function MYTHEME_privatemsg_list_field__participants($variables) {
  $thread = $variables['thread'];
  $participants = _privatemsg_generate_user_array($thread['participants'], -4);
  $field = array();
    
   //** We will add user picture here */
   
   // Retrieve current recipient/user id
   $aux = explode('_', $thread['participants']);
   $user_id = $aux['1'];
   unset($aux);
   
   // Retrieve each value needed to theme the image: rute to the image, height, width and alternate text if no image found
   $profile_values = profile2_load_by_user($user_id);
   $picture_name = $profile_values['main']->field_user_picture['und'][0]['filename'];
   $picture_uri = $profile_values['main']->field_user_picture['und'][0]['uri'];
   $exploded_uri = explode('//', $picture_uri);
   $route_to_pic = $exploded_uri['1'];
   $picture_path = 'system/files/' . $route_to_pic;
   $picture_width = 40;
   $picture_height = 40;
   $picture_alt_text = $profile_values['main']->field_user_picture['und'][0]['alt'];
   
   // Append the picture to html to be rendered
   $field['data'] = theme_image(array('path' => $picture_path, 'width' => $picture_width, 'height' => $picture_height, 'alt' => $picture_alt_text));
   
  // Then we will append the participant username.
  $field['data'] = _privatemsg_format_participants($participants, 3, TRUE);
  $field['class'][] = 'privatemsg-list-participants';
  return $field;
}

It is not adding the user image to the Participants column.

Can anyone tell me what I am doing wrong, and how I can use this code to add the user's image to the Participants column instead of the Subject column?

One other question... how can I modify the profile2 portion of the code so that the user's image links to their profile page (for example, mysite.com/members/username)

hockey2112’s picture

OK so I tried the solution listed in #3, using the User's "picture" value. It works, but there is still the issue of no image showing up if the recipient has never replied, since the following code is only looking for UID for any user EXCEPT the current author:

    // select last author uid except the current user.
$uid = db_query('SELECT pm.author FROM {pm_message} pm INNER JOIN {pm_index} pmi ON pmi.mid = pm.mid AND pmi.thread_id = :thread WHERE pm.author <> :author ORDER BY pm.timestamp DESC LIMIT 1', array(':thread' => $thread['thread_id'], 'author' => $user->uid))->fetchField();
  // Only display something if we have an uid.
  $account = user_load($uid);
  if ($uid) {
    return theme('user_picture', array('account' =>$account)) . theme('username', array('account' =>$account)) ;
  }

Since there is only one UID, that of the original author, when the message has not yet been replied to, the username and photo do not display and that column is left blank.

How can this code be adjusted to fix this issue? Is there perhaps a way to show the thumbnail for all "other" users involved in the conversation? I suppose that could get unwieldy if you are in a huge group discussion, but I'd imaging those are rarer than one-to-one messaging.

The changes from #10 get me a little closer, in that the recipient user name is displayed in the un-replied-to message in the Sent folder, but it still is not displaying the recipient user's picture.

Anonymous’s picture

function jd_ma_profile_services_get_uid($thread_id, $thread_uid) {

$not_author_uid = db_query('SELECT pm.author FROM {pm_message} pm INNER JOIN {pm_index} pmi ON pmi.mid = pm.mid AND pmi.thread_id = :thread WHERE pm.author <> :author ORDER BY pm.timestamp DESC LIMIT 1',
            array(':thread' => $thread_id, 'author' => $thread_uid))->fetchField();
if (!empty($not_author_uid)) {            
$result = user_load($not_author_uid);
}

if (empty($not_author_uid)) {         
 $thread = _privatemsg_load_thread_participants($thread_id);
 $result = array_pop($thread);
}

return ($result);

}

I just used this function in a custom service to return the user object with the data you are looking for i.e. the OTHER USER besides the author.

the variable $result is the user object so I think $result->picture->uri is the picture. You can also look up formatting the thumbnail using programmatic image styles.

Mihai-Alin’s picture

Hello! I would like to ask some help regarding the message body in the list.
Should I take the same approach as for the avatar, or how could i get something like "privatemsg_list_field__BODY" ?
Thank you!