? .cvsignore
? privatemsg_inbox_tag.patch
Index: privatemsg.pages.inc
===================================================================
RCS file: /cvs/drupal/contributions/modules/privatemsg/privatemsg.pages.inc,v
retrieving revision 1.1
diff -u -p -r1.1 privatemsg.pages.inc
--- privatemsg.pages.inc	2 Dec 2009 20:03:59 -0000	1.1
+++ privatemsg.pages.inc	15 Dec 2009 09:40:36 -0000
@@ -41,6 +41,7 @@ function privatemsg_list(&$form_state, $
   $result = pager_query($query['query'], variable_get('privatemsg_per_page', 25), 0, $query['count']);
 
   $threads = array();
+  $form = array('#list_argument' => $argument);
   $form['#data'] = array();
   while ($row = db_fetch_array($result)) {
     // Store the raw row data.
Index: privatemsg_filter/privatemsg_filter.install
===================================================================
RCS file: /cvs/drupal/contributions/modules/privatemsg/privatemsg_filter/privatemsg_filter.install,v
retrieving revision 1.2
diff -u -p -r1.2 privatemsg_filter.install
--- privatemsg_filter/privatemsg_filter.install	30 Nov 2009 17:37:16 -0000	1.2
+++ privatemsg_filter/privatemsg_filter.install	15 Dec 2009 09:40:37 -0000
@@ -6,7 +6,9 @@
  * install file for privatemsg_filter
  */
 
-
+/**
+ * Implements hook_schema().
+ */
 function privatemsg_filter_schema() {
   $schema = array();
 
@@ -66,15 +68,33 @@ function privatemsg_filter_schema() {
 
   return $schema;
 }
+
+/**
+ * Implements hook_install().
+ */
 function privatemsg_filter_install() {
   drupal_install_schema('privatemsg_filter');
 
 }
 
+/**
+ * Implements hook_enable().
+ */
+function privatemsg_filter_enable() {
+  if (!variable_get('privatemsg_filter_inbox_tag', '')) {
+    db_query("INSERT INTO {pm_tags} (tag, hidden) VALUES('Inbox', 1)");
+    variable_set('privatemsg_filter_inbox_tag', db_last_insert_id('pm_tags', 'tag_id'));
+  }
+}
+
+/**
+ * Implements hook_uninstall().
+ */
 function privatemsg_filter_uninstall() {
   variable_del('privatemsg_filter_searchbody');
   variable_del('privatemsg_filter_tagfield_weight');
   variable_del('privatemsg_filter_default_list');
+  variable_del('privatemsg_filter_inbox_tag');
   drupal_uninstall_schema('privatemsg_filter');
 }
 
@@ -94,4 +114,57 @@ function privatemsg_filter_update_6002()
     'default'       => 0,
   ));
   return $ret;
-}
\ No newline at end of file
+}
+
+/**
+ * Add hidden flag and create inbox tag.
+ */
+function privatemsg_filter_update_6003() {
+  $ret = array();
+  db_add_column($ret, 'pm_tags', 'hidden', 'int', array(
+    'description'   => 'Defines if a tag should not be displayed and is usually automatically managed',
+    'unsigned'      => TRUE,
+    'size'          => 'tiny',
+    'default'       => 0,
+  ));
+
+  if (!variable_get('privatemsg_filter_inbox_tag', '')) {
+    $ret[] = update_sql("INSERT INTO {pm_tags} (tag, hidden) VALUES('Inbox', 1)");
+    variable_set('privatemsg_filter_inbox_tag', db_last_insert_id('pm_tags', 'tag_id'));
+  }
+
+  return $ret;
+}
+
+/**
+ * Add inbox tag to existing inbox messages.
+ */
+function privatemsg_filter_update_6004(&$sandbox) {
+  $sql = 'SELECT pmi.thread_id, pmi.uid FROM {pm_index} pmi GROUP BY pmi.thread_id, pmi.uid HAVING ((SELECT pmf.author FROM {pm_message} pmf WHERE pmf.mid = pmi.thread_id) = pmi.uid AND COUNT(pmi.thread_id) > 1) OR (SELECT COUNT(*) FROM {pm_message} pmf INNER JOIN {pm_index} pmif ON (pmf.mid = pmif.mid) WHERE pmif.thread_id = pmi.thread_id AND pmf.author <> pmi.uid) > 0';
+
+  // First run, initialize sandbox.
+  if (!isset($sandbox['progress'])) {
+    $count_sql = 'SELECT COUNT(*) FROM (' . $sql . ') subquery';
+    $sandbox['progress'] = 0;
+    $sandbox['max'] = db_result(db_query($count_sql));
+  }
+
+  // Process 20 threads.
+  $result = db_query_range($sql, $sandbox['progress'], 20);
+  $i = 0;
+  while ($row = db_fetch_object($result)) {
+    privatemsg_filter_add_tags(array($row->thread_id), variable_get('privatemsg_filter_inbox_tag', ''), $row);
+    $i++;
+  }
+
+  // When less than 20 threads were processed, we're finished.
+  if ($i < 20) {
+    $sandbox['progress'] = $sandbox['max'];
+  }
+  else {
+    $sandbox['progress'] += $i;
+  }
+  // Set #finished based on sandbox.
+  $ret['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']);
+  return $ret;
+}
Index: privatemsg_filter/privatemsg_filter.module
===================================================================
RCS file: /cvs/drupal/contributions/modules/privatemsg/privatemsg_filter/privatemsg_filter.module,v
retrieving revision 1.3
diff -u -p -r1.3 privatemsg_filter.module
--- privatemsg_filter/privatemsg_filter.module	2 Dec 2009 20:04:00 -0000	1.3
+++ privatemsg_filter/privatemsg_filter.module	15 Dec 2009 09:40:37 -0000
@@ -461,6 +461,48 @@ function privatemsg_filter_create_get_qu
 }
 
 /**
+ * Form callback for adding a tag to threads.
+ */
+function privatemsg_filter_add_tag_submit($form, &$form_state) {
+  $operation = array(
+    'callback' => 'privatemsg_filter_add_tags',
+    'callback arguments' => array('tag_id' => $form_state['values']['tag-add']),
+    'undo callback' => 'privatemsg_filter_remove_tags',
+    'undo callback arguments' => array('tag_id' => $form_state['values']['tag-add']),
+  );
+  drupal_set_message(t('The selected conversations have been tagged.'));
+  privatemsg_operation_execute($operation, $form_state['values']['threads']);
+}
+
+/**
+ * Form callback for removing a tag to threads.
+ */
+function privatemsg_filter_remove_tag_submit($form, &$form_state) {
+  $operation = array(
+    'callback' => 'privatemsg_filter_remove_tags',
+    'callback arguments' => array('tag_id' => $form_state['values']['tag-remove']),
+    'undo callback' => 'privatemsg_filter_add_tags',
+    'undo callback arguments' => array('tag_id' => $form_state['values']['tag-remove']),
+  );
+  drupal_set_message(t('The tag has been removed from the selected conversations.'));
+  privatemsg_operation_execute($operation, $form_state['values']['threads']);
+}
+
+/**
+ * Form callback for removing a tag to threads.
+ */
+function privatemsg_filter_archive_submit($form, &$form_state) {
+  $operation = array(
+    'callback' => 'privatemsg_filter_remove_tags',
+    'callback arguments' => array('tag_id' => variable_get('privatemsg_filter_inbox_tag', '')),
+    'undo callback' => 'privatemsg_filter_add_tags',
+    'undo callback arguments' => array('tag_id' => variable_get('privatemsg_filter_inbox_tag', '')),
+  );
+  drupal_set_message(t('The messages have been archived.'));
+  privatemsg_operation_execute($operation, $form_state['values']['threads']);
+}
+
+/**
  * Implements hook_form_FORM_ID_alter().
  *
  * Adds a filter widget to the message listing pages.
@@ -473,7 +515,7 @@ function privatemsg_filter_form_privatem
   }
 
   $fields = array_filter(variable_get('privatemsg_display_fields', array('participants')));
-  if (in_array('tags', $fields)) {
+  if (in_array('tags', $fields) && !empty($form['#data'])) {
     // Load thread id's of the current list.
     $threads = array_keys($form['#data']);
 
@@ -487,6 +529,15 @@ function privatemsg_filter_form_privatem
     }
   }
 
+  if ($form['#list_argument'] == 'inbox' && !empty($form['#data'])) {
+    $form['actions']['archive'] = array(
+      '#type'   => 'submit',
+      '#value'  => t('Archive'),
+      '#submit' => array('privatemsg_filter_archive_submit'),
+      '#weight' => -10,
+    );
+  }
+
   $tags = privatemsg_filter_get_tags_data($user);
   if (privatemsg_user_access('filter private messages') && !empty($tags) && !empty($form['#data'])) {
     $options = array();
@@ -578,14 +629,13 @@ function privatemsg_filter_privatemsg_sq
     $fragments['where'][]       = "pm.author = %d";
     $fragments['query_args']['where'][]   = $account->uid;
   }
+  $filter = privatemsg_filter_get_filter($account);
   if ($argument == 'inbox') {
-    $fragments['having'][]       = '((SELECT pmf.author FROM {pm_message} pmf WHERE pmf.mid = pmi.thread_id) = %d AND COUNT(pmi.thread_id) > 1) OR (SELECT COUNT(*) FROM {pm_message} pmf INNER JOIN {pm_index} pmif ON (pmf.mid = pmif.mid) WHERE pmif.thread_id = pmi.thread_id AND pmf.author <> %d) > 0';
-    $fragments['query_args']['having'][]   = $account->uid;
-    $fragments['query_args']['having'][]   = $account->uid;
+    $filter['tags'][] = variable_get('privatemsg_filter_inbox_tag', '');
   }
 
   // Filter the message listing by any set tags.
-  if ($filter = privatemsg_filter_get_filter($account)) {
+  if ($filter) {
     $count = 0;
     if (isset($filter['tags']) && !empty($filter['tags'])) {
       foreach ($filter['tags'] as $tag) {
@@ -772,7 +822,7 @@ function privatemsg_filter_privatemsg_sq
  * @param $limit
  *   Limit the number of tags *per thread*.
  */
-function privatemsg_filter_sql_tags(&$fragments, $user = NULL, $threads = NULL, $limit = NULL) {
+function privatemsg_filter_sql_tags(&$fragments, $user = NULL, $threads = NULL, $limit = NULL, $showHidden = FALSE) {
   $fragments['primary_table'] = '{pm_tags} t';
   $fragments['select'][] = 't.tag';
   $fragments['select'][] = 't.tag_id';
@@ -799,6 +849,10 @@ function privatemsg_filter_sql_tags(&$fr
     $fragments['query_args']['where'][] = $user->uid;
   }
 
+  if (!$showHidden) {
+    $fragments['where'][]       = 't.hidden = 0 OR t.hidden IS NULL';
+  }
+
   // Only select n tags per thread (ordered per tag_id), see
   // http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/.
   //
@@ -868,4 +922,10 @@ function privatemsg_filter_user($op, &$e
       db_query("DELETE FROM {pm_tags_index} WHERE uid = %d", $account->uid, $account->uid);
       break;
   }
+}
+
+function privatemsg_filter_privatemsg_message_insert($message) {
+  foreach ($message['recipients'] as $recipient) {
+    privatemsg_filter_add_tags(array($message['thread_id']), variable_get('privatemsg_filter_inbox_tag', ''), $recipient);
+  }
 }
\ No newline at end of file
