summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Grossenbacher2009-10-14 14:12:43 (GMT)
committer Sascha Grossenbacher2009-10-14 14:12:43 (GMT)
commit6794baa14d26444e1821746c923aecc22fc1734a (patch)
tree5409bd3268ed6e370d3a69da0a1b29733e15621e
parentde0db33f24ea77b710b1d33c2785f5d8d95b1a2d (diff)
#444264 by nbz, Berdir | litwol: Added Add tagging actions to message listing.
-rw-r--r--privatemsg.module68
-rw-r--r--privatemsg_filter/privatemsg_filter.module189
2 files changed, 205 insertions, 52 deletions
diff --git a/privatemsg.module b/privatemsg.module
index 35f6cd6..aa9a438 100644
--- a/privatemsg.module
+++ b/privatemsg.module
@@ -2123,37 +2123,55 @@ function privatemsg_list_submit($form, &$form_state) {
$operation = $operations[$keys[1]];
}
+ // Only execute something if we have a valid callback and at least one checked thread.
+ if (!empty($operation['callback'])) {
+ privatemsg_operation_execute($operation, $form_state['values']['threads']);
+ }
+}
+
+/**
+ * Execute an operation on a number of threads.
+ *
+ * @param $operation
+ * The operation that should be executed.
+ * @see hook_privatemsg_thread_operations()
+ * @param $threads
+ * An array of thread ids. The array is filtered before used, a checkboxes
+ * array can be directly passed to it.
+ */
+function privatemsg_operation_execute($operation, $threads) {
// Filter out unchecked threads, this gives us an array of "checked" threads.
- $threads = array_filter($form_state['values']['threads']);
+ $threads = array_filter($threads);
+
+ if (empty($threads)) {
+ // Do not execute anything if there are no checked threads.
+ return;
+ }
+ // Add in callback arguments if present.
+ if (isset($operation['callback arguments'])) {
+ $args = array_merge(array($threads), $operation['callback arguments']);
+ }
+ else {
+ $args = array($threads);
+ }
+ // Execute the chosen action and pass the defined arguments.
+ call_user_func_array($operation['callback'], $args);
- // Only execute something if we have a valid callback and atleast one checked thread.
- if (!empty($operation['callback']) && !empty($threads)) {
+ // Check if that operation has defined an undo callback.
+ if (isset($operation['undo callback']) && $undo_function = $operation['undo callback']) {
// Add in callback arguments if present.
- if (isset($operation['callback arguments'])) {
- $args = array_merge(array($threads), $operation['callback arguments']);
+ if (isset($operation['undo callback arguments'])) {
+ $undo_args = array_merge(array($threads), $operation['undo callback arguments']);
}
else {
- $args = array($threads);
- }
- // Execute the chosen action and pass the defined arguments.
- call_user_func_array($operation['callback'], $args);
-
- // Check if that operation has defined a undo callback
- if (isset($operation['undo callback']) && $undo_function = $operation['undo callback']) {
- // Add in callback arguments if present.
- if (isset($operation['undo callback arguments'])) {
- $undo_args = array_merge(array($threads), $operation['undo callback arguments']);
- }
- else {
- $undo_args = array($threads);
- }
- // Store the undo callback in the session and display a "Undo" link.
- // @todo: Provide a more flexible solution for such an undo action, operation defined string for example.
- $_SESSION['privatemsg']['undo callback'] = array('function' => $undo_function, 'args' => $undo_args);
- $undo = l(t('undone'), 'messages/undo/action', array('query' => drupal_get_destination()));
-
- drupal_set_message(t('The previous action can be !undo.', array('!undo' => $undo)));
+ $undo_args = array($threads);
}
+ // Store the undo callback in the session and display a "Undo" link.
+ // @todo: Provide a more flexible solution for such an undo action, operation defined string for example.
+ $_SESSION['privatemsg']['undo callback'] = array('function' => $undo_function, 'args' => $undo_args);
+ $undo = url('messages/undo/action', array('query' => drupal_get_destination()));
+
+ drupal_set_message(t('The previous action can be <a href="!undo">undone</a>.', array('!undo' => $undo)));
}
}
diff --git a/privatemsg_filter/privatemsg_filter.module b/privatemsg_filter/privatemsg_filter.module
index 69ab2b7..47190ce 100644
--- a/privatemsg_filter/privatemsg_filter.module
+++ b/privatemsg_filter/privatemsg_filter.module
@@ -120,6 +120,94 @@ function privatemsg_filter_settings_submit($form, &$form_state) {
}
}
+/**
+ * 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, $user->uid, $thread)) == 0) {
+ db_query('INSERT INTO {pm_tags_index} (tag_id, uid, thread_id) VALUES (%d, %d, %d)', $tag_id, $user->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'])) {
@@ -337,11 +425,76 @@ function privatemsg_filter_create_get_query($filter)
* Implementation of hook_form_FORM_ID_alter() to add 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')) {
$form += privatemsg_filter_dropdown($form_state, $form['#account']);
}
+
+ $tags = privatemsg_filter_get_tags_data($user);
+ if (privatemsg_user_access('filter private messages') && !empty($tags)) {
+ $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,
+ // Execute the submit button if a operation has been selected.
+ '#attributes' => array('onchange' => "$('#edit-tag-add-submit').click()"),
+ );
+ $form['actions']['tag-add-submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Apply Tag'),
+ '#submit' => array('privatemsg_filter_add_tag_submit'),
+ '#attributes' => array('class' => 'privatemsg-action-button'),
+ );
+ $options[0] = t('Remove Tag...');
+ $form['actions']['tag-remove'] = array(
+ '#type' => 'select',
+ '#options' => $options,
+ '#default_value' => 0,
+ // Execute the submit button if a operation has been selected.
+ '#attributes' => array('onchange' => "$('#edit-tag-remove-submit').click()"),
+ );
+ $form['actions']['tag-remove-submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Remove Tag'),
+ '#submit' => array('privatemsg_filter_remove_tag_submit'),
+ '#attributes' => array('class' => 'privatemsg-action-button'),
+ );
+ }
}
+/**
+ * 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']);
+}
/**
* Hook into the query builder to add the tagging info to the correct query
@@ -459,34 +612,16 @@ function privatemsg_filter_form_submit($form, &$form_state) {
$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)) {
- // 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;
- }
-
- // 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']);
+ privatemsg_filter_remove_tags($form_state['values']['thread_id']);
+
+ // Step 2 - Get the id for each of the tags.
+ $tag_ids = privatemsg_filter_create_tags($tags);
+
+ // Step 3 - Save all the tagging data.
+ foreach ($tag_ids as $tag_id) {
+ privatemsg_filter_add_tags($form_state['values']['thread_id'], $tag_ids);
}
- drupal_set_message(t('Tagging information has been saved.'));
+ drupal_set_message(t('Tagging information has been saved.'));
}
}