? .cvsignore
? privatemsg_paging.patch
? privatemsg_paging2.patch
? privatemsg_paging3.patch
? privatemsg_paging4.patch
Index: privatemsg.module
===================================================================
RCS file: /cvs/drupal/contributions/modules/privatemsg/privatemsg.module,v
retrieving revision 1.70.2.30.2.91.2.93
diff -u -p -r1.70.2.30.2.91.2.93 privatemsg.module
--- privatemsg.module	10 Nov 2009 19:48:17 -0000	1.70.2.30.2.91.2.93
+++ privatemsg.module	10 Nov 2009 21:21:03 -0000
@@ -251,6 +251,9 @@ function privatemsg_view_access() {
  * @param $account
  *   User object for which the thread should be loaded, defaults to
  *   the current user.
+ * @param $limit
+ *   How many messages should be loaded. Unread messages will always be
+ *   displayed and counting starts from the end.
  *
  * @return
  *   $thread object, with keys messages, participants, title and user. messages
@@ -262,7 +265,7 @@ function privatemsg_view_access() {
 
  * @ingroup api
  */
-function privatemsg_thread_load($thread_id, $account = NULL) {
+function privatemsg_thread_load($thread_id, $account = NULL, $limit = NULL) {
   static $threads = array();
   if ((int)$thread_id > 0) {
     $thread = array('thread_id' => $thread_id);
@@ -289,9 +292,29 @@ function privatemsg_thread_load($thread_
         $thread['read_all'] = TRUE;
       }
 
+      // If limit is NULL, select based on get params.
+      if (is_null($limit)) {
+        if (isset($_GET['show']) && (int)$_GET['show'] > 0) {
+          $limit = (int)$_GET['show'];
+        }
+        else {
+          $limit = variable_get('privatemsg_view_limit', 10);
+        }
+      }
+      $thread['limit'] = $limit;
+
       // load messages returned by the messages query with privatemsg_message_load_multiple().
       $query = _privatemsg_assemble_query('messages', array($thread_id), $thread['read_all'] ? NULL : $account);
-      $conversation = db_query($query['query']);
+      $thread['message_count'] = db_result(db_query($query['count']));
+      // Check if we need to limit the messages.
+      $startwith = 0;
+      if ($thread['message_count'] > $limit) {
+        $startwith = $thread['message_count'] - $limit;
+      }
+      elseif ($limit > variable_get('privatemsg_view_limit', 10) && $limit > $thread['message_count']) {
+        $thread['limit'] = $limit = $thread['message_count'];
+      }
+      $conversation = db_query_range($query['query'], $startwith, variable_get('privatemsg_view_hardlimit', 50));
       $mids = array();
       while ($result = db_fetch_array($conversation)) {
         $mids[] = $result['mid'];
@@ -299,12 +322,12 @@ function privatemsg_thread_load($thread_
       // Load messages returned by the messages query.
       $thread['messages'] = privatemsg_message_load_multiple($mids, $thread['read_all'] ? NULL : $account);
 
-      // if there are no messages, don't allow access to the thread.
+      // If there are no messages, don't allow access to the thread.
       if (empty($thread['messages'])) {
         $thread = FALSE;
       }
       else {
-        // general data, assume subject is the same for all messages of that 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'];
@@ -417,6 +440,20 @@ function private_message_settings() {
     '#default_value' => variable_get('privatemsg_display_fields', array('participants')),
   );
 
+  $form['privatemsg_listing']['privatemsg_view_limit'] = array(
+    '#type'          => 'textfield',
+    '#title'         => t('Display limit for messages inside threads'),
+    '#default_value' => variable_get('privatemsg_view_limit', 10),
+    '#description'   => t('Define how many messages should be displayed by default. It does display the last messages and earlier messages can be displayed incrementally by the same amount.'),
+  );
+
+  $form['privatemsg_listing']['privatemsg_view_hardlimit'] = array(
+    '#type'          => 'textfield',
+    '#title'         => t('Hard display limit for messages inside threads'),
+    '#default_value' => variable_get('privatemsg_view_hardlimit', 50),
+    '#description'   => t('Threads will never display more messages than defined here at the same time. It is still possible to view all messages of a thread, but not at the same time.'),
+  );
+
   $form['#submit'][] = 'private_message_settings_submit';
   return system_settings_form($form);
 }
@@ -643,6 +680,33 @@ function privatemsg_unread_count($accoun
 function privatemsg_view($thread) {
   drupal_set_title(check_plain($thread['subject']));
 
+  // Generate paging links.
+  if ($thread['message_count'] > count($thread['messages'])) {
+    $from = $thread['message_count'] - $thread['limit'] + 1;
+    $to = $from - 1 + (($thread['limit'] > variable_get('privatemsg_view_hardlimit', 50)) ? variable_get('privatemsg_view_hardlimit', 50) : $thread['limit']);
+
+    $previous = '';
+    if ($from > 1) {
+      $options = array(
+        'query' => array('show' => $thread['limit'] + variable_get('privatemsg_view_limit', 10)),
+        'title' => t('Display older messages'),
+      );
+       $previous = l(t('<<'), 'messages/view/' . $thread['thread_id'], $options);
+    }
+    $newer = '';
+    if ($to < $thread['message_count']) {
+      $options = array(
+        'query' => array('show' => $thread['limit'] - variable_get('privatemsg_view_limit', 10)),
+        'title' => t('Display newer messages'),
+      );
+      $newer = l(t('>>'), 'messages/view/' . $thread['thread_id'], $options);
+    }
+
+    $title = t('!previous_link Displaying messages @from - @to of @total !newer_link', array('@from' => $from, '@to' => $to, '@total' => $thread['message_count'], '!previous_link' => $previous, '!newer_link' => $newer));
+    $content['display_all']['#value'] = trim($title);
+    $content['display_all']['#weight'] = -10;
+  }
+
   // Render the participants.
   $content['participants']['#value'] = theme('privatemsg_recipients', $thread);
   $content['participants']['#weight'] = -5;
@@ -1088,7 +1152,7 @@ function privatemsg_sql_load(&$fragments
 function privatemsg_sql_messages(&$fragments, $threads, $account = NULL, $load_all = FALSE) {
   $fragments['primary_table'] = '{pm_index} pmi';
 
-  $fragments['select'][]      = 'DISTINCT(pmi.mid) as mid';
+  $fragments['select'][]      = 'pmi.mid';
   $fragments['where'][]       = 'pmi.thread_id IN ('. db_placeholders($threads) .')';
   $fragments['query_args']['where']   += $threads;
   if ($account) {
@@ -1097,8 +1161,9 @@ function privatemsg_sql_messages(&$fragm
     $fragments['query_args']['where'][]  = $account->uid;
   }
   if (!$load_all) {
-    $fragments['where'][]       = 'pmi.deleted = 0';
+    $fragments['where'][]     = 'pmi.deleted = 0';
   }
+  $fragments['group_by'][]    = 'pmi.mid';
   $fragments['order_by'][]    = 'pmi.mid ASC';
 }
 
Index: privatemsg.test
===================================================================
RCS file: /cvs/drupal/contributions/modules/privatemsg/privatemsg.test,v
retrieving revision 1.2.2.9
diff -u -p -r1.2.2.9 privatemsg.test
--- privatemsg.test	9 Nov 2009 20:08:09 -0000	1.2.2.9
+++ privatemsg.test	10 Nov 2009 21:21:03 -0000
@@ -64,6 +64,61 @@ class PrivatemsgTestCase extends DrupalW
     $this->assertResponse(200, t('HTTP Response 200: Access to Write New Message page was authorized to user with "<em>write privatemsg</em>" permission'));
   }
 
+  function testPaging() {
+    $author     = $this->drupalCreateUser(array('write privatemsg', 'read privatemsg'));
+    $recipient  = $this->drupalCreateUser(array('read privatemsg'));
+
+    // Set lower values so that we don't need to generate 100's of messages.
+    variable_set('privatemsg_view_limit', 5);
+    variable_set('privatemsg_view_hardlimit', 10);
+
+    $subject = $this->randomName(20);
+    $bodies = array();
+    for ($i = 0; $i < 25; $i++) {
+      $bodies[$i] = $this->randomName(100);
+    }
+    $thread = privatemsg_new_thread(array($recipient), $subject, $bodies[0], array('author' => $author));
+    for ($i = 1; $i < 25; $i++) {
+      privatemsg_reply($thread['message']['thread_id'], $bodies[$i], array('author' => $author));
+    }
+
+    $this->drupalLogin($recipient);
+    $this->drupalGet('messages');
+    $this->clickLink($subject);
+
+    // Verify that only the last 5 messages are displayed.
+    $this->assertText(t('Displaying messages 21 - 25 of 25'), t('Pager is displayed'));
+    $this->assertNoText($bodies[0], t('First message is not displayed.'));
+    $this->assertNoText($bodies[19], t('Hidden message is not displayed.'));
+    $this->assertText($bodies[20], t('Message is displayed.'));
+    $this->assertText($bodies[24], t('Message is displayed.'));
+
+    // Load older messages and verify again.
+    $this->clickLink(t('<<'));
+    $this->assertText(t('Displaying messages 16 - 25 of 25'), t('Pager is displayed'));
+    $this->assertNoText($bodies[0], t('First message is not displayed.'));
+    $this->assertNoText($bodies[14], t('Hidden message is not displayed.'));
+    $this->assertText($bodies[15], t('Message is displayed.'));
+    $this->assertText($bodies[24], t('Message is displayed.'));
+
+    // Load older messages and verify again.
+    $this->clickLink(t('<<'));
+    $this->assertText(t('Displaying messages 11 - 20 of 25'), t('Pager is displayed'));
+    $this->assertNoText($bodies[0], t('First message is not displayed.'));
+    $this->assertNoText($bodies[9], t('Hidden message is not displayed.'));
+    $this->assertNoText($bodies[20], t('Hidden message is not displayed.'));
+    $this->assertText($bodies[10], t('Message is displayed.'));
+    $this->assertText($bodies[19], t('Message is displayed.'));
+
+    // Display newer messages and verify again.
+    $this->clickLink(t('>>'));
+    $this->assertText(t('Displaying messages 16 - 25 of 25'), t('Pager is displayed'));
+    $this->assertNoText($bodies[0], t('First message is not displayed.'));
+    $this->assertNoText($bodies[14], t('Hidden message is not displayed.'));
+    $this->assertText($bodies[15], t('Message is displayed.'));
+    $this->assertText($bodies[24], t('Message is displayed.'));
+  }
+
   /**
    * Test sending message from the /messages/new page between two people
    */
