Hi,

I have a Content Type "music_album" that has many CCK fields, especially a field of type "Node Reference" in which you can put unlimited values.

But, In fact I'm creating some of music albums programmatically. However I have a problem with these unlimited fields of node reference: I'm not able to add more than one node reference.

One person seemed to have the same problem: See http://stackoverflow.com/questions/2723574/drupal-how-to-update-a-cck-no...

But I followed the instructions given and it doesn't work.

My code:

function get_current_delta($node_vid){
    return db_result(db_query("SELECT delta FROM {content_field_album_artist}
                               WHERE vid = '%d'
                               ORDER BY delta DESC
                               LIMIT 1", $node_vid));
} 
function addArtistToAlbum($anid,$nid) {
	$node = node_load($anid);
	$curdelta=get_current_delta($anid);

	$node->field_album_artist = array($curdelta+1 => array('nid' => $nid));
	
	$node = node_submit($node);
	node_save($node);
	content_insert($node);

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

Some details:
- I want to fill one node with this function each time I have to add a node reference. When I'm getting the output of the node after the node_load, even when It is supposed to return at least one node reference, the DSM shows nothing in the "field_album_artist" field..

- I put in my code the "content_insert($node);" line whereas it doesn't work if I let this line since I got "duplicate entries" warnings. I have no errors when I remove this line.

In fact it seems to be a validation problem, but I don't know where and why...

Thanks!

Comments

nevets’s picture

Just a thought, what if you replace

    $curdelta=get_current_delta($anid);

    $node->field_album_artist = array($curdelta+1 => array('nid' => $nid));

with

    $node->field_album_artist[] = array('nid' => $nid);
XmhO’s picture

It doesn't work. In fact It was what I tried before I saw the stackoverflow topic I showed you in my first post.

I tried to debug this, and for example when I want to add for the first time my nid, just after the

$node->field_album_artist = array($curdelta+1 => array('nid' => $nid));

line, it's ok the nid is in the node.
Whereas, when for the second time I want to edit the same node, when I debug the node after the node_load, I can see that the nid disappeared.
That's why I thought It was a validation problem. what do you think about that?

Then for the second time I add the second nid (in the 0 delta), I save, after the node_save I can see that It is saved, but after each next node_load the field is empty...

nevets’s picture

Are you sure that $nid is being passed correctly the second time. Is it possible the problem is in the code that calls addArtistToAlbum()?

XmhO’s picture

Nope, It doesn't work. I tried moving the two lines where I was calling my function, but It doesn't seem to be the problem.
Moreover It can't be a problem about the second call since when I make my node_load() for the second time, I don't see my nodereference value nid that I put in the first time...

What about a validation problem, maybe?

XmhO’s picture

Hey!

It's ok, I solved my problem, thanks to this: http://drupalbin.com/14439

Edit: If you have this problem you just have to specify you won't use cache when you code your node_load, e.g:

node_load($node,NULL,true);

My code if some persons would need an example:

function addArtistToAlbum($anid,$nid) {
	module_load_include('inc', 'node', 'node.pages');
// Loading node ignoring cache : IT IS the solution
	$node = node_load($anid,NULL,TRUE);
// As you can see we don't need the delta anymore. Appending a node ref
// like that works great ;)
	$node->field_album_artist[]['nid'] = $nid;
	$node = node_submit($node);
	node_save($node);
	//content_insert($node);
	// This line creates an error for me. "content_presave()" only is perfectly working ;)
	drupal_flush_all_caches();
}

Thanks a lot nevets for helping me.

nevets’s picture

It seems to me this could be more efficient. I suspect the calling code has a loop and it seems you could get rid of this function all together. So my suggestion in psuedo code would be to do something like this

loop through nodes we are going to add references to
   $node = node_load($anid);
   loop through references
         $node->field_album_artist[]['nid'] = $nid;
    end inner loop
    $node = node_submit($node);
    node_save($node);
end outer loop

This would reduce the number of calls to node_load() and node_save().

eamontaylor’s picture

This also saved me hours of pulling my hair out. Thank you!!

drupee’s picture

After saveral hours I found your post. It was very helpful.

stomerfull’s picture

thank you very much , work like charm for me :)