This page explains how to embed certain pages of Privatemsg into your website. Be sure only to use code suitable for your respective version of Drupal.

You should know some things about Drupal administration (for example, how to create new blocks) and some PHP knowledge if you want to further customize the given examples.

Warning: While these examples say that you can put this in a custom block through the User Interface, it is heavily suggested to create a custom module instead to embed PHP code into your site. Also, these examples are untested and might not work properly.

Privatemsg for Drupal 6

Display list of latest 5 messages in a block

Create a new block with the PHP Filter and put the following code into it:

global $user;

// Generate the query to load the messages.
// Replace 'inbox' with 'sent' to display sent messages or 'list' to display all messages.
$query = _privatemsg_assemble_query('list', $user, 'inbox');

// Load 5 messages/threads. Replace 5 if you want to display a different amount of messages.
$result = db_query_range($query['query'], 0, 5);
$list = array();
while ($thread = db_fetch_array($result)) {
  // Generate a link with the subject as title that points to the view message page.
  $list[] = l($thread['subject'], 'messages/view/'. $thread['thread_id']);
}
// Display list as a themed item_list.
echo theme('item_list', $list);

Display a list of unread messages.

Put the following code into a custom module (If you don't have one, you need to create it: http://drupal.org/node/206753). This tells the query builder of Privatemsg to only include new messages when you pass the argument "unread" to it.

function yourmodule_privatemsg_sql_list_alter(&$fragments, $account, $argument) {
  if ($argument == 'unread') {
    $fragments['where'][] = 'pmi.is_new = 1';
  }
}

In a second step, you have to embed the list with the unread argument into your website. As an example, you could use the above example to display it in a block and simply replace "inbox" with "unread".

You can customize almost every query that Privatemsg uses to load information, see http://blog.worldempire.ch/api/group/sql/1 for more information.

Display a form to send a new private message

There are two possible ways to do this, depending on your use case:

Use the existing Privatemsg form

This is useful if you simply want to display this form in a block or another non-default place. Place the following code into a new block or wherever you want it:

// The module_load_include() is necessary when using 6.x-2.x
// module_load_include('pages.inc','privatemsg');
echo drupal_get_form('privatemsg_new');

You can further customize this by adding default recipients and/or a default subject.

// The first argument can be a list of user objects the message should be sent to. These are just default values and it is possibel to change them as a user.
// Example: Send to the user with uid 1.
$recipients = array(user_load(1));
// The second argument sets the default subject.
$subject = 'Again, this is just a default that can be changed';
echo drupal_get_form('privatemsg_new', $recipients, $subject);

Note: If you display this in a block, you probably need to theme the form with CSS and/or a theme function to make it narrower.

Use a custom form and the Privatemsg API functions

A possible use case for this would be a contact form to send messages to a specific user like the site admin. First you have to create your form with Drupal FAPI (see http://api.drupal.org/api/group/form_api/6) and validate it as usually. In your submit function, you can use the privatemsg_new_thread() API function to start a new thread:

The following example sends a message to user 1 with a hardcoded subject.

function your_form_name_submit($form, &$form_state) {
  // Send message to user 1.
  $recipients = array(user_load(1));
  // Define the subject of the thread
  $subject = 'Message sent through contact form';
  // We assume the fapi element with the message text is called "body".
  $body = $form_state['values']['body'];
  
  // Send the message.
  $return = privatemsg_new_thread($recipients, $subject, $body);
  
  // Check return value to see if the message has been sent.
  if ($return['success']) {
    // Message has been sent, display confirmation message.
    drupal_set_message(t('Message has been sent.'));
  }
  else {
    // Display possible errors...
    foreach ($return['messages']['error'] as $error) {
      drupal_set_message($error, 'error');
    }
  }
  // Display warnings, these might occur even if the message has been sent successfully.
  foreach ($return['messages']['warning'] as $warning) {
    drupal_set_message($warning, 'warning');
  }
}

Privatemsg for Drupal 7

Display list of latest 5 messages in a block

global $user;

// Generate the query to load the messages.
// Replace 'inbox' with 'sent' to display sent messages or 'list' to display all messages.
$query = _privatemsg_assemble_query('list', $user, 'inbox');

// Load 5 messages/threads. Replace 5 if you want to display a different amount of messages.

$list = array();
$count=0;
foreach ($query->execute() as $thread) {
  if ($count <=5) {
    // Generate a link with the subject as title that points to the view message page.
    // $list[] = l($thread->subject, 'messages/view/'. $thread->thread_id);
    // take a look at $thread to see if what you needed is already there, so you can bypass other theming functions (you probably shouldnt)

    // proper solution:
    $theme_variables=array('thread' => (array)$thread);
    $subject=theme('privatemsg_list_field__subject', $theme_variables);
    $list_parts[]=$subject['data'];
    $list_parts[]=t('from');
    $participants=theme('privatemsg_list_field__participants', $theme_variables);
    $list_parts[]=$participants['data'];
    $last_updated=theme('privatemsg_list_field__last_updated', $theme_variables);
    $list_parts[]=$last_updated['data'];
    $list[] = implode(' ',$list_parts);
    $count++;
  } else {
    break;
  }
}

// Display list as a themed item_list.

print theme('item_list', array('items'=>$list));

Display a list of unread messages.

Extending the above example; you have to modify the query returned from _privatemsg_assemble_query() to include only unread messages like this:

$query = _privatemsg_assemble_query('list', $user, 'inbox');
$query->condition('pmi.is_new', 1);

Render the send message form with preset recipient

For Drupal 7 user, you can render the form in block as follow.

  module_load_include('pages.inc','privatemsg');
  $recipients = array(user_load($uid));
  $subject = 'Again, this is just a default that can be changed';
  print drupal_get_form('privatemsg_new', $recipients, $subject);

Please open bug reports if an example does not work or create a support request if you have a privatemsg related question here: http://drupal.org/node/add/project-issue/privatemsg

Comments

neopoet’s picture

There's an easier way that doesn't involve creating a custom module:

The below code generates a variable with the unread message count

privatemsg_unread_count($user->uid);

You can feed this into the code snippet so that only the x most recent messages are displayed (where x is the number of unread messages) -- note: there's an issue with this: this will only display the x more recent messages, so if, for example, the only unread message was 5 messages prior, this will display the wrong set...

Just replace

 if ($count <=5) {

with:

  if ($count <privatemsg_unread_count($user->uid)) {
Cromian’s picture

How would one add a delete link? Like in the listing of messages via inbox simply have a button that deletes the message right there in one click vs. three?

- C

fehin’s picture

I'm getting error when I try to use the embed form example. I'm on D7.

<?php
    Notice: Undefined index: privatemsg_new in drupal_retrieve_form() (line 752 of \includes\form.inc).
    Warning: call_user_func_array() expects parameter 1 to be a valid callback, function 'privatemsg_new' not found or invalid function name in drupal_retrieve_form() (line 787 of \includes\form.inc).
?>
jayhariani’s picture

<?php
  module_load_include('pages.inc','privatemsg');
  $recipients = array(user_load(arg(1)));
  $subject = 'Again, this is just a default that can be changed';
  print drupal_render(drupal_get_form('privatemsg_new', $recipients, $subject));
?>
fehin’s picture

Thank you. I will try it out. Do you know how to generate the Participant (sender) field?

yustos’s picture

When I try to run the code, I keep getting an error "Strict warning: Only variables should be passed by reference in function eval() (string 5 in C:\apache\htdocs\d7\modules\php\php.module(80) : eval()'d code)". What am I doing wrong?

fehin’s picture

I want to add "sender" to my mini inbox in the block. What do I use for the field?

zeezack’s picture

How would you configure an embedded private message form ajax based?

zeezack’s picture

Trying to get the private message embed to work via ajax. Its created a new submit button - and it looks like it does an ajaxy thing, but I am unsure how to get the callback - its also not submitting the form. Any help asap will be appreciated.

Am I to create a new functon like

function advanced_form_callback($form){
return json_encode($response);
}

	<?php
		module_load_include('pages.inc','privatemsg');
		
		
		
		function new_note_form($form, &$form_state, $nodeid = NULL) {
		  $form_state['build_info']['args'] = array('note');
		  $form = drupal_build_form('privatemsg_new', $form_state);

		  $form['submit'] = array(
			'#type' => 'button',
			'#value' => 'Submit',
			'#limit_validation_errors' => array(),
			'#ajax' => array(
				'callback' => 'advanced_form_callback',
				'wrapper' => 'status',
			),
		  );

		  return $form;
		}

		echo render(drupal_get_form('new_note_form'));	
?>
vegaper’s picture

Hi, I'm quite unexperienced with Drupal I want to display the send private message form in a block, and this can sound a bit stupid but... I don't have any idea where I have to place the php code you are providing. Is there any place where s/o explain where and how to paste the code? or if it is easy can you explain it to me, please?
thank you very much.

fehin’s picture

Go to Blocks > select "Add block" > at the bottom of the form, change Text format "php code". Then copy and paste the code there. If you don't see "php code" option, enable the php module.

ChrisValentine’s picture

You first need to go to Modules and allow PHP filter - make sure you carefully restrict its use, though. Admin only should suffice. When you've done that, you can pick PHP as a Text format.

Web application developer
http://kmi.open.ac.uk/

josebc’s picture

did anyone managed to get hook_privatemsg_sql_list_alter working?
i need to filter results on some custom rules
thank you

abrahamso’s picture

current code


global $user;

// Generate the query to load the messages.
// Replace 'inbox' with 'sent' to display sent messages or 'list' to display all messages.
$query = _privatemsg_assemble_query('list', $user, 'inbox');

// Load 5 messages/threads. Replace 5 if you want to display a different amount of messages.

$list = array();
$count=0;
foreach ($query->execute() as $thread) {
  if ($count <=5) {
    // Generate a link with the subject as title that points to the view message page.
    $list[] = array(l($thread->subject, 'messages/view/'. $thread->thread_id));
    $count++;
  } else {
    break;
  }
}

// Display list as a themed item_list.
$header_array = array(
      'subject' => array('data' => 'Subject', 'type' => 'property', 'specifier' => 'subject', 'sort' => 'asc'),
);

$recipients = user_load(array('uid' => $recipients));


$header = array('Subject');
print theme('table',  array('header' => $header, 'rows' =>  $list));


How can i add date and sender name into the page?

RaulMuroc’s picture

Hi,

Would be nice that the code example in Drupal 7 to have a block with preset recipient, which works for USER type, will also be available (explained) for PROFILE2 type.

Thanks.

Drupal Association individual member

icistech’s picture

How can I add custom fields to the list?
I have added a field with machine name field_donation_amt to
/admin/config/messaging/privatemsg/fields

I want to have a list that looks like:
username | date sent | Amount (custom field)

josephd’s picture

If anyone is still interested in this i've written a module that exposes a block containing the PM list and controls that can be embedded in any page with regions. It's still in development but it's worked for all of the use cases i've tried.

https://www.drupal.org/sandbox/josephd/2686629