Index: community_tags.install =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/community_tags/community_tags.install,v retrieving revision 1.9 diff -u -p -r1.9 community_tags.install --- community_tags.install 18 Jul 2008 03:32:55 -0000 1.9 +++ community_tags.install 18 Oct 2010 16:55:32 -0000 @@ -12,7 +12,7 @@ function community_tags_install() { // Install schema drupal_install_schema('community_tags'); - + // Drop module weight so we act after taxonomy. $weight = (int)db_result(db_query("SELECT weight FROM {system} WHERE name = 'taxonomy'")); db_query("UPDATE {system} SET weight = %d WHERE name = 'community_tags'", $weight + 1); Index: community_tags.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/community_tags/community_tags.module,v retrieving revision 1.37.2.11 diff -u -p -r1.37.2.11 community_tags.module --- community_tags.module 14 May 2010 05:00:10 -0000 1.37.2.11 +++ community_tags.module 18 Oct 2010 16:55:33 -0000 @@ -35,7 +35,7 @@ function community_tags_theme() { ), 'community_tags' => array( 'arguments' => array('tags' => NULL), - ), + ), ); } @@ -59,9 +59,9 @@ function community_tags_menu() { 'page arguments' => array(2), 'access callback' => '_community_tags_menu_access', 'type' => MENU_CALLBACK, - 'file' => 'community_tags.ajax.inc', + 'file' => 'community_tags.ajax.inc', ); - + $items['community-tags/user'] = array( 'page callback' => 'community_tags_by_user', 'access callback' => '_community_tags_menu_access', @@ -260,6 +260,9 @@ function community_tags_get_user_node_ta $tags[$term->tid] = $term; } + // allow other modules to have a say + drupal_alter('community_tags_get_user_node_tags', $tags, $uid, $nid); + return $tags; } @@ -292,11 +295,15 @@ function community_tags_taxonomy_node_sa if (isset($terms['tags'])) { $typed_input = $terms['tags']; unset($terms['tags']); - + foreach ($typed_input as $vid=>$vid_value) { if (isset($community_tagged[$vid])) { $typed_terms = is_array($vid_value)?$vid_value:drupal_explode_tags($vid_value); + + // allow other modules to alter the terms + drupal_alter('community_tags_terms', $typed_terms, $vid, $node, $is_owner, $uid); + foreach ($typed_terms as $typed_term) { // See if the term exists in the chosen vocabulary // and return the tid, otherwise, add a new record. @@ -307,21 +314,21 @@ function community_tags_taxonomy_node_sa $typed_term_tid = $possibility->tid; } } - + if (!$typed_term_tid) { $edit = array ('vid'=>$vid, 'name'=>$typed_term); $status = taxonomy_save_term($edit); $typed_term_tid = $edit['tid']; - + // Add only new terms to return value $tids[$typed_term_tid] = $typed_term; } - + // If we already added this term in this cycle, skip this duplicate. if ( isset ($inserted_tids[$typed_term_tid])) { continue ; } - + // If there was an existing tag by this user, load that data. $tag_node = new stdClass (); $tag_node->tid = $typed_term_tid; @@ -329,7 +336,7 @@ function community_tags_taxonomy_node_sa $tag_node->uid = $uid; $tag_node->date = time(); $tag_node->vid = $node->vid; - + // So we don't add this tag again on this run or re-insert the old tag for this user. $inserted_tids[$typed_term_tid] = $typed_term_tid; $tag_nodes[] = $tag_node; @@ -392,7 +399,7 @@ function community_tags_taxonomy_node_sa db_query('DELETE FROM {term_node} WHERE nid = %d AND tid = %d', $tag->nid, $tag->tid); } } - + // Force re-indexing to include new tags in the search index. if (module_exists('search')) { search_touch_node($node->nid); @@ -478,13 +485,13 @@ function community_tags_node_view($node, $tags = community_tags_get_user_node_tags($user->uid, $node->nid); $names = array(); $output = ''; - + module_load_include('inc', 'community_tags', 'community_tags.pages'); if (!count($tags)) { // User has not yet added tags to this node yet. Show form. $output .= drupal_get_form('community_tags_form', array('node' => $node, 'cloud' => $cloud, 'nid' => $node->nid, 'vid' => $vid, 'tags' => NULL, 'inline' => $inline)); - } + } elseif (user_access('edit own tags')) { // User has already tagged this node, but can edit their tags. Show form // with the user's tags pre-populated. Index: contrib/community_tags_unitag/community_tags_unitag.info =================================================================== RCS file: contrib/community_tags_unitag/community_tags_unitag.info diff -N contrib/community_tags_unitag/community_tags_unitag.info --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/community_tags_unitag/community_tags_unitag.info 18 Oct 2010 16:55:33 -0000 @@ -0,0 +1,7 @@ +; $Id$ +name = Community Tags Unitag +description = "Integrates community tags with unitag." +dependencies[] = community_tags +dependencies[] = unitag +package = "Taxonomy" +core=6.x \ No newline at end of file Index: contrib/community_tags_unitag/community_tags_unitag.install =================================================================== RCS file: contrib/community_tags_unitag/community_tags_unitag.install diff -N contrib/community_tags_unitag/community_tags_unitag.install --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/community_tags_unitag/community_tags_unitag.install 18 Oct 2010 16:55:33 -0000 @@ -0,0 +1,51 @@ + array( + 'basename' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''), + 'name' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''), + 'nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0), + 'uid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0), + 'vid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0), + 'date' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0), + ), + 'indexes' => array( + 'basename' => array('basename'), + 'nid' => array('nid'), + 'uid' => array('uid'), + 'vid' => array('vid'), + ), + 'primary key' => array('basename', 'uid', 'nid', 'vid'), + ); + return $schema; +} Index: contrib/community_tags_unitag/community_tags_unitag.module =================================================================== RCS file: contrib/community_tags_unitag/community_tags_unitag.module diff -N contrib/community_tags_unitag/community_tags_unitag.module --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/community_tags_unitag/community_tags_unitag.module 18 Oct 2010 16:55:33 -0000 @@ -0,0 +1,163 @@ +unitag_suggestions + */ +function community_tags_unitag_community_tags_terms_alter(&$terms, $vid, $node, $is_owner, $uid) { + if (isset($node->unitag_suggestions)) { + // node edit form mode - terms are correct but we need to record unitag suggestions against this user + _community_tags_unitag_save_unitag_suggestions($node->unitag_suggestions[$vid], $node, $uid, $vid); + } + else { + // CT ajax mode - have to replicate functionailty of unitag node edit form submission + + // get terms back in the format required by unitag + $term_str = drupal_implode_tags($terms); + + // get unitag to do it's thing + $unitag_result = unitag_taxonomy_terms_resolve_tags($vid, $term_str); + + // replace terms to be processed by community tags with ones allowed by unitag + $terms = $unitag_result['parsed']; + + if (!empty($unitag_result['new'])) { + // save nodes as unitag suggestions + foreach ($unitag_result['new'] as $suggestion) { + unitag_suggestion_save($node->nid, $vid, $suggestion); + } + + // cleanup old suggestions + _community_tags_unitag_cleanup_existing_suggestions_unique_to_user($unitag_result['new'], $node->nid, $uid, $vid); + + // record unitag suggestions against this user + _community_tags_unitag_save_unitag_suggestions($unitag_result['new'], $node, $uid, $vid); + } + } +} + +/** + * Implementation of hook_community_tags_get_user_node_tags_alter(). Adds + * users tags that are waiting for moderation and aren't yet terms. + */ +function community_tags_unitag_community_tags_get_user_node_tags_alter(&$tags, $uid, $nid) { + $query = db_query("SELECT basename as tid, name, uid, nid FROM {community_tags_unitag} WHERE nid = %d AND uid = %d", $nid, $uid); + while ($row = db_fetch_object($query)) { + // obviously not a tid but it's a unique identifier for the associative array of users tags. + $tags[$row->tid] = $row; + } +} + +/** + * Any existing CT unitag suggestions that aren't in the up to date list of suggestions + * for the user/node combination (i.e. have been removed by the user) and have not + * been suggested by another user should be removed from unitag moderation queue. + */ +function _community_tags_unitag_cleanup_existing_suggestions_unique_to_user($unitag_suggestions, $nid, $uid, $vid) { + $basenames = array(); + foreach ($unitag_suggestions as $suggestion) { + $basenames[] = _unitag_get_basename($suggestion); + } + + // query to get existing suggestions for this node that are unique to this user. + $query = db_query( + "SELECT ctu.* FROM {community_tags_unitag} ctu + LEFT JOIN (SELECT count(*) AS others, nid, basename, uid, vid FROM {community_tags_unitag} GROUP BY nid, basename, uid, vid) ctu2 ON ctu2.nid = ctu.nid AND ctu2.basename = ctu.basename AND ctu2.vid = ctu.vid AND ctu2.uid <> ctu.uid + WHERE ctu.nid = %d AND ctu.uid = %d AND ctu.vid = %d AND ctu2.others IS NULL AND ctu.basename NOT IN (" . db_placeholders($basenames, 'varchar') . ")", array_merge(array($nid, $uid, $vid), $basenames)); + + while ($row = db_fetch_object($query)) { + // remove this from unitag processing + unitag_suggestion_delete($row, TRUE); + } +} + +/** + * Save suggestions with against node and user. Delete first as will be supplied complete + * up to date list of suggestions. + */ +function _community_tags_unitag_save_unitag_suggestions($unitag_suggestions, $node, $uid, $vid) { + // Insert new suggestions + db_lock_table('{community_tags_unitag}'); + + // delete existing suggestions because some may have been removed by user + db_query("DELETE FROM {community_tags_unitag} WHERE nid = %d AND uid = %d AND vid = %d", $node->nid, $uid, $vid); + foreach ($unitag_suggestions as $suggestion) { + // can't use utid as unitag records are deleted and re-inserted - so use basename + $basename = _unitag_get_basename($suggestion); + $date = time(); + db_query("INSERT INTO {community_tags_unitag} (nid, uid, vid, name, basename, date) VALUES (%d, %d, %d, '%s', '%s', %d)", $node->nid, $uid, $vid, $suggestion, $basename, $date); + } + + db_unlock_tables(); +} + +/** + * Implementation of hook_form_FROM_ID_alter() for form id = unitag_manage_suggestions_form. + * + * Processes the form submission before unitag to act on suggestion moderataion before suggestions + * are deleted. + */ +function community_tags_unitag_form_unitag_manage_suggestions_form_alter(&$form, &$form_state) { + array_unshift($form['#submit'], 'community_tags_unitag_unitag_manage_suggestions_form_pre_submit'); + array_push($form['#submit'], 'community_tags_unitag_unitag_manage_suggestions_form_submit'); +} + +/** + * Just need to statically cache suggestions before unitag form processing deletes + * them from the database. + */ +function community_tags_unitag_unitag_manage_suggestions_form_pre_submit($form, &$form_state) { + $form_state['ct_suggestions'] = array(); + + $utids = array_filter($form_state['values']['utids']); + foreach ($utids as $utid) { + if ($suggestion = unitag_suggestion_load($utid)) { + $form_state['ct_suggestions'][$utid] = $suggestion; + } + } +} + +/** + * Process manage suggestions form submission. + */ +function community_tags_unitag_unitag_manage_suggestions_form_submit($form, &$form_state) { + foreach ($form_state['ct_suggestions'] as $utid => $suggestion) { + switch ($form_state['values']['operation']) { + case 'new-term': + case 'new-child': + // suggestion has been saved as term (new-child just means new term saved with parents set)- so get the term by name and update community tags records + if ($term = unitag_taxonomy_get_term_by_name($suggestion->name, $suggestion->vid)) { + _community_tags_unitag_suggestion_to_term($suggestion, $term); + } + break; + case 'new-synonym': + // suggestion deemed to be a synonym of existing term - get the existing term and update community tags accordingly. + if ($term = unitag_taxonomy_get_term_by_name($form_state['values']['root'][$utid], $suggestion->vid)) { + _community_tags_unitag_suggestion_to_term($suggestion, $term); + } + break; + case 'deny': + // rejected suggestion remove from ct unitag table. Perhaps a hook here or action to notify user(s). + db_query("DELETE FROM {community_tags_unitag} WHERE basename = '%s' AND vid = %d", $suggestion->basename, $suggestion->vid); + break; + } + } +} + +/** + * Find the suggestion in the ct unitags table and for all nid/uid's insert + * into community tags table with the term. + */ +function _community_tags_unitag_suggestion_to_term($suggestion, $term) { + $query = db_query("SELECT * FROM {community_tags_unitag} WHERE basename = '%s' AND vid = %d", $suggestion->basename, $suggestion->vid); + while ($row = db_fetch_object($query)) { + // create proper CT record for this approved new term. + db_query('INSERT INTO {community_tags} (tid, nid, uid, date) VALUES (%d, %d, %d, %d)', $term->tid, $row->nid, $row->uid, $row->date); + } + db_query("DELETE FROM {community_tags_unitag} WHERE basename = '%s' AND vid = %d", $suggestion->basename, $suggestion->vid); +}