If "Save values additionally to the core taxonomy system" is checked, have the field check the Taxonomy system to see if it was changed, when the node is saved/edited.
or
Make a Bulk Operations to update/change taxonomy in bulk.

CommentFileSizeAuthor
#46 content_tax.patch1.32 KBpwaterz
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

mikeytown2’s picture

Title: Support Bulk Operations » Keep core taxonomy & CCK taxonomy synced

Check the database term_node table, see what CCK fields need to be updated? Do a comparison, assuming that the term_* table is always correct, making the various changes to CCK's fields.

Flying Drupalist’s picture

subscribe

Flying Drupalist’s picture

Priority: Normal » Critical

Content Taxonomy needs to sync with taxonomy. The way that all current terms are lost is not good.

thekevinday’s picture

I have been poking around at this problem myself.

It looks like there is something wrong with the content_taxonomy_field function.
The follow hack+patch causes everything to work, but I have doubts as to whether this is a correct fix:

--- content_taxonomy.module.orig        2009-04-14 15:55:50.000000000 -0500
+++ content_taxonomy.module     2009-04-14 16:03:55.000000000 -0500
@@ -153,7 +153,7 @@
 function content_taxonomy_field($op, &$node, $field, &$items, $teaser, $page) {
   switch ($op) {
     case 'presave':
-      if ($field['save_term_node']) {
+      //if ($field['save_term_node']) {
         static $_content_taxonomy_array_cleared;
         if (!is_array($_content_taxonomy_array_cleared) || !$_content_taxonomy_array_cleared[$node->nid][$field['vid']]) {
           _content_taxonomy_taxonomy_unset($node->taxonomy, array($field['vid']));
@@ -183,7 +183,7 @@
         if (empty($node->taxonomy)) {
           $node->taxonomy[$field['vid']] = NULL;
         }
-      }
+      //}
       break;
   }
 }

Notice that all I did was comment out the if ($field['save_term_node']) { if statement.

Flying Drupalist’s picture

What's the expected behavior after making this change?

On my node/edit page the vocabulary loses all other terms except for the one added in CT. On the node view page however all terms are present, CT/and regular taxonomy term.

thekevinday’s picture

Prior to this hack:
I have multiselect (http://drupal.org/project/multiselect) used as a cck content taxonomy field.
I do not use the original taxonomy fields themselves as they multiblock+content taxonomy+cck is being used to provide a more user-friendly way of assigning taxonomies from a select list.

The problem I noticed is that while the changes I made to this cck field did properly save for the cck field itself, the taxonomy vocabulary itself never registered that these taxonomies were being applied.
So at this point in time, the taxonomy cck field never synced up with the actual taxonomy.
That is to say, no matter what I selected with the cck taxonomy field, the term_node table would never populate with data.

I looked at the taxonomy database tables (if I remember correctly, I think it is the term_node table) and there was no node to taxonomy associations going on despite what the cck taxonomy field was claiming.

With this hack:
When I selected the appropriate taxonomies from the select list and saved, the term_node table now populated with data and the taxonomy core was now synced with what the cck taxonomy fields claim.

Tom Ash’s picture

Why was the the if ($field['save_term_node']) { statement there in the first place? I presume someone'd need to check whether removing it does any harm before merging it into module?

Tom Ash’s picture

Status: Active » Closed (fixed)

Hang on, it seems the if statement just check whether 'Save values additionally to the core taxonomy system (into the 'term_node' table).' is checked at the 'Configure' page for your Content Taxonomy field - I located this by searching for $field['save_term_node'] in the module code. It works for me when I check that box - it'd be nice to be able to have it checked by default but that's another issue.

mikeytown2’s picture

Status: Closed (fixed) » Active

@Thomas Ash
This is not a UI issue, like your describing. Change a nodes taxonomy via Views Bulk Operation. That change doesn't cross over to the CCK taxonomy field; thus it gets displayed wrong. Other modules change the taxonomy as well, so Content Taxonomy has to detect the change if it happened, and act accordingly.

Tom Ash’s picture

OK, good point, I'd forgotten your original issue description. Could you clarify the first half of that description?

thekevinday’s picture

I apologize, it seems I was so busy thinking about the syncing issue that I misread this thread.

My problem was apparently that I overlooked "Save values additionally to the core taxonomy system" setting somewhere.
Sorry for almost hijacking this thread.

Flying Drupalist’s picture

I'm not sure if I still want it synched, but I definitely need a way to upgrade from core tax to CT.

My nodes all have lots of terms on them, I can't imagine losing them all in an upgrade.

anrikun’s picture

+1 Subscribe
Yes it have to be synched
or make a Bulk operation to update content taxonomy

mrfelton’s picture

+1. subscribing

Bilmar’s picture

subscribing

portulaca’s picture

subscribing

phpepe’s picture

Component: User interface » Code

subscribing

pierre_cotiniere’s picture

subscribing

pierre_cotiniere’s picture

I found this php script which can help : http://drupal.org/node/485328#comment-1952462

xjm’s picture

Tracking.

Summit’s picture

Subscribing, greetings, Martijn

yan’s picture

These are related issues:

#332454: Also operate as taxonomy widget ONLY
#794068: Sync with core (duplicate of this issue)

yan’s picture

Are the maintainers ever gonna comment on this issue? It's been more than a year now that it exists.

rjbrown99’s picture

I'm on 6.x-1.0-rc2 and have been struggling with this all day. Specifically, what I wanted to do was to load up a node, modify a content_taxonomy field, and the save the node. We're talking specifically about updates to existing nodes and not newly created nodes. This is important.

Here's where I started. Load up the node and clear out both the node cache and CCK cache.

// Notice TRUE, which resets the node_load cache
$fullnode = node_load($nid, NULL, TRUE);
// Also clear the CCK cache
if (module_exists('content')) {
  cache_clear_all('content:'. $fullnode->nid .':'. $fullnode->vid, content_cache_tablename());
}
// Update a content_taxonomy field, where the field definition is set to update both (field and core taxonomy)
$terms = array();
$terms[0]['value'] = '15976';  // This is a specific TID I am using for testing
unset($fullnode->field_myfield);
$fullnode->field_myfield = $terms;
// Save it
$fullnode = node_submit($fullnode);
node_save($fullnode);

Pretty straight-forward. Although what ends up happening in this case is that the core taxonomy in term_node is updated, but the CCK field is not. I confirmed this by reviewing both term_node and content_type_mytype (field_myfield_value). I can see 15976 in the term_node but the old TID in field_myfield_value. If I insert a dsm($fullnode) in front of the node_save and after the node_save, it does properly show 15976 as the term for that field. So I know it's getting set properly, but node_save isn't registering it upon save.

Note that this DOES work if I manually click edit on the node and then save the changes. Both the CCK field and term_node tables are updated properly.

I have spent far too long trying to figure out why that happens, so I gave up and hacked it. After my node_save I manually update the DB.

db_query("UPDATE {content_type_mytype} SET field_myfield_value = %d WHERE nid = %d", '15976', $fullnode->nid);

Here are issues that are potentially related:
#594004: taxonomy_node_get_terms() needs a $reset param that node_load can call when *it* is reset
#217824: Content Taxonomy is not saved when "cck" or "both" are specified
#531274: Using node_save with a Content Taxonomy Field

Here's where I found about clearing CCK cache:
#605594: node_load() during signup's node_save() breaks node data cached by CCK

I have no idea where to go from here. Suggestions would be more than welcome.

meatbag’s picture

subscribing

jvieille’s picture

Content taxonomy is irrelevant as long as it does not sync with core taxonomy.
This is an addon, which should not be allowed to expose an incompatible implementation of an existing feature.

yan’s picture

Well, I think there are cases that don't need content taxonomy to be synced with core taxonomy. For example using the module as a sort of "taxonomy reference" (just like "user reference" or "node reference") if you want to connect a node with a taxonomy term without actually assigning it to the term.

But I totally agree that it is a problem to somehow duplicate a core functionality without allowing to use the core version or at least get both versions synced.

It seems to me that the Content Taxonomy maintainers are suffering a work overload or something like that. The issue queue is really long and even critical issues aren't addressed sometimes -- like this one.

Summit’s picture

Hi, in reply to #24
I think that you also need content_update, see: http://www.balancedscale.com/blog/201006/update-cck-fields-custom-drupal...

greetings, Martijn

Steven Jones’s picture

So I guess the approach would be thus:

  1. On a node load duplicate the $node->taxonomy array to a taxonomy_old array
  2. On a node presave, inspect the two above arrays for differences, and set the value of our CCK fields accordingly, though care must be taken if our field has been updated at the same time.

This is probably fairly simple, but still fraught with intricacies,

yan’s picture

I'm wondering if it is really necessary to duplicate the taxonomy data in the content taxonomy table. At least there should be an option to simply use the 'real' taxonomy data. That way, no synchronization is necessary.

Then there are other cases where we might want to 'reference' a node to a taxonomy term without actually adding the term to it. In that case we could save the data in the content taxonomy table only.

Steven Jones’s picture

If you don't store the data in the CCK tables, then you just end up with the opposite problem: things that are supposed to work with CCK fields won't when they get the data from the tables directly.

jvieille’s picture

What is the reason for storing the taxonomy terms associated to nodes through CCK in different tables than core's?

Steven Jones’s picture

Views.

YK85’s picture

Doesn't Views support taxonomy fields?

Steven Jones’s picture

Okay, I was being a bit pedantic. But it is very useful having the values in CCK's tables.

xjm’s picture

#32, #34: because CCK lets you do things that core taxonomy in D6 does not support. For example, suppose I have a "University" vocabulary. I might want to let someone add their undergraduate school(s), their graduate school(s), their medical school in separate fields on a profile. I want to preserve the information that one is the undergrad, another the grad, etc., but I want to use the one main vocab of schools. That's a use case that core taxonomy in D6 does not address. (D7 will).

jvieille’s picture

That just being able to lay down several fields for the same vocabulary.
Basically, that does not change much about the core capability of
- defining the vocabularies associated to a type of node
- associating multiple terms of each vocabulary to a specific node

the main difference is that CCK allows to put these terms "in context"
A - breaking - consequence is that CCK allows the same term to possibly appear more than once for different context/meaning in the same node.

The best handling of this improvement would be to deal with the context (field definition) in the CCK tables, and extend the core table appropriately, not duplicating the taxonomy system.
Is that forbidden?

xjm’s picture

#37: Alter a core table structure? Forbidden? Perhaps not. Unwise? Definitely.

This is a CCK module. The whole point of it existing at all is that it exposes taxonomy to all the flexibility of CCK. Therefore, it stores its data using CCK's API, which means CCK's types of tables.

Also, the current codebase for the module is end-of-lifed, since (as I mention) taxonomy has been completely redesigned in D7 and core includes the functionality of taxonomy term reference fields in the new Field API. So, I don't think there's much point in arguing against the fundamental architecture (and existence?) of a module that's existed for 3.5 years and is in the top 100 most used contrib modules available on d.o. If you think it's a bad idea, then don't use it.

TrevorBradley’s picture

EDIT: Deleted my comment.. I can verify the following works to update a CCK Taxonomy Field:

$node ->my_cck_taxonomy_field[]['value'] = 123;

Where 123 is a Taxonomy tid associated with the correct vocabulary.

(I'm working on a simpler problem, updating simply a CCK Taxonomy field without worrying about the node taxonomy.)

jean84’s picture

hello seems i have the same problem (maybe)
i have "Save values additionally to the core taxonomy system" activated, but when i try to use the module to add a taxonomie term the new term is assigned to the node but taxonomie dont display it.
So my question is is there a working fix now and please explain exactly how to do it because i am not a coder i dont know where to put a line to change....

thebuckst0p’s picture

Subscribe. Working on a huge migration now and need to sync automatically migrated term_node links to content_taxonomy fields... I'll have to code something custom but it would be nice if the module didn't duplicate the data.

thebuckst0p’s picture

I solved this with a Drush migration script, documented here: Re-Sync Content Taxonomy from core taxonomy.

pwaterz’s picture

replace the function content_taxonomy_options_widget in content_taxonomy_options.module with the following code.
<?/**
* Implementation of hook_widget().
*/
function content_taxonomy_options_widget(&$form, &$form_state, $field, $items, $delta = NULL) {

/**
* This fixes the problem if you add content taxonomy after you have been using normal taxonomy.
* This fix will load in the old terms on the node and make them selected. So when the node is saved again they don't loose the old terms.
*/
if($field['save_term_node'] == 1){
if(!$items[0]['value']){
if($form['nid']['#value']){
$node = new stdClass();
$node->vid = $form['vid']['#value'];
$node_terms = taxonomy_node_get_terms($node);

$items = array();
foreach($node_terms as $term){

if($field['vid'] == $term->vid){
$items[]['value'] = $term->tid;

}
}
}
}
}

$element = array(
'#type' => ($field['widget']['type'] == 'content_taxonomy_select') ? 'optionwidgets_select' : 'optionwidgets_buttons',
'#default_value' => !empty($items) ? $items : array(),
);
return $element;
}?>

pwaterz’s picture

replace the function content_taxonomy_options_widget in content_taxonomy_options.module with the following code.

/**
 * Implementation of hook_widget().
 */
function content_taxonomy_options_widget(&$form, &$form_state, $field, $items, $delta = NULL) {
  
  /**
   * This fixes the problem if you add content taxonomy after you have been using normal taxonomy. 
   * This fix will load in the old terms on the node and make them selected. So when the node is saved again they don't loose the old terms. 
   */
  if($field['save_term_node'] == 1){
    if(!$items[0]['value']){
      if($form['nid']['#value']){
        $node = new stdClass();
        $node->vid = $form['vid']['#value'];
        $node_terms = taxonomy_node_get_terms($node);
        
        $items = array();
        foreach($node_terms as $term){
          
          if($field['vid'] == $term->vid){
              $items[]['value'] = $term->tid; 
          
          }
        }
      }
    }
  }
  
  $element = array(
    '#type' => ($field['widget']['type'] == 'content_taxonomy_select') ? 'optionwidgets_select' : 'optionwidgets_buttons', 
    '#default_value' => !empty($items) ? $items : array(),
  );
  return $element;
}
kartik.gmf’s picture

In my setup the taxonomies and the CCK's are synced but the issue is that the parents are not.

My taxonomies are defined like this

Parent A
- Child A1
- Child A2
- Child A3

Parent B
- Child B1
- Child B2

My content type has fields which use this taxonomy. When I select Child A1 in a CCK field it is added to the term_node table, but Parent A is not.

I need Parent A also to be associated in the term_node table since I need to use the Faceted Search module which drills down content based on various facets.

Please help !

pwaterz’s picture

FileSize
1.32 KB

Here is a patch from my code above.

djroshi’s picture

My approach to syncing core taxonomy and content taxonomy fields within a node is to implement hook_content_fieldapi() within content_taxonomy.module, to update all nodes of a certain content type when the content taxonomy field settings are updated, specifically when the vocabulary setting for the field is changed:

/**
 * Implementation of hook_content_fieldapi
 */
function content_taxonomy_content_fieldapi($op, $field) {
  if ($field['type'] == 'content_taxonomy') {
    switch($op) {
      case 'update instance':
        // Get the previous field settings
        $previous_field = (!empty($field['previous_field'])) ? unserialize($field['previous_field']) : array();
        // Check if the vocabulary setting has changed
        if (isset($previous_field['vid']) && isset($field['vid'])) {
          if ($previous_field['vid'] != $field['vid']) {
            $query = db_query(db_rewrite_sql("SELECT n.nid FROM {node} n WHERE n.type = '%s'"), $field['type_name']);
            while ($result = db_fetch_object($query)) {
              // Update the node
              $node = node_load(array('nid' => $result->nid), NULL, TRUE);
              $delta = 0;
              $temp[$delta]['value'] = '';
              foreach ($node->taxonomy as $term_data) {
                if ($term_data->vid == $field['vid']) {
                  $temp[$delta]['value'] = $term_data->tid;
                  $delta++;
                }
              }
              $node->$field['field_name'] = $temp;
              node_save($node);
            }
          }
        }
        break;
    }
  }
} 

This is only a partial solution to the issue, however it seems to suit my current use case - migrating core taxonomy to content taxonomy fields for existing nodes. I will update this thread if I discover any issues with this while I carry out the migration.

crcarlin’s picture

Subscribe.

image import can set taxonomy terms, but it does so in the system table, getting everything out of sync.

pwaterz’s picture

Just as an FYI this module is not longer maintained.