? cvs-release-notes.php
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.102
diff -u -p -r1.70.2.30.2.91.2.64.2.102 privatemsg.module
--- privatemsg.module	20 Jan 2011 11:43:53 -0000	1.70.2.30.2.91.2.64.2.102
+++ privatemsg.module	18 Feb 2011 15:12:19 -0000
@@ -1870,7 +1870,9 @@ function privatemsg_get_link($recipients
   }
   $url = 'messages/new/'. implode(',', $validated);
   if (!is_null($subject)) {
-    $url .= '/'. $subject;
+    // Explicitly encode the / so that it will be encoded twice to work around
+    // the the menu_system.
+    $url .= '/' . str_replace('/', '%2F', $subject);
   }
   return $url;
 }
Index: privatemsg.pages.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/privatemsg/privatemsg.pages.inc,v
retrieving revision 1.1.2.40
diff -u -p -r1.1.2.40 privatemsg.pages.inc
--- privatemsg.pages.inc	20 Jan 2011 12:57:55 -0000	1.1.2.40
+++ privatemsg.pages.inc	18 Feb 2011 15:12:21 -0000
@@ -328,6 +328,10 @@ function privatemsg_new($form, &$form_st
     $to_plain['user_' . $user->uid] = privatemsg_recipient_format($user, array('plain' => TRUE));
   }
 
+  // Subject has / encoded twice if clean urls are enabled to get it through
+  // mod_rewrite and the menu system. Decode it once more.
+  $subject = str_replace('%2F', '/', $subject);
+
   if (!empty($to)) {
     $recipients_string = implode(', ', $to);
     $recipients_plain = implode(', ', $to_plain);
Index: privatemsg.test
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/privatemsg/privatemsg.test,v
retrieving revision 1.2.2.1.2.42
diff -u -p -r1.2.2.1.2.42 privatemsg.test
--- privatemsg.test	5 Jan 2011 09:54:46 -0000	1.2.2.1.2.42
+++ privatemsg.test	18 Feb 2011 15:12:26 -0000
@@ -1283,4 +1283,61 @@ class PrivatemsgAPITestCase extends Drup
     $this->assertEqual($errormessage, $resultf2['messages']['error'][0], 'API denied to send message from user without permission');
 
   }
+
+  /**
+   * Test various use cases for privatemsg_get_link().
+   */
+  function testGetLink() {
+    $author      = $this->drupalCreateUser(array('write privatemsg', 'read privatemsg'));
+    $recipient1  = $this->drupalCreateUser(array('read privatemsg'));
+    $recipient2  = $this->drupalCreateUser(array('read privatemsg'));
+    $recipient3  = $this->drupalCreateUser(array('read privatemsg', 'allow disabling privatemsg'));
+    $recipient4  = $this->drupalCreateUser();
+
+    $this->drupalLogin($author);
+
+    $this->drupalGet(privatemsg_get_link(array($recipient1)));
+    $this->assertFieldByName('recipient', $recipient1->name . ' [user]');
+
+    $this->drupalGet(privatemsg_get_link(array($recipient1, $recipient2)));
+    $this->assertFieldByName('recipient', $recipient1->name . ' [user], ' . $recipient2->name . ' [user]');
+
+    $this->drupalGet(privatemsg_get_link(array($recipient1, $recipient2), $author));
+    $this->assertFieldByName('recipient', $recipient1->name . ' [user], ' . $recipient2->name . ' [user]');
+
+    $this->drupalGet(privatemsg_get_link(array($recipient1, $recipient2), $author, $subject = 'Str/"ang\\w3//'));
+    $this->assertFieldByName('recipient', $recipient1->name . ' [user], ' . $recipient2->name . ' [user]');
+    $this->assertFieldByName('subject', $subject);
+
+    // Disable privatemsg for recipient 3.
+    db_insert('pm_disable')
+      ->fields(array(
+        'uid' => $recipient3->uid,
+      ))
+      ->execute();
+    $this->assertFalse(privatemsg_get_link(array($recipient3), $author));
+
+    $this->drupalGet(privatemsg_get_link(array($recipient1, $recipient3), $author));
+    $this->assertFieldByName('recipient', $recipient1->name . ' [user]');
+
+    // Disable links to self, verify that a link is only returned when the
+    // author is not the only recipient.
+    variable_set('privatemsg_display_link_self', FALSE);
+
+    $this->assertFalse(privatemsg_get_link(array($author), $author));
+
+    $this->drupalGet(privatemsg_get_link(array($recipient1, $author), $author));
+    $this->assertFieldByName('recipient', $recipient1->name . ' [user]');
+
+    // Verify that link is not shown when recipient doesn't have read
+    // permission.
+    $this->assertFalse(privatemsg_get_link(array($recipient4), $author));
+
+    $this->drupalGet(privatemsg_get_link(array($recipient1, $recipient4), $author));
+    $this->assertFieldByName('recipient', $recipient1->name . ' [user]');
+
+    // Verify that link is not shown when author does not have write permission.
+    $this->drupalLogin($recipient1);
+    $this->assertFalse(privatemsg_get_link(array($author), $recipient1));
+  }
 }
