diff --git a/privatemsg.module b/privatemsg.module index 4f50ad6e80f49579d86096e40b8c2405ff89dd52..308eb48c98e43aa72a2bea23bc8c4c0c44ca7774 100644 --- a/privatemsg.module +++ b/privatemsg.module @@ -110,26 +110,18 @@ function privatemsg_menu() { 'title' => 'Messages', 'title callback' => 'privatemsg_title_callback', 'page callback' => 'drupal_get_form', - 'page arguments' => array('privatemsg_list'), + 'page arguments' => array('privatemsg_list', 'list'), 'access callback' => 'privatemsg_user_access', 'type' => MENU_NORMAL_ITEM, ); - $items['messages/inbox'] = array( - 'title' => 'All messages', + $items['messages/list'] = array( + 'title' => 'Messages', 'page callback' => 'drupal_get_form', - 'page arguments' => array('privatemsg_list'), + 'page arguments' => array('privatemsg_list', 'list'), 'access callback' => 'privatemsg_user_access', 'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10, ); - $items['messages/sent'] = array( - 'title' => 'Sent messages', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('privatemsg_list'), - 'access callback' => 'privatemsg_user_access', - 'type' => MENU_LOCAL_TASK, - 'weight' => -5, - ); $items['messages/view/%privatemsg_thread'] = array( 'title' => 'Read message', 'page callback' => 'privatemsg_view', @@ -318,11 +310,11 @@ function private_message_settings() { '#title' => t('Configure fields'), '#description' => t('Select which columns/fields should be displayed in the message listings. Subject and Last updated cannot be disabled.'), '#options' => array( - 'author' => t('Author'), + 'participants' => t('Participants'), 'thread_started' => t('Started'), 'count' => t('Answers'), ), - '#default_value' => variable_get('privatemsg_display_fields', array('author')), + '#default_value' => variable_get('privatemsg_display_fields', array('participants')), ); $form['#submit'][] = 'private_message_settings_submit'; @@ -410,10 +402,17 @@ function privatemsg_preprocess_privatemsg_to(&$vars) { /** * List messages. * + * @param $form_state + * Form state array + * @param $argument + * An argument to pass through to the query builder. * @param $uid - * user id for whom to load messages. + * User id messages of another user should be displayed + * + * @return + * Form array */ -function privatemsg_list(&$form_state, $uid = NULL) { +function privatemsg_list(&$form_state, $argument = 'list', $uid = NULL) { global $user; // Setting default behavior... @@ -430,14 +429,8 @@ function privatemsg_list(&$form_state, $uid = NULL) { } } // By this point we have figured out for which user we are listing messages and now it is safe to use $account->uid in the listing query. - switch (arg(1)) { - case 'sent': - $query = _privatemsg_assemble_query('list_sent', $account); - break; - case 'inbox': - default: - $query = _privatemsg_assemble_query('list', $account); - } + + $query = _privatemsg_assemble_query('list', $account, $argument); $result = pager_query($query['query'], variable_get('privatemsg_per_page', 25), 0, $query['count']); $threads = array(); @@ -747,46 +740,11 @@ function pm_preview($form, &$form_state) { $form_state['rebuild'] = TRUE; // this forces our form to be rebuilt instead of being submitted. } -function privatemsg_sql_list_sent(&$fragments, $account) { - $fragments['primary_table'] = '{pm_message} pm'; - - $fragments['select'][] = 'pmi.thread_id'; - $fragments['select'][] = 'pm.subject'; - if ($GLOBALS['db_type'] == 'pgsql') { - $fragments['select'][] = "array_to_string(array(SELECT DISTINCT textin(int4out(pmia.uid)) - FROM {pm_index} pmia - WHERE pmia.thread_id = pmi.thread_id AND pmia.uid <> %d), ',') AS recipient"; - - } - else { - $fragments['select'][] = '(SELECT GROUP_CONCAT(DISTINCT pmia.uid SEPARATOR ",") - FROM {pm_index} pmia - WHERE pmia.thread_id = pmi.thread_id AND pmia.uid <> %d) AS recipient'; - - } - $fragments['query_args'][] = $account->uid; - - $fragments['select'][] = 'MAX(pm.timestamp) as last_updated'; - $fragments['inner_join'][] = 'INNER JOIN {pm_index} pmi ON pm.mid = pmi.mid'; - $fragments['where'][] = 'pmi.uid = %d'; - $fragments['query_args'][] = $account->uid; - $fragments['where'][] = 'pm.author = %d'; - $fragments['query_args'][] = $account->uid; - $fragments['where'][] = 'pmi.deleted = 0'; - $fragments['group_by'][] = 'pmi.thread_id'; - $fragments['group_by'][] = 'pm.subject'; - - // We can use tablesort_sql now, but we don't need the ORDER BY part of the query. - // Because of that, we need to cut off the first 9 characters of the generated string. - $order_by = drupal_substr(tablesort_sql(_privatemsg_list_headers( FALSE, array('subject', 'recipient', 'last_updated'))), 9); - $fragments['order_by'][] = $order_by; -} - -function privatemsg_sql_list(&$fragments, $account) { +function privatemsg_sql_list(&$fragments, $account, $argument = 'list') { $fragments['primary_table'] = '{pm_message} pm'; // Load enabled columns - $fields = array_filter(variable_get('privatemsg_display_fields', array('author'))); + $fields = array_filter(variable_get('privatemsg_display_fields', array('participants'))); // Required columns $fragments['select'][] = 'pmi.thread_id'; @@ -797,16 +755,17 @@ function privatemsg_sql_list(&$fragments, $account) { if (in_array('count', $fields)) { $fragments['select'][] = 'COUNT(pmi.thread_id) as count'; } - if (in_array('author', $fields)) { + if (in_array('participants', $fields)) { // Query for a string with uid's, for example "1,6,7". This needs a subquery on PostgreSQL. if ($GLOBALS['db_type'] == 'pgsql') { - $fragments['select'][] = "array_to_string(array(SELECT DISTINCT textin(int4out(pma.author)) - FROM {pm_message} pma - INNER JOIN pm_index pmia ON pma.mid = pmia.mid - WHERE pmia.thread_id = pmi.thread_id),',') AS author"; + $fragments['select'][] = "array_to_string(array(SELECT DISTINCT textin(int4out(pmia.uid)) + FROM {pm_index} pmia + WHERE pmia.thread_id = pmi.thread_id), ',') AS participants"; } else { - $fragments['select'][] = 'GROUP_CONCAT(DISTINCT author SEPARATOR ",") as author'; + $fragments['select'][] = '(SELECT GROUP_CONCAT(DISTINCT pmia.uid SEPARATOR ",") + FROM {pm_index} pmia + WHERE pmia.thread_id = pmi.thread_id) AS participants'; } } if (in_array('thread_started', $fields)) { @@ -1037,7 +996,6 @@ function _privatemsg_block_menu() { } if (privatemsg_user_access('read privatemsg') || privatemsg_user_access('read all private messages') ) { $links[] = l(privatemsg_title_callback(), 'messages'); - $links[] = l(t('Sent messages'), 'messages/sent'); } if ( count( $links ) ) { $block = array( @@ -1427,6 +1385,7 @@ function _privatemsg_assemble_query($query) { $INNER_JOIN = array(); $WHERE = array(); $GROUP_BY = array(); + $HAVING = array(); $ORDER_BY = array(); $QUERY_ARGS = array(); $primary_table = ''; @@ -1436,6 +1395,7 @@ function _privatemsg_assemble_query($query) { 'inner_join' => $INNER_JOIN, 'where' => $WHERE, 'group_by' => $GROUP_BY, + 'having' => $HAVING, 'order_by' => $ORDER_BY, 'query_args' => $QUERY_ARGS, 'primary_table' => $primary_table, @@ -1469,6 +1429,7 @@ function _privatemsg_assemble_query($query) { $INNER_JOIN = $fragments['inner_join']; $WHERE = $fragments['where']; $GROUP_BY = $fragments['group_by']; + $HAVING = $fragments['having']; $ORDER_BY = $fragments['order_by']; $QUERY_ARGS = $fragments['query_args']; $primary_table = $fragments['primary_table']; @@ -1509,6 +1470,14 @@ function _privatemsg_assemble_query($query) { $str_group_by = ' GROUP BY '. implode(", ", $GROUP_BY) ; $query .= " {$str_group_by}"; } + if (!empty($HAVING)) { + $str_having = '('. implode(') AND (', $HAVING) .')'; + $query .= " HAVING {$str_having}"; + // queries containing a HAVING break the count query on pgsql. + // In this case, use the subquery method as outlined in http://drupal.org/node/303087#comment-1370752 . + // The subquery method will work for all COUNT queries, but it is thought to be much slower, so we are only using it where other cross database approaches fail. + $count = 'SELECT COUNT(*) FROM ('. $query .') as count'; + } if (!empty($ORDER_BY)) { $str_order_by = ' ORDER BY '. implode(", ", $ORDER_BY) ; $query .= " {$str_order_by}"; diff --git a/privatemsg.theme.inc b/privatemsg.theme.inc index 6aff30653883546066d78f052bcdc9a546f25cb2..b7390aaa08c4937d0e5c3ee4d3747ddc856e1ac2 100644 --- a/privatemsg.theme.inc +++ b/privatemsg.theme.inc @@ -9,25 +9,14 @@ function theme_privatemsg_list_field($thread) { } -function phptemplate_privatemsg_list_field__author($thread) { - if (empty($thread['author'])) { +function phptemplate_privatemsg_list_field__participants($thread) { + if (empty($thread['participants'])) { return; } - $authors = _privatemsg_generate_user_array($thread['author']); + $participants = _privatemsg_generate_user_array($thread['participants']); $field = array(); - $field['data'] = _privatemsg_format_participants($authors, 3, TRUE); - $field['class'] = 'privatemsg-list-author'; - return $field; -} - -function phptemplate_privatemsg_list_field__recipient($thread) { - if (empty($thread['recipient'])) { - return; - } - $recipients = _privatemsg_generate_user_array($thread['recipient']); - $field = array(); - $field['data'] = _privatemsg_format_participants($recipients, 3, TRUE); - $field['class'] = 'privatemsg-list-recipient'; + $field['data'] = _privatemsg_format_participants($participants, 3, TRUE); + $field['class'] = 'privatemsg-list-participants'; return $field; } @@ -82,20 +71,11 @@ function phptemplate_privatemsg_list_header__count() { ); } -function phptemplate_privatemsg_list_header__author() { - return array( - 'data' => t('Authors'), - 'key' => 'author', - 'class' => 'privatemsg-header-authors', - '#weight' => -30, - ); -} - -function phptemplate_privatemsg_list_header__recipient() { +function phptemplate_privatemsg_list_header__participants() { return array( - 'data' => t('Recipients'), - 'key' => 'recipient', - 'class' => 'privatemsg-header-recipients', + 'data' => t('Participants'), + 'key' => 'participants', + 'class' => 'privatemsg-header-participants', '#weight' => -30, ); } diff --git a/privatemsg_filter/privatemsg_filter.module b/privatemsg_filter/privatemsg_filter.module index e571d35f5df0d69b7f3683cd131f6e0139a054b5..02c86514c7d61b1cdd043727492a24b9386dd579 100644 --- a/privatemsg_filter/privatemsg_filter.module +++ b/privatemsg_filter/privatemsg_filter.module @@ -36,6 +36,30 @@ function privatemsg_filter_menu() { 'access arguments' => array('administer privatemsg settings'), 'type' => MENU_LOCAL_TASK, ); + $items['messages/list/all'] = array( + 'title' => 'All messages', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('privatemsg_list', 'list'), + 'access callback' => 'privatemsg_user_access', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => -10, + ); + $items['messages/list/inbox'] = array( + 'title' => 'Inbox', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('privatemsg_list', 'inbox'), + 'access callback' => 'privatemsg_user_access', + 'type' => MENU_LOCAL_TASK, + 'weight' => -10, + ); + $items['messages/list/sent'] = array( + 'title' => 'Sent Messages', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('privatemsg_list', 'sent'), + 'access callback' => 'privatemsg_user_access', + 'type' => MENU_LOCAL_TASK, + 'weight' => -10, + ); return $items; } @@ -267,7 +291,7 @@ function privatemsg_filter_dropdown(&$form_state, $account) { $form['filter']['author'] = array( '#type' => 'select', - '#title' => t('Authors'), + '#title' => t('Users'), '#options' => privatemsg_filter_get_author_data($account), '#multiple' => TRUE, '#size' => 5, @@ -348,14 +372,14 @@ function privatemsg_filter_dropdown_submit($form, &$form_state) { $_SESSION['privatemsg_filter'] = $filter; break; case t('Filter'): - drupal_goto('messages', privatemsg_filter_create_get_query($form_state['values'])); + drupal_goto($_GET['q'], privatemsg_filter_create_get_query($form_state['values'])); return; break; case t('Reset'): $_SESSION['privatemsg_filter'] = array(); break; } - $form_state['redirect'] = 'messages'; + $form_state['redirect'] = $_GET['q']; } function privatemsg_filter_create_get_query($filter) @@ -416,12 +440,24 @@ function privatemsg_filter_form_privatemsg_list_alter(&$form, $form_state) { /** * Hook into the query builder to add the tagging info to the correct query */ -function privatemsg_filter_privatemsg_sql_list_alter(&$fragments, $account) { +function privatemsg_filter_privatemsg_sql_list_alter(&$fragments, $account, $argument) { + + // Check if its a filtered view. + if ($argument == 'sent') { + $fragments['where'][] = "pm.author = %d"; + $fragments['query_args'][] = $account->uid; + } + if ($argument == 'inbox') { + $fragments['select'][] = '(SELECT pmf.author FROM {pm_message} pmf WHERE pmf.mid = pmi.thread_id) AS first_author'; + $fragments['having'][] = '(first_author = %d AND COUNT(pmi.thread_id) > 1) OR first_author <> %d'; + $fragments['query_args'][] = $account->uid; + $fragments['query_args'][] = $account->uid; + } + // Filter the message listing by any set tags. if ($filter = privatemsg_filter_get_filter($account)) { - + $count = 0; if (isset($filter['tags']) && !empty($filter['tags'])) { - $count = 0; foreach ($filter['tags'] as $tag) { $fragments['inner_join'][] = "INNER JOIN {pm_tags_index} pmti$count ON (pmti$count.thread_id = pmi.thread_id AND pmti$count.uid = pmi.uid)"; $fragments['where'][] = "pmti$count.tag_id = %d"; @@ -431,10 +467,9 @@ function privatemsg_filter_privatemsg_sql_list_alter(&$fragments, $account) { } if (isset($filter['author']) && !empty($filter['author'])) { - $count = 0; foreach ($filter['author'] as $author) { - $fragments['inner_join'][] = "INNER JOIN {users} u$count ON (u$count.uid = pm.author)"; - $fragments['where'][] = "u$count.uid = %d"; + $fragments['inner_join'][] = "INNER JOIN {pm_index} pmi$count ON (pmi$count.mid = pm.mid)"; + $fragments['where'][] = "pmi$count.uid = %d"; $fragments['query_args'][] = $author; $count++; }