Download & Extend

Non-community tag vocabularies still get inserted in community tags on node save.

Project:Community Tags
Version:6.x-1.x-dev
Component:Code
Category:bug report
Priority:normal
Assigned:Unassigned
Status:closed (fixed)

Issue Summary

I am pretty sure the problem is that it does not check if the vocab is marked as a community tags vocab, somewhere in this function:

<?php function community_tags_taxonomy_node_save($node, $terms, $is_owner, $uid) {
 
$community_tagged = variable_get('community_tags_vocabularies', array());
  if (
count($community_tagged) == 0) {
    return;
  }
 
$nid = $node->nid;

 
// If we're adding tags from the node add/edit page, then we want to delete
  // any tags that aren't entered to allow admins to remove node tags.
  // If not, we at least want the existing counts to update them.

 
$old_tags_by_uid = array();
 
$result = db_query('SELECT * FROM {community_tags} ttn WHERE nid = %d', $nid);
  while (
$old_tag_node = db_fetch_object($result)) {
   
$old_tags_by_uid[$old_tag_node->uid][$old_tag_node->tid] = $old_tag_node;
  }

 
$tag_nodes = array();
 
$inserted_tids = array();

 
$tids = array();
 
// Free tagging vocabularies do not send their tids in the form,
  // so we'll detect them here and process them independently.
 
if (isset($terms['tags'])) {
   
$typed_input = $terms['tags'];
    unset(
$terms['tags']);

    foreach (
$typed_input as $vid => $vid_value) {
     
$typed_terms = is_array($vid_value) ? $vid_value : drupal_explode_tags($vid_value);
      foreach (
$typed_terms as $typed_term) {
       
// See if the term exists in the chosen vocabulary
        // and return the tid, otherwise, add a new record.
       
$possibilities = taxonomy_get_term_by_name($typed_term);
       
$typed_term_tid = NULL; // tid match if any.
       
foreach ($possibilities as $possibility) {
          if (
$possibility->vid == $vid) {
           
$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;
       
$tag_node->nid = $nid;
       
$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;
      }
    }
  }

 
// Re-insert the existing tags we haven't already added back in (incl. other users' tags).
 
foreach ($old_tags_by_uid as $old_uid => $old_tags) {
    foreach (
$old_tags as $old_tag) {
     
// If we're editing as the owner, only re-insert this other user's old tag
      // when I've kept this tag in the node edit form.
     
if ($is_owner && isset($inserted_tids[$old_tag->tid]) && $old_tag->uid != $uid) {
       
$tag_nodes[] = $old_tag;
      }
      elseif (!
$is_owner && $old_tag->uid != $uid) {
       
$tag_nodes[] = $old_tag;
      }
    }
  }

 
// Get existing term-node associations to see if we need to re-insert a term-node
  // relation for each old tag we're putting back in since we're acting after
  // taxonomy.module has done its business.
 
$result = db_query('SELECT tid FROM {term_node} WHERE nid = %d', $nid);
 
$existing_term_nodes = array();
 
$add_term_nodes = array();
  while (
$term_node = db_fetch_object($result)) {
   
$existing_term_nodes[$term_node->tid] = TRUE;
  }

 
// Re-insert tag-node-user associations and term-node if not existing.
 
db_lock_table('{community_tags}');
 
db_query('DELETE FROM {community_tags} WHERE nid = %d', $nid);
  foreach (
$tag_nodes as $tag_node) {
   
db_query('INSERT INTO {community_tags} (tid, nid, uid, date) VALUES (%d, %d, %d, %d)', $tag_node->tid, $tag_node->nid, $tag_node->uid, $tag_node->date);

   
// Remember to insert term-node relation into term_node table if it doesn't exist already.
   
if (!isset($existing_term_nodes[$tag_node->tid])) {
     
$add_term_nodes[] = $tag_node;
     
$existing_term_nodes[$tag_node->tid] = TRUE;
    }
  }
 
db_unlock_tables();

 
// Avoid locking term_node so we loop again.
 
foreach ($add_term_nodes as $tag_node) {
   
// Insert term-node relation into term_node table since it doesn't exist already.
   
db_query('INSERT INTO {term_node} (nid, tid, vid) VALUES (%d, %d, %d)', $tag_node->nid, $tag_node->tid, $tag_node->vid);
  }

 
// Match real tags to community tags, if necessary (e.g. after quick tagging).
 
if (!$is_owner) {
   
$placeholders = implode(',', array_fill(0, count($community_tagged), '%d'));
   
$args = $community_tagged;
   
array_unshift($args, $nid);
   
$result = db_query('SELECT n.tid, n.nid FROM {term_node} n LEFT JOIN {community_tags} c ON n.tid = c.tid AND n.nid = c.nid INNER JOIN {term_data} d ON n.tid = d.tid WHERE n.nid = %d AND c.nid IS NULL AND d.vid IN ('. $placeholders .')', $args);
    while (
$tag = db_fetch_object($result)) {
     
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);
  }

}
?>

Comments

#1

Same problem here, when I save a node, the form shows the community tag terms mixed with all other terms associated with the node.

#2

Status:active» needs review

Simple patch.

AttachmentSize
community_tags.patch 929 bytes

#3

the patch in #2 seems to work for me

#4

patch committed, thanks Gyt.

#5

Status:needs review» fixed

#6

Status:fixed» closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.