'Filter', 'description' => 'Configure filter settings.', 'page callback' => 'drupal_get_form', 'page arguments' => array('privatemsg_filter_admin'), 'access arguments' => array('administer privatemsg settings'), 'type' => MENU_LOCAL_TASK, ); $items['admin/settings/messages/tags'] = array( 'title' => 'Tags', 'description' => 'Configure tags.', 'page callback' => 'privatemsg_tags_admin', 'access arguments' => array('administer privatemsg settings'), 'type' => MENU_LOCAL_TASK, 'file' => 'privatemsg_filter.admin.inc', ); $items['admin/settings/messages/tags/list'] = array( 'title' => 'List', 'description' => 'Configure tags.', 'page callback' => 'privatemsg_tags_admin', 'access arguments' => array('administer privatemsg settings'), 'type' => MENU_DEFAULT_LOCAL_TASK, 'file' => 'privatemsg_filter.admin.inc', 'weight' => -10, ); $items['admin/settings/messages/tags/add'] = array( 'title' => 'Add', 'description' => 'Configure tags.', 'page callback' => 'drupal_get_form', 'page arguments' => array('privatemsg_tags_form'), 'access arguments' => array('administer privatemsg settings'), 'type' => MENU_LOCAL_TASK, 'file' => 'privatemsg_filter.admin.inc', ); $items['admin/settings/messages/tags/edit/%'] = array( 'title' => 'Add', 'description' => 'Configure tags.', 'page callback' => 'drupal_get_form', 'page arguments' => array('privatemsg_tags_form', 5), 'access arguments' => array('administer privatemsg settings'), 'type' => MENU_CALLBACK, 'file' => 'privatemsg_filter.admin.inc', ); $items['admin/settings/messages/tags/delete/%'] = array( 'title' => 'Add', 'description' => 'Configure tags.', 'page callback' => 'drupal_get_form', 'page arguments' => array('privatemsg_filter_tags_delete', 5), 'access arguments' => array('administer privatemsg settings'), 'type' => MENU_CALLBACK, 'file' => 'privatemsg_filter.admin.inc', ); $items['messages/inbox'] = array( 'title' => 'Inbox', 'page callback' => 'drupal_get_form', 'page arguments' => array('privatemsg_list', 'inbox'), 'access callback' => 'privatemsg_user_access', 'type' => variable_get('privatemsg_filter_default_list', 0) ? MENU_LOCAL_TASK : MENU_DEFAULT_LOCAL_TASK, 'weight' => -15, ); $items['messages/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' => -12, ); $items['messages/filter/user-name-autocomplete'] = array( 'page callback' => 'privatemsg_user_name_autocomplete', 'access callback' => 'privatemsg_user_access', 'access arguments' => array('write privatemsg'), 'type' => MENU_CALLBACK, ); $items['messages/filter/tag-autocomplete'] = array( 'page callback' => 'privatemsg_filter_tags_autocomplete', 'access callback' => 'privatemsg_user_access', 'access arguments' => array('tag private messages'), 'type' => MENU_CALLBACK, 'weight' => -10, ); return $items; } /** * Implements hook_menu_alter(). */ function privatemsg_filter_menu_alter(&$items) { // Rename messages to "All messages". $items['messages/list']['title'] = 'All messages'; if (variable_get('privatemsg_filter_default_list', 0) == 0) { // Change default argument of /messages to inbox. and set the task to MENU_LOCAL_TASK. $items['messages']['page arguments'] = array('privatemsg_list', 'inbox'); $items['messages/list']['type'] = MENU_LOCAL_TASK; } } function privatemsg_filter_admin() { $form = array(); $form['privatemsg_filter_searchbody'] = array( '#type' => 'checkbox', '#title' => t('Search message body'), '#description' => t('WARNING: turning on this feature will slow down search performance by a large factor. Gets worse as your messages database increases.'), '#default_value' => variable_get('privatemsg_filter_searchbody', FALSE), ); $form['privatemsg_filter_tagfield_weight'] = array( '#type' => 'textfield', '#title' => t('Position of the tagging textfield'), '#description' => t('Use higher values to push the form lower down the page, lower or negative values to raise it higher.'), '#size' => 4, '#default_value' => variable_get('privatemsg_filter_tagfield_weight', 10), ); return system_settings_form($form); } /** * Implements hook_form_FORM_ID_alter(). * * Add a filter widget to the message listing pages. */ function privatemsg_filter_form_private_message_settings_alter(&$form, $form_state) { $form['privatemsg_listing']['privatemsg_filter_default_list'] = array( '#type' => 'radios', '#default_value' => variable_get('privatemsg_filter_default_list', 0), '#options' => array(t('Inbox'), t('All messages')), '#title' => t('Choose the default list option'), '#description' => t('Choose which of the two lists are shown by default when following the messages link.'), ); // Add tags to the list of possible columns. $form['privatemsg_listing']['privatemsg_display_fields']['#options']['tags'] = t('Tags'); $form['#submit'][] = 'privatemsg_filter_settings_submit'; } /** * Rebuilding the menu if necessary. */ function privatemsg_filter_settings_submit($form, &$form_state) { if ($form['privatemsg_listing']['privatemsg_filter_default_list']['#default_value'] != $form_state['values']['privatemsg_filter_default_list']) { menu_rebuild(); } } /** * Function to create a tag * * @param $tags * A single tag or an array of tags. */ function privatemsg_filter_create_tags($tags) { if (!is_array($tags)) { $tags = array($tags); } $tag_ids = array(); foreach ($tags as $tag) { $tag = trim($tag); if (empty($tag)) { // Do not save a blank tag. continue; } // Check if the tag already exists and only create the tag if it does not. $tag_id = db_result(db_query("SELECT tag_id FROM {pm_tags} WHERE tag = '%s'", $tag)); if (empty($tag_id) && privatemsg_user_access('create private message tags')) { db_query("INSERT INTO {pm_tags} (tag) VALUES ('%s')", $tag); $tag_id = db_last_insert_id('pm_tags', 'tag_id'); } elseif (empty($tag_id)) { // The user does not have permission to create new tags - disregard this tag and move onto the next. drupal_set_message(t('Tag %tag was ignored because you do not have permission to create new tags.', array('%tag' => $tag))); continue; } $tag_ids[] = $tag_id; } return $tag_ids; } /** * Tag one or multiple threads with a tag. * * @param $threads * A single thread id or an array of thread ids. * @param $tag_id * Id of the tag. */ function privatemsg_filter_add_tags($threads, $tag_id, $account = NULL) { if (!is_array($threads)) { $threads = array($threads); } if (empty($account)) { global $user; $account = drupal_clone($user); } foreach ($threads as $thread) { // Make sure that we don't add a tag to a thread twice, // only insert if there is no such tag yet. if (db_result(db_query('SELECT COUNT(*) FROM {pm_tags_index} WHERE tag_id = %d AND (uid = %d AND thread_id = %d)', $tag_id, $account->uid, $thread)) == 0) { db_query('INSERT INTO {pm_tags_index} (tag_id, uid, thread_id) VALUES (%d, %d, %d)', $tag_id, $account->uid, $thread); } } } /** * Remove tag from one or multiple threads. * * @param $threads * A single thread id or an array of thread ids. * @param $tag_id * Id of the tag - set to NULL to remove all tags. */ function privatemsg_filter_remove_tags($threads, $tag_id = NULL, $account = NULL) { if (!is_array($threads)) { $threads = array($threads); } if (empty($account)) { global $user; $account = drupal_clone($user); } if (is_null($tag_id)) { // Delete all tag mapping. foreach ($threads as $thread) { db_query('DELETE FROM {pm_tags_index} WHERE uid = %d AND thread_id = %d', $account->uid, $thread); } } else { // Delete tag mapping for the specified tag. foreach ($threads as $thread) { db_query('DELETE FROM {pm_tags_index} WHERE uid = %d AND thread_id = %d AND tag_id = %d', $account->uid, $thread, $tag_id); } } } function privatemsg_filter_get_filter($account) { $filter = array(); if (isset($_GET['tags'])) { $_GET['tags'] = urldecode($_GET['tags']); $tag_data = privatemsg_filter_get_tags_data($account); foreach (explode(',', $_GET['tags']) as $tag) { if (isset($tag_data[$tag])) { $filter['tags'][$tag] = $tag; } elseif (in_array($tag, $tag_data)) { $filter['tags'][array_search($tag, $tag_data)] = array_search($tag, $tag_data); } } } if (isset($_GET['author'])) { list($filter['author']) = _privatemsg_parse_userstring($_GET['author']); } if (isset($_GET['search'])) { $filter['search'] = $_GET['search']; } if (!empty($filter)) { return $filter; } if (!empty($_SESSION['privatemsg_filter'])) { return $_SESSION['privatemsg_filter']; } } function privatemsg_filter_get_tags_data($account) { static $tag_data; if (is_array($tag_data)) { return $tag_data; } // Only show the tags that a user have used. $query = _privatemsg_assemble_query(array('tags', 'privatemsg_filter'), $account); $results = db_query($query['query']); $tag_data = array(); while ($result = db_fetch_object($results)) { $tag_data[$result->tag_id] = $result->tag; } return $tag_data; } function privatemsg_filter_dropdown(&$form_state, $account) { drupal_add_css(drupal_get_path('module', 'privatemsg_filter') .'/privatemsg_filter.css'); $form['filter'] = array( '#type' => 'fieldset', '#title' => t('Filter messages'), '#collapsible' => TRUE, '#collapsed' => TRUE, ); $form['filter']['search'] = array( '#type' => 'textfield', '#title' => variable_get('privatemsg_filter_searchbody', FALSE) ? t('Search messages') : t('Search subjects'), '#weight' => -20 ); $form['filter']['author'] = array( '#type' => 'textfield', '#title' => t('Participants'), '#description' => t('Separate multiple names with commas.'), '#weight' => -5, '#size' => 50, '#autocomplete_path' => 'messages/filter/user-name-autocomplete', ); // Only show form if the user has some messages tagged. if (count($tag_data = privatemsg_filter_get_tags_data($account))) { $form['filter']['tags'] = array( '#type' => 'select', '#title' => t('Tags'), '#options' => $tag_data, '#multiple' => TRUE, '#size' => 5, '#weight' => 0 ); } $form['filter']['submit'] = array( '#type' => 'submit', '#value' => t('Filter'), '#prefix' => '
', '#weight' => 11, '#submit' => array('privatemsg_filter_dropdown_submit'), ); if ($filter = privatemsg_filter_get_filter($account)) { privatemsg_filter_dropdown_set_active($form, $filter); } return $form; } function privatemsg_filter_dropdown_set_active(&$form, $filter) { $form['filter']['#title'] = t('Filter messages (active)'); $form['filter']['#collapsed'] = FALSE; if (isset($filter['author'])) { $string = ''; foreach ($filter['author'] as $author) { $string .= $author->name . ', '; } $form['filter']['author']['#default_value'] = $string; } if (isset($filter['tags'])) { $form['filter']['tags']['#default_value'] = $filter['tags']; } if (isset($filter['search'])) { $form['filter']['search']['#default_value'] = $filter['search']; } $form['filter']['reset'] = array( '#type' => 'submit', '#value' => t('Reset'), '#suffix' => '', '#weight' => 12, '#submit' => array('privatemsg_filter_dropdown_submit'), ); unset($form['filter']['save']['#suffix']); } function privatemsg_filter_dropdown_submit($form, &$form_state) { if (!empty($form_state['values']['author'])) { list($form_state['values']['author']) = _privatemsg_parse_userstring($form_state['values']['author']); } switch ($form_state['values']['op']) { case t('Save filter'): $filter = array(); if (!empty($form_state['values']['tags'])) { $filter['tags'] = $form_state['values']['tags']; } if (!empty($form_state['values']['author'])) { $filter['author'] = $form_state['values']['author']; } if (!empty($form_state['values']['search'])) { $filter['search'] = $form_state['values']['search']; } $_SESSION['privatemsg_filter'] = $filter; break; case t('Filter'): 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'] = $_GET['q']; } function privatemsg_filter_create_get_query($filter) { $query = array(); if (isset($filter['tags']) && !empty($filter['tags'])) { $ids = array(); foreach ($filter['tags'] as $tag) { if ((int)$tag > 0) { $ids[] = $tag; } else { $query['tags'][] = $tag; } } $sql = 'SELECT pmt.tag FROM {pm_tags} pmt WHERE pmt.tag_id IN ('. implode(', ', $filter['tags']) .')'; $result = db_query($sql); while ($row = db_fetch_object($result)) { $query['tags'][] = $row->tag; } if (isset($query['tags'])) { $query['tags'] = implode(',', $query['tags']); } } if (isset($filter['author']) && !empty($filter['author'])) { foreach ($filter['author'] as $author) { if (is_object($author) && isset($author->uid) && isset($author->name)) { $query['author'][] = $author->name; } elseif ($author_obj = user_load($author)) { $query['author'][] = $author_obj->name; } } if (isset($query['author'])) { $query['author'] = implode(',', $query['author']); } } if (isset($filter['search']) && !empty($filter['search'])) { $query['search'] = $filter['search']; } return $query; } /** * Implements hook_form_FORM_ID_alter(). * * Adds a filter widget to the message listing pages. */ function privatemsg_filter_form_privatemsg_list_alter(&$form, $form_state) { global $user; if (privatemsg_user_access('filter private messages') && !empty($form['#data'])) { $form += privatemsg_filter_dropdown($form_state, $form['#account']); } $fields = array_filter(variable_get('privatemsg_display_fields', array('participants'))); if (in_array('tags', $fields)) { // Load thread id's of the current list. $threads = array_keys($form['#data']); // Fetch all tags of those threads. $query = _privatemsg_assemble_query(array('tags', 'privatemsg_filter'), $user, $threads, 3); // Add them to #data $result = db_query($query['query']); while ($tag = db_fetch_array($result)) { $form['#data'][$tag['thread_id']]['tags'][$tag['tag_id']] = $tag['tag']; } } $tags = privatemsg_filter_get_tags_data($user); if (privatemsg_user_access('tag private messages') && !empty($tags) && !empty($form['#data'])) { $options = array(); $options[] = t('Apply tag...'); foreach ($tags as $tag_id => $tag) { $options[$tag_id] = $tag; } $form['actions']['tag-add'] = array( '#type' => 'select', '#options' => $options, '#default_value' => 0, ); $form['actions']['tag-add-submit'] = array( '#prefix' => '