Index: privatemsg_filter.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/privatemsg/privatemsg_filter/privatemsg_filter.install,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 privatemsg_filter.install
--- privatemsg_filter.install 16 Apr 2009 20:10:35 -0000 1.1.2.2
+++ privatemsg_filter.install 24 Apr 2009 21:09:21 -0000
@@ -66,5 +66,13 @@
function privatemsg_filter_uninstall() {
variable_del('privatemsg_filter_searchbody');
+ variable_del('privatemsg_filter_tagfield_weight');
drupal_uninstall_schema('privatemsg_filter');
}
+
+function privatemsg_filter_update_6001() {
+ $ret = array();
+ $ret[] = update_sql("UPDATE {permission} SET perm = REPLACE(perm, 'use privatemsg_filter', 'filter private messages') WHERE perm LIKE '%use privatemsg_filter%'");
+ $ret[] = update_sql("UPDATE {permission} SET perm = REPLACE(perm, 'create privatemsg_filter', 'create private message tags') WHERE perm LIKE '%create privatemsg_filter%'");
+ return $ret;
+}
\ No newline at end of file
Index: privatemsg_filter.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/privatemsg/privatemsg_filter/privatemsg_filter.module,v
retrieving revision 1.1.2.15
diff -u -r1.1.2.15 privatemsg_filter.module
--- privatemsg_filter.module 22 Apr 2009 02:23:45 -0000 1.1.2.15
+++ privatemsg_filter.module 24 Apr 2009 21:14:32 -0000
@@ -11,9 +11,9 @@
*/
function privatemsg_filter_perm() {
return array(
- 'use privatemsg_filter',
- 'create privatemsg_filter',
- 'delete privatemsg_filter',
+ 'filter private messages',
+ 'tag private messages',
+ 'create private message tags',
);
}
@@ -21,13 +21,6 @@
* Implementation of hook_menu().
*/
function privatemsg_filter_menu() {
- $items['messages/tags'] = array(
- 'title' => 'Tags',
- 'page callback' => 'privatemsg_filter_page',
- 'access callback' => 'privatemsg_user_access',
- 'access arguments' => array('use privatemsg_filter'),
- 'type' => MENU_LOCAL_TASK,
- );
$items['admin/settings/messages/filter'] = array(
'title' => 'Filter',
'description' => 'Configure filter settings.',
@@ -60,6 +53,13 @@
'type' => MENU_LOCAL_TASK,
'weight' => -10,
);
+ $items['messages/filter/tag-autocomplete'] = array(
+ 'page callback' => 'privatemsg_filter_tags_autocomplete',
+ 'access callback' => 'privatemsg_user_access',
+ 'access arguments' => array('filter private messages'),
+ 'type' => MENU_CALLBACK,
+ 'weight' => -10,
+ );
return $items;
}
@@ -72,138 +72,24 @@
'#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),
);
-
- return system_settings_form($form);
-}
-
-function privatemsg_filter_page() {
- $content = '';
- drupal_set_title(t('Tags'));
-
- $sql = 'SELECT * FROM {pm_tags}';
- $query = db_query($sql);
- $tag_array = array();
-
- while ($result = db_fetch_object($query)) {
- $tag_array[] = l($result->tag, 'messages', array('query' => 'tags='. $result->tag));
- }
- if (count($tag_array)) {
- $content .= '
'. t('Current tags:') .'
';
- $content .= implode(', ', $tag_array) .'.';
- }
-
- if (privatemsg_user_access('create privatemsg_filter')) {
- $content .= drupal_get_form('privatemsg_filter_add_tags');
- }
- if (privatemsg_user_access('delete privatemsg_filter')) {
- $content .= drupal_get_form('privatemsg_filter_delete_tags');
- }
-
- return $content;
-}
-
-/**
- * Add new tags
- */
-function privatemsg_filter_add_tags($form_state) {
- $form['addtags'] = array(
- '#type' => 'fieldset',
- '#title' => t('Add tags'),
- '#collapsible' => TRUE,
- '#collapsed' => FALSE,
- );
-
- $form['addtags']['newtags'] = array(
- '#type' => 'textfield',
- '#title' => t('What tags would you like to add?'),
- '#description' => t('Please insert a comma separated list of new tags in the form of "tag1, tag2, tag3...". All spaces will be replaced by hyphens.'),
- '#default_value' => '',
- '#required' => 1,
- );
-
- $form['addtags']['submit'] = array(
- '#type' => 'submit',
- '#value' => t('Add tags'),
- );
-
-
- return $form;
-}
-
-function privatemsg_filter_add_tags_submit($form, &$form_state) {
-
- if (isset($form_state['values']['submit'])) {
- $tags = explode(',', $form_state['values']['newtags']);
-
- foreach ($tags as $tag) {
- $tag = trim($tag);
- $tag = str_replace(' ', '-', $tag);
- $count = db_result(db_query("SELECT COUNT(*) FROM {pm_tags} WHERE tag = '%s'", $tag));
- if ($count == 0) {
- db_query("INSERT INTO {pm_tags} (tag) VALUES ('%s')", $tag);
- $inserted[] = $tag;
- }
- }
- }
- if (count($inserted)) {
- drupal_set_message(t('!count tags have been saved: !tags.', array('!count' => count($inserted), '!tags' => implode(', ', $inserted))));
- }
-}
-
-/**
- * Delete existing tags
- */
-function privatemsg_filter_delete_tags($form_state) {
-
- $form['deletetags'] = array(
- '#type' => 'fieldset',
- '#title' => t('Delete tags'),
- '#collapsible' => TRUE,
- '#collapsed' => TRUE,
- );
-
- $sql = 'SELECT * FROM {pm_tags}';
- $query = db_query($sql);
- $tag_array = array();
-
- while ($result = db_fetch_object($query)) {
- $checked = 0;
- $form_data = array('#type' => 'checkbox', '#title' => $result->tag, '#default_value' => $checked, '#return_value' => 1);
- $form['deletetags']['tag_'. $result->tag_id] = $form_data;
- }
-
- $form['deletetags']['submit'] = array(
- '#type' => 'submit',
- '#value' => t('Delete selected tags'),
+
+ $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 $form;
-
-}
-
-function privatemsg_filter_delete_tags_submit($form, &$form_state) {
- if (isset($form_state['values']['submit'])) {
- $sql = 'SELECT * FROM {pm_tags}';
- $query = db_query($sql);
-
- while ($result = db_fetch_object($query)) {
- if ($form_state['values']['tag_'. $result->tag_id] == 1) {
- db_query('DELETE FROM {pm_tags_index} WHERE tag_id = %d', $result->tag_id);
- db_query('DELETE FROM {pm_tags} WHERE tag_id = %d', $result->tag_id);
- $deleted[] = $result->tag;
- }
- }
- }
- if (count($deleted)) {
- drupal_set_message(t('!count tags have been deleted: !tags.', array('!count' => count($deleted), '!tags' => implode(', ', $deleted))));
- }
+ return system_settings_form($form);
}
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) {
+ foreach (explode(',', $_GET['tags']) as $tag) {
if (isset($tag_data[$tag])) {
$filter['tags'][$tag] = $tag;
}
@@ -263,11 +149,11 @@
}
// Only show the tags that a user has used.
- $sql = 'SELECT pmt.tag, pmt.tag_id FROM {pm_tags_index} pmti LEFT JOIN {pm_tags} pmt ON pmti.tag_id = pmt.tag_id WHERE pmti.uid = %d GROUP BY pmt.tag_id, pmt.tag';
- $query = db_query($sql, $account->uid);
+ $query = _privatemsg_assemble_query(array('used_tags', 'privatemsg_filter'), $account);
+ $results = db_query($query['query']);
$tag_data = array();
- while ($result = db_fetch_object($query)) {
+ while ($result = db_fetch_object($results)) {
$tag_data[$result->tag_id] = $result->tag;
}
return $tag_data;
@@ -402,7 +288,7 @@
}
if (isset($query['tags'])) {
- $query['tags'] = implode(' ', $query['tags']);
+ $query['tags'] = implode(',', $query['tags']);
}
}
@@ -431,7 +317,7 @@
* Implementation of hook_form_alter().
*/
function privatemsg_filter_form_privatemsg_list_alter(&$form, $form_state) {
- if (privatemsg_user_access('use privatemsg_filter')) {
+ if (privatemsg_user_access('filter private messages')) {
$form += privatemsg_filter_dropdown($form_state, $form['#account']);
}
}
@@ -489,9 +375,9 @@
}
function privatemsg_filter_privatemsg_view_messages_alter(&$content, $thread) {
- if (count($thread['messages']) > 0 && db_result(db_query('SELECT COUNT(*) FROM {pm_tags}')) > 0) {
+ if (count($thread['messages']) > 0) {
$content['tags']['#value'] = drupal_get_form('privatemsg_filter_form');
- $content['tags']['#weight'] = 10;
+ $content['tags']['#weight'] = variable_get('privatemsg_filter_tagfield_weight', 10);
}
}
@@ -499,11 +385,21 @@
global $user;
$thread_id = arg(2);
+ // Get a list of current tags for this thread
+ $query = _privatemsg_assemble_query(array('used_tags', 'privatemsg_filter'), $user, $thread_id);
+ $results = db_query($query['query']);
+ $count = db_result(db_query($query['count']));
+ $tags = '';
+ while ($tag = db_fetch_array($results)) {
+ $tags .= $tag['tag']. ', ';
+ }
+
$form['tags'] = array(
'#type' => 'fieldset',
'#title' => t('Tags'),
+ '#access' => privatemsg_user_access('tag private messages'),
'#collapsible' => TRUE,
- '#collapsed' => TRUE,
+ '#collapsed' => empty($count) ? TRUE : FALSE,
);
$form['tags']['user_id'] = array(
'#type' => 'value',
@@ -513,19 +409,15 @@
'#type' => 'value',
'#value' => $thread_id,
);
-
- $sql = 'SELECT * FROM {pm_tags}';
- $query = db_query($sql);
- $tag_array = array();
-
- while ($result = db_fetch_object($query)) {
- $checked = 0;
- if (db_result(db_query('SELECT COUNT(*) FROM {pm_tags_index} WHERE tag_id = %d AND (uid = %d AND thread_id = %d)', $result->tag_id, $user->uid, $thread_id))) {
- $checked = 1;
- }
- $form_data = array('#type' => 'checkbox', '#title' => $result->tag, '#default_value' => $checked, '#return_value' => 1);
- $form['tags']['tag_'. $result->tag_id] = $form_data;
- }
+
+ $form['tags']['tags'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Tags for this conversation'),
+ '#description' => t('Separate multiple tags with commas.'),
+ '#size' => 50,
+ '#default_value' => $tags,
+ '#autocomplete_path' => 'messages/filter/tag-autocomplete',
+ );
$form['tags']['submit'] = array(
'#type' => 'submit',
@@ -538,17 +430,93 @@
function privatemsg_filter_form_submit($form, &$form_state) {
if (isset($form_state['values']['submit'])) {
- $sql = 'SELECT * FROM {pm_tags}';
- $query = db_query($sql);
-
- while ($result = db_fetch_object($query)) {
- if ($form_state['values']['tag_'. $result->tag_id] == 0) {
- db_query('DELETE FROM {pm_tags_index} WHERE tag_id = %d AND (uid = %d AND thread_id = %d)', $result->tag_id, $form_state['values']['user_id'], $form_state['values']['thread_id']);
- }
- elseif (db_result(db_query('SELECT COUNT(*) FROM {pm_tags_index} WHERE tag_id = %d AND (uid = %d AND thread_id = %d)', $result->tag_id, $form_state['values']['user_id'], $form_state['values']['thread_id'])) == 0) {
- db_query('INSERT INTO {pm_tags_index} (tag_id, uid, thread_id) VALUES (%d, %d, %d)', $result->tag_id, $form_state['values']['user_id'], $form_state['values']['thread_id']);
+ $tags = explode(',', $form_state['values']['tags']);
+
+ // Step 1 - Delete all tag mapping. I cannot think of a better way to remove tags that are no longer in the textfield, so ideas welcome.
+ db_query('DELETE FROM {pm_tags_index} WHERE uid = %d AND thread_id = %d', $form_state['values']['user_id'], $form_state['values']['thread_id']);
+
+ foreach ($tags as $tag) {
+ // Step 2 - We need to sanitise the tag.
+ // Since we allow tags to be passed via the url, there needs to be some sanity testing of each tag.
+ // Currently we replace blank spaces and a # with a "-", but this needs to be expanded to cover all the url special cases.
+ $tag = trim($tag);
+ if (empty($tag)) {
+ // Do not save a blank tag.
+ continue;
+ }
+
+ // Step 3 - Make sure that the tag exists and if it does not, we need to create it.
+ $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)) {
+ drupal_set_message(t('Tag %tag was ignored because you do not have permission to create new tags.', array('%tag' => $tag)));
+ continue;
+ }
+
+ // Step 4 - map the tag to the thread and the user.
+ db_query('INSERT INTO {pm_tags_index} (tag_id, uid, thread_id) VALUES (%d, %d, %d)', $tag_id, $form_state['values']['user_id'], $form_state['values']['thread_id']);
}
- drupal_set_message(t('Tagging information has been saved.'));
+
+ drupal_set_message(t('Tagging information has been saved.'));
+ }
+}
+
+/**
+ * Return autocomplete results for tags.
+ *
+ * Most of this code has been lifted/modified from privatemsg_user_name_autocomplete().
+ */
+function privatemsg_filter_tags_autocomplete($string) {
+ $tags = array();
+ // 1: Parse $string and build a list of tags.
+ $fragments = explode(',', $string);
+ foreach ($fragments as $index => $tag) {
+ $tag = trim($tag);
+ $tags[$tag] = $tag;
+ }
+
+ // 2: Find the next tag suggestion.
+ $fragment = array_pop($tags);
+ $matches = array();
+ if (!empty($fragment)) {
+ $query = _privatemsg_assemble_query(array('tags_autocomplete', 'privatemsg_filter'), $fragment, $tags);
+ $result = db_query_range($query['query'], $fragment, 0, 10);
+ $prefix = count($tags) ? implode(", ", $tags) .", " : '';
+ // 3: Build proper suggestions and print.
+ while ($tag = db_fetch_object($result)) {
+ $matches[$prefix . $tag->tag .", "] = $tag->tag;
+ }
+ }
+ // convert to object to prevent drupal bug, see http://drupal.org/node/175361
+ drupal_json((object)$matches);
+}
+
+function privatemsg_filter_sql_used_tags(&$fragments, $user, $thread_id = NULL) {
+ $fragments['primary_table'] = '{pm_tags} t';
+ $fragments['select'][] = 't.tag';
+ $fragments['select'][] = 't.tag_id';
+ $fragments['inner_join'][] = 'INNER JOIN {pm_tags_index} ti on ti.tag_id = t.tag_id';
+ if (!empty($thread_id)) {
+ $fragments['where'][] = 'ti.thread_id = %d';
+ $fragments['query_args']['where'][] = $thread_id;
+ }
+ $fragments['where'][] = 'ti.uid = %d';
+ $fragments['query_args']['where'][] = $user->uid;
+
+ $fragments['order_by'][] = 't.tag ASC';
+}
+
+function privatemsg_filter_sql_tags_autocomplete(&$fragments, $search, $tags) {
+ $fragments['primary_table'] = '{pm_tags} pmt';
+ $fragments['select'][] = 'pmt.tag';
+ $fragments['where'][] = "pmt.tag LIKE '%s'";
+ $fragments['query_args']['where'][] = $search .'%%';
+ if (!empty($tags)) {
+ $fragments['where'][] = "pmt.tag NOT IN (". db_placeholders($tags, 'text') .")";
+ $fragments['query_args']['where'] += $tags;
}
+ $fragments['order_by'][] = 'pmt.tag ASC';
}
\ No newline at end of file