'{pm_tags} holds the names of tags and their id.', 'fields' => array( 'tag_id' => array( 'description' => 'Tag ID', 'type' => 'serial', 'not null' => TRUE, 'unsigned' => TRUE, ), 'tag' => array( 'description' => 'The name of the tag', 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, ), 'public' => array( 'description' => 'Defines if a tag is public (visible for all users)', 'type' => 'int', 'unsigned' => TRUE, 'size' => 'tiny', 'default' => 0, ), 'hidden' => array( 'type' => 'int', 'description' => 'Defines if a tag should not be displayed and is usually automatically managed', 'unsigned' => TRUE, 'size' => 'tiny', 'default' => 0, ) ), 'primary key' => array('tag_id'), 'indexes' => array( 'tag_list' => array('tag_id', 'tag', 'public'), ), ); $schema['pm_tags_index'] = array( 'description' => '{pm_tags_index} holds mapping information between tags, threads the users.', 'fields' => array( 'tag_id' => array( 'description' => 'Tag ID', 'type' => 'int', 'not null' => TRUE, 'unsigned' => TRUE, ), 'uid' => array( 'description' => 'ID of the user', 'type' => 'int', 'not null' => TRUE, 'unsigned' => TRUE, ), 'thread_id' => array( 'description' => 'id of the thread', 'type' => 'int', 'not null' => TRUE, 'unsigned' => TRUE, ), ), 'primary key' => array('tag_id', 'uid', 'thread_id'), 'indexes' => array( 'thread_tags' => array('uid', 'thread_id'), ), ); return $schema; } /** * 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'); } /** * Implements hook_enable(). */ function privatemsg_filter_enable() { if (!($tag_id = variable_get('privatemsg_filter_inbox_tag', '')) || db_query('SELECT 1 FROM {pm_tags} WHERE tag_id = :tag_id', array(':tag_id' => $tag_id))->fetchField()) { $tag_id = db_insert('pm_tags') ->fields(array( 'tag' => 'Inbox', 'hidden' => 1, )) ->execute(); variable_set('privatemsg_filter_inbox_tag', $tag_id); } drupal_set_message(t('Visit Rebuild Inbox to tag existing messages to show up in the inbox.', array('!rebuild_url' => url('admin/config/messaging/privatemsg/tags/rebuild')))); } /** * Add hidden flag and create inbox tag. */ function privatemsg_filter_update_7000() { if (!db_field_exists('pm_tags', 'hidden')) { db_add_field('pm_tags', 'hidden', array( 'description' => 'Defines if a tag should not be displayed and is usually automatically managed', 'type' => 'int', 'unsigned' => TRUE, 'size' => 'tiny', 'default' => 0, )); } if (!($tag_id = variable_get('privatemsg_filter_inbox_tag', '')) || (!db_query('SELECT 1 FROM {pm_tags} WHERE tag_id = :tag_id', array(':tag_id' => $tag_id))->fetchField())) { $tag_id = db_insert('pm_tags') ->fields(array( 'tag' => 'Inbox', 'hidden' => 1, )) ->execute(); variable_set('privatemsg_filter_inbox_tag', $tag_id); } } /** * Add inbox tag to existing inbox messages. */ function privatemsg_filter_update_7001(&$sandbox) { // First run, initialize sandbox. if (!isset($sandbox['current_thread_id'])) { // If the sandbox is not initialized, check if there are any threads tagged // with the inbox tag. If yes, the update did already run. if (db_query_range('SELECT 1 FROM {pm_tags_index} WHERE tag_id = :tag_id', 0, 1, array(':tag_id' => variable_get('privatemsg_filter_inbox_tag', 0)))->fetchField()) { return; } $sandbox['current_thread_id'] = 0; // Assume that the thread ids are distributed more or less equally over the // whole data set. This allows us to calculate the approximate progress. $sandbox['max'] = db_query('SELECT MAX(thread_id) FROM {pm_index}')->fetchField(); } // There is no way to know if this update is run before or after // privatemsg_update_update_6201() which renames uid to recipient. $uid_column = 'uid'; if (db_field_exists('pm_index', 'recipient')) { $uid_column = 'recipient'; } // Fetch the 10 next thread_ids. $result = db_query_range('SELECT DISTINCT thread_id FROM {pm_index} WHERE thread_id > :thread_id ORDER BY thread_id ASC', 0, 20, array('thread_id' => $sandbox['current_thread_id'])); $threads = $result->fetchCol(); $inbox_tag = variable_get('privatemsg_filter_inbox_tag', ''); if (!empty($threads)) { // By limiting this slow query (having condition with 2 depending subqueries) // on a specific set of threads, this allows us to process the slow having // part on a relatively small subset of pm_index that can be selected based on // the thread_id index. $sql = 'SELECT pmi.thread_id, pmi.' . $uid_column . ' AS uid FROM {pm_index} pmi WHERE thread_id IN (:threads) GROUP BY pmi.thread_id, pmi.' . $uid_column . ' HAVING ((SELECT pmf.author FROM {pm_message} pmf WHERE pmf.mid = pmi.thread_id) = pmi.' . $uid_column . ' 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_column . ') > 0'; $result = db_query($sql, array(':threads' => $threads)); foreach ($result as $row) { // Make sure that we don't add a tag to a thread twice, // only insert if there is no such tag yet. // We duplicate privatemsg_filter_add_tags() here in case // privatemsg_filter.module is disabled and therefore not loaded. $exists = db_query('SELECT 1 FROM {pm_tags_index} WHERE tag_id = :tag_id AND (uid = :uid AND thread_id = :thread_id)', array(':tag_id' => $inbox_tag, ':uid' => $row->uid, ':thread_id' => $row->thread_id))->fetchField(); if (!$exists) { db_insert('pm_tags_index') ->fields(array( 'tag_id' => $inbox_tag, 'uid' => $row->uid, 'thread_id' => $row->thread_id, )) ->execute(); } } $sandbox['current_thread_id'] = max($threads); } // Set #finished based on sandbox. $sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['current_thread_id'] / $sandbox['max']); }