Drupal - How to programmatically update a CCK NodeReference field?

I am trying to create a node (type B) and assign it to a field of type NWWERK of type node CCK using the node_save () method.

$node_type_A = node_load($some_nid); $node_type_A->field_type_B_node_ref[]['nid'] = $node_type_B_nid; $node_type_A = node_submit($node_type_A); node_save($node_type_A); 

As a result, a new type of B node will be created, but no link type will be assigned to type A node. Any help would be appreciated.

+7
php drupal drupal-6 cck
source share
5 answers

GApple is right, the format is correct, but there are a few things you might want to take care of.

Delta strong value>
First you need to know the delta value of the last node link bound to $node_type_A , the delta is actually a partial index, combined with the vid $node_type_A , they become the index for the node lookup table in the database. In other words, its counter for $node_type_B referenced in $node_type_A , ok?

GApple will be back again, you need to say exactly where to add the new link. When you get this delta value, you can tell exactly where to add (delta + 1) the new link. Here he is:

 function get_current_delta($node_vid){ return db_result(db_query("SELECT delta FROM {content_field_type_A_node_ref} WHERE vid = '%d' ORDER BY delta DESC LIMIT 1", $node_vid)); } 

Adding a new link
We have a delta! so we can attach a new $node_type_B node to our $node_type_A node:

 // Loading type_A node. $node_type_A = node_load($some_nid); // Getting current delta value. $current_delta = get_current_delta($node_type_A->vid); // "Appending" a node reference based on delta. $node_type_A->field_type_B_node_ref += array($current_delta + 1 => array('nid' => $node_type_B_nid)); 

Saving the updated node
If desired, call node_submit() to fill in some important fields in the node object and save it using node_save() . In the end, you need to call content_insert() to make the node fully preserved asidelong with its CCK fields:

 // Resaving the updated node. $node_type_A = node_submit($node_type_A); node_save($node_type_A); content_insert($node_type_A); 

Clearing Content Cache
Probably the most important part, it killed me a couple of days. CCK has a cache table in the database called cache_content (take a look at its structure), after saving the updated node you will notice that nothing has changed in the output of the topic $node_type_A , even though the tables are being updated, We must delete the record from this table content cache, this will cause Drupal to show the last snapshot of the data. You can define the following as a function:

 db_query("DELETE FROM {cache_content} WHERE cid = '%s'", 'content:' . $node_type_A->nid . ':' . $node_type_A->vid); 

Hope this helps;)

+6
source share

I just checked one of my own modules, which does something similar for the format of the object, and $node_type_A->field_type_B_node_ref[]['nid'] should be correct.

You can verify that when loading the node, CCK can pre-populate the node reference array with a null value. If you configured a field for only one value using the add array operator ( field_type_B_node_ref[] ), it will create a second record that will be ignored ( field_type_B_node_ref[1] ) instead of overwriting the existing value ( field_type_B_node_ref[0] ), Try to explicitly specify array key, if possible.

+4
source share

Great mail, but one fix: do not flush cache entries manually by querying the database. In case someone uses memcache or any other external cache, he will fail.

cache_clear_all () is your friend for cleaning.

Suggested code directly from the CCK module:

 cache_clear_all('content:'. $node_type_A->nid .':'. $node_type_A->vid, content_cache_tablename()); 
+3
source share

I show that CCK stores node links as $node->field_node_reference[0]['items'][0]['nid'] , not $node->field_node_reference[0]['nid'] . Have you tried to imitate this?

0
source share

"Clearing the content cache" This works for me, especially if you get data from node_load ()

0
source share

All Articles