For freetagging vocabularies i use Content Taxonomy Autocomplete (6.x-1.0-beta6) field to save terms.
In my content type i have 3 such fields - Region, Street and Index

Users often input street address wrong (for example "13 Avenue" and "13th Avenue") - so i want to merge "13 Avenue" into "13th Avenue". But when i merge term "13 Avenue" with "13th Avenue" in Street vocabulary - all other terms (Region and Index) in nodes becames empty!

Explain in detail

First i have such nodes:
title: Teddy Shop
Region: West
Street: 13 Avenue
Index: 31000

After merging:
title: Teddy Shop
Region:
Street:
Index:

What is the reason for such problem? Maybe - the using of Content Taxonomy Field inspite of direct assigning vocabulary to node?

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Eugene Fidelin’s picture

I find out that terms from other vocabularies disappears when module delete term which is still linked to node.
So module must first assign new merged term to node and then delete old unnecessary term

So if i want merge "13 Avenue" into "13th Avenue" then module must do in such order
1. Update all nodes and set "13th Avenue" where term is "13 Avenue"
2. Delete unnecessary term "13 Avenue"

Taras Zavaliy’s picture

I believe you're right – it's because of CCK Content Taxonomy Fields.
This would be a very useful feature, but implementation may not be straightforward...

(subscribing)

mh86’s picture

Category: bug » feature

yes, at the moment the Merge feature is not compatible with Content Taxonomy Fields!!
As far as I remember I pointed this out in the readme.txt
I'm planing to implement this, but can't tell you when I'm going to find time to implement this feature

mh86’s picture

Title: Merging terms disappear from node » Make Content Taxonomy Fields compatible with Merge feature

changing title...

michellekim’s picture

Any progress on this yet?

(subscribing)

a_c_m’s picture

also interested in this.

hefox’s picture

implementating a hook as mentioned in a TODO should solve this if correctly implmentated them by content_taxonomy

ie
//TODO: add hook, so that other modules can consider changes

  foreach ($merging_terms as $merge_term) {
    if ($merge_term != $main_term) {
      //update node-relations
      module_invoke_all('taxonomy_manager_term','merge',$main_term,$merge_term); // the hook

and then content_taxonomy could implement something like

function content_taxonomy_taxonomy_manager_term($op,$arg0=null,$arg1=null) {
    switch($op) {
        case 'merge':
            $new = $arg0;
            $old = $arg1 ;
            $types = content_types();
            foreach(content_fields() as $fieldname => $fieldinfo) {
              if ($fieldinfo['type']=='content_taxonomy') {
                foreach($types as $type=>$info) {
                    if ($info['fields'][$fieldname]) {
                        if ($info['tables']['content_'.$fieldname]) $table = 'content_' . $fieldname;
                        else $table = _content_tablename($type['type'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
                        $dbfield = $fieldname . '_value';
                        if (!db_result(db_query("SELECT vid from {$table} where $dbfield=%d LIMIT 1",$old))) continue; 
                        db_query("UPDATE {$table} SET $dbfield=%d where $dbfield=%d",array($new,$old));
                        //cleanup
                        $vids = array();
                        if ($fieldinfo['multiple'] > 0) {
                            $query = "SELECT vid from {$table} where $dbfield=%d GROUP by vid, $dbfield having count(delta) > 1";
                            $result =db_query($query,$new);
                            while ($row = db_fetch_object($result)) {
                                $result2 = db_query("SELECT delta from  {$table} where $dbfield=%d AND vid=%d ",array($new,$row->vid));
                                while ($delta = db_fetch_object($result2)) {
                                    if (!in_array($row->vid,$vids)) $vids[] = $row->vid;
                                    else {
                                        db_query("DELETE from {$table} where $dbfield=%d AND vid=%d AND delta=%d",array($new,$row->vid,$delta->delta));
                                    }
                                }
                            }
                        }
                    }
                }
              }
            }
        break;
    }
}

(...with a much better 'cleanup' area, blerg).

Wouldn't that work?

benone’s picture

subscribe

GregoryHeller’s picture

I just posted this issue over on content taxonomy module: http://drupal.org/node/665868

hefox’s picture

function taxonomy_manager_switch($tids, $from_voc, $to_voc, $parents = array()) {
  foreach ($tids as $tid) {
   module_invoke_all('taxonomy_manager_term','switch',$tid,$from_voc,$to_voc); // the hook

This is also nice for when terms switch vocabularies so modules have a chance of responding to the switch; here's an example of it use http://foxinbox.org/drupal/code-snippits/switching-content-taxonomy-fiel... (haven't tested it too much).

I can make a patch for the hooks if the syntax is desirable.

Bilmar’s picture

subscribing

mh86’s picture

I committed both hooks for switching and merging to the taxonomy manager, as suggested by hefox (thanks for working on this issue!).
Implementations of these hooks by other modules, like the content taxonomy, are of course still missing, but at least it's possible from now on to react on the changes.

robby.smith’s picture

+1 subscribing

pimousse98’s picture

Has there been any progress in implementing the integration with Content Taxonomy?

pedrorestu’s picture

suscribing.

it would be good this request.

brycesenz’s picture

Subscribing.

brycesenz’s picture

Actually, after reading through the current taxonomy manager code and reading through hefox's awesome code, it seems that really all you have to do is to append this function at the bottom of "content_taxonomy.module":

/**
 * Implementation of hook_taxonomy_manager_term
 */
function content_taxonomy_taxonomy_manager_term($op, $arg0 = NULL, $arg1 = NULL, $arg2 = NULL) {    
  switch($op) {
    case 'merge':
      $new = $arg0;
      $old = $arg1;
      $types = content_types();
        foreach(content_fields() as $fieldname => $fieldinfo) {
        if ($fieldinfo['type']=='content_taxonomy') {
          foreach($types as $type=>$info) {
            if ($info['fields'][$fieldname]) {
              if ($info['tables']['content_'.$fieldname]) {
                $table = 'content_' . $fieldname;
              }
              else {
                $table = _content_tablename($type, CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
              }
              $dbfield = $fieldname . '_value';
              
              if (!db_result(db_query("SELECT vid from {$table} where $dbfield=%d LIMIT 1",$old))) continue; 
              db_query("UPDATE {$table} SET $dbfield=%d where $dbfield=%d",array($new,$old));
              //cleanup
              $vids = array();
              if ($fieldinfo['multiple'] > 0) {
                $query = "SELECT vid from {$table} where $dbfield=%d GROUP by vid, $dbfield having count(delta) > 1";
                $result =db_query($query,$new);
                while ($row = db_fetch_object($result)) {
                  $result2 = db_query("SELECT delta from  {$table} where $dbfield=%d AND vid=%d ",array($new,$row->vid));
                  while ($delta = db_fetch_object($result2)) {
                    if (!in_array($row->vid,$vids)) $vids[] = $row->vid;
                    else {
                      db_query("DELETE from {$table} where $dbfield=%d AND vid=%d AND delta=%d",array($new,$row->vid,$delta->delta));
                    }
                  }
                }
              }
            }
          }
        }
      }
    break;
  }
}

You can optionally add the 'switch' case code that hefox also provided, if that's how you want your content taxonomy module to behave when terms switch vocabularies.

matuck’s picture

Subscribing.

ju.ri’s picture

Just tested the code in #17 and it works great! Thank you!

asb’s picture

Version: 6.x-1.0-beta2 » 6.x-1.x-dev

Maybe if someone would roll a patch with the changes from #17, there'd be a slight chance to get this fixed and committed, almost 2.5 years after the initial feature request (just in case that someone still maintains content_taxonomy.module)?

Thank you!

darrell_ulm’s picture

Here is the patch rolled. Can anyone test?

asb’s picture

Thanks, darrellulm!

Running the patch in #21 from within ./sites/all/modules/content_taxonomy against content_taxonomy-6.x-1.0-rc2 gives me:

# git apply 402592_Make_Content_Taxonomy_Fields_compatible_with_Merge_feature.patch 
402592_Make_Content_Taxonomy_Fields_compatible_with_Merge_feature.patch:14: trailing whitespace.
function content_taxonomy_taxonomy_manager_term($op, $arg0 = NULL, $arg1 = NULL, $arg2 = NULL) {    
402592_Make_Content_Taxonomy_Fields_compatible_with_Merge_feature.patch:31: trailing whitespace.
              
402592_Make_Content_Taxonomy_Fields_compatible_with_Merge_feature.patch:32: trailing whitespace.
              if (!db_result(db_query("SELECT vid from {$table} where $dbfield=%d LIMIT 1",$old))) continue; 
warning: 3 lines add whitespace errors.

However, this is RC2, not one of the current "dev" releases (branches 6.x-2.x-dev or 6.x-1.x-dev), and probably I have a number of patches already applied.

darrell_ulm’s picture

Darned white-space, hmmmm, wonder if it can still apply.

Do you want me to re-roll this?

Thanks.

asb’s picture

This is beyond me... Stackoverflow 1, Stackoverflow 2, Check for whitespace errors in diff. Yes, please reroll, if you can make any sense of those "whitespace errors".

Thank you!

darrell_ulm’s picture

OK, I'll roll for the 2 dev releases when I get caught up.

naero’s picture

Issue summary: View changes

This did not work for me; it ended up deleting the value from the node altogether.

  • mh86 committed 3d60539 on 8.x-1.x
    #402592 by hefox: added hooks for merging and switching of terms
    
    
ivnish’s picture

Status: Active » Closed (outdated)