First, a little background info:

I'm running privatemsg 7.x-1.2 across several sites running on a single D7 codebase. I have all of the privatemsg tables in one database, which is accessed by all of the sites as to keep private messages synchronised between them.

To enhance that little setup, what I would like to do is manipulate the message body at the time of insertion/saving to append a "This message was sent via [site name]" line at the very end of each message. This is how I achieved it at first:

function global_privatemsg_message_presave_alter(&$message) {
    $message->body .= "<div class=\"sent-via\">(". t("Sent via !site_link", array('!site_link' => get_site_link())) .")</div>";

That worked well except I overlooked the fact that hook_privatemsg_presave_alter takes place prior to the input filter being applied, so if the user sends their message as "Filtered HTML" or "Plain text", the 'sent-via' gets thrown out.

So, what I'm looking for is a reliable way of appending markup to the message body, or even introducing a new template variable that I can populate accordingly, without it being mangled by input filters (the result of Drupal's check_markup, I suppose).

Preferably I want to do this entirely within the constraints of the Privatemsg module API, but I appreciate that might be asking for the impossible.


1 Answer 1


(I haven't used privatemsg) ... but sure it's doable because of a new feature in D7:

Instead of attachments, private messages are fieldable and any number and combination of fields can be added to them.

So what you do is code up a custom module that defines a custom "sent_by_sitename" field that is a text field_type. Then in your presave hook you would just do:

$message->sent_by_sitename = 'some_sitename_in_your_multisite_install';

Then you could alter your message display to show this new field with a custom formatter that adds the markup and leading "This message sent by " markup.

I dont have the code to do this offhand (its probably about 30 lines). Here is a similar request of adding custom fields to the default user object in drupal -- your request is different regarding privatemsg but you probably will still use some of the same functions: add-properties-to-an-entity-hook-schema-alter

So in short:

  • Define your custom field in your custom module, eg hook_field_info()
  • on module_enable() and module_disable() attach your field to the message entity, eg field_create_field() and field_create_instance()
  • alter your existing privatemsg API call to set this new field value instead of raw HTML.
  • alter your privatemsg message display to show your new field with its associated field_formatter to be at the bottom of the message display.
  • Thanks, that seems like a fairly solid solution. Since posting the question it has occurred to me that I might be able to use one of the privatemsg hooks (hook_privatemsg_message_insert to be precise) to run an update query on the message row for the same end result, but this will be my second port of call. Gives me an insight into manipulating fields in general too :)
    – Riari
    Commented Apr 11, 2012 at 22:20
  • @RickoMann No, that won't help. Text formats are applied when content is displayed, not when it's saved into the database.
    – Berdir
    Commented Apr 13, 2012 at 11:27
  • @Berdir D'oh, right you are. I knew that's how input filters normally work, but for some reason I thought privatemsg only did check_markup() just before insertion and not on display. I don't like the idea of introducing another module just to facilitate this but I'm probably being overly picky in that regard. :)
    – Riari
    Commented Apr 13, 2012 at 15:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.