I'm currently migrating a custom csv - import module from D6 to D7. But I'm having problems with programmatically creating a node with a references field attached to it. When saving the node, I get the following exception:

PDOException: SQLSTATE[HY000]: General error: 1366 Incorrect integer value: 'nid' for column 'delta' at row 1: INSERT INTO {field_data_field_nodereference} (entity_type, entity_id, revision_id, bundle, delta, language, field_parentregion_nid) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6); Array ( [:db_insert_placeholder_0] => node [:db_insert_placeholder_1] => 25 [:db_insert_placeholder_2] => 25 [:db_insert_placeholder_3] => someCustomType [:db_insert_placeholder_4] => nid [:db_insert_placeholder_5] => de [:db_insert_placeholder_6] => ) in field_sql_storage_field_storage_write() (line 425 of ... field_sql_storage.module).

$node = new stdClass ();
			$node->type = 'someCustomType'; //has a references field called 'nodereference'
			node_object_prepare($node);
			$node->title = 'Title';
			$node->body = 'Some content...';
			
			$node->field_nodereference['de'][0]['nid'] = 25; //reference to node with nid 25
			node_submit($node);
			node_save($node); //exception thrown

I would be very thankful if someone could point out a way on how to programmatically adding a references field to a node. I have the feeling that I miss some fundamental aspects of creating the D7 fields programmatically.

Your help is appreciated!

Comments

fgm’s picture

In D7, the node body is no longer a hardcoded string/format pair but a field too: you can probably not get a correct node creation using $node->body = 'Some content';

danielb’s picture

Something like this should work.


    $node->body = array(
      'de' => array(
        '0' => array(
          'value' => 'Some content...',
          'summary' => '',
          'format' => 'filtered_html',
          'safe_value' => '<p>Some content...</p>
',
          'safe_summary' => '',
        ),
      ),
    );

    $node->field_nodereference = array(
      'de' => array(
        '0' => array(
          'nid' => '25',
        ),
      ),
    );

I generated similar code with Node export, and it imported back fine.

In future, you could just var_dump a $node and see what it looks like.

geerlingguy’s picture

I'd like to know if there's some sort of helper function that, instead of creating an entire node with a reference, will allow me to add a reference to a node that's already created. I know I could do all this manually, but it would be awesome if there were something like references_add_node_reference($nid, $nid_to_refer) or something like that.

danielb’s picture

You would also need to add a parameter to specify which field to add the reference to, which also means you'd have to have created the node reference field on the content type. In the end it would just be a case of using node_load(), modifying the node, and then doing a node_save(). The only issue I'm fuzzy on is identifying the node's available languages to add it in the right spot in the data structure.

Umayal’s picture

Title: How to programmatically create node with reference » Problem in programmatically create node with reference
Category: support » task
function generate_content_settings_submit($form, &$form_state){
//Node -1

$city=array('toneity','excelcity'); 
for($i=0;$i<count($city);$i++){
$node = new stdClass(); // We create a new node object 
$node->type = "city"; // Or any other content type you want
$node->title = $city[$i];
$node->language = LANGUAGE_NONE;
node_object_prepare($node); // Set some default values
$node = node_submit($node); // Prepare node for a submit
node_save($node); // After this call we'll get a nid
}

//node-2 (node 2 refer node1 in node reference field)

$inst=array(array('SSM ','1'),
array('KSR '),
array('Kongu ','2')); 
for($i=0;$i<count($inst);$i++){
$node = new stdClass(); // We create a new node object
$node->type = "inst"; // Or any other content type you want
$node->title = $inst[$i][0];
//$node->field_nodereference['field_fnr_city']['und'][0]['nid'] = 1;
$node->language = LANGUAGE_NONE;
$node = node_submit($node); // Prepare node for a submit
node_save($node); // After this call we'll get a nid
node_object_prepare($node); // Set some default values
}
}

Node 1 has city value and node 2 refer node 1 city value.

when node 2 have the automatic value of node reference field passing nid of node1?

How is it possible ? pls help me?

nevets’s picture

For the city node change

$node = node_submit($node); // Prepare node for a submit
node_save($node); // After this call we'll get a nid

to

$city_node = node_submit($node); // Prepare node for a submit
node_save($city_node); // After this call we'll get a nid

That way you can use $city_node->nid to initialize the reference field in node 2.

Not sure what that for loop is about though, you are actually creating 4 nodes.

And I do not think calling node_object_prepare() after saving the node has any value.

Umayal’s picture

Thanks for replay.

I change the city node as you said.

It so an error ---> Parse error: syntax error, unexpected T_VARIABLE
($city_node = node_submit($node);)

nevets’s picture

Whats the complete code look like?

Umayal’s picture

Complete code

function generate_menu() {
  $items = array();
  $items['generate_content'] = array(
    'title' => 'Generate Content',
    'page callback'=>'drupal_get_form',
    'page arguments' =>array('generate_content_settings'),
    'access callback'=>TRUE, 
    );
 return $items;
}


function generate_content_settings() {

$form['submit']= array(
  '#type'=>'submit',
  '#value'=>t('Generate '),
  );

  return($form);
}


function generate_content_settings_submit($form, &$form_state){

$city=array('toneity','excelcity'); 
for($i=0;$i<count($city);$i++){
$node = new stdClass(); // We create a new node object 
$node->type = "city"; // Or any other content type you want
$node->title = $city[$i];
$node->language = LANGUAGE_NONE;
$city_node = node_submit($node); // Prepare node for a submit
node_save($city_node); // After this call we'll get a nid
}

$inst=array(array('SSM'),array('KSR'),array('Kongu')); 
for($i=0;$i<count($inst);$i++){
$node = new stdClass(); // We create a new node object
$node->type = "inst"; // Or any other content type you want
$node->title = $inst[$i][0];
//$node->field_nodereference['field_fnr_city']['und'][0]['nid'] = $city_node->nid;
$node->language = LANGUAGE_NONE;
$node = node_submit($node); // Prepare node for a submit
node_save($node); // After this call we'll get a nid
}

$link ='node/'.$node->nid;
 drupal_goto($link); 
 
}
nevets’s picture

I copies the code, saved as a file and did a syntax check and I do not get that parse error. One possibility that suggests is a hidden character that did not come over with the cut and paste.

Umayal’s picture

I also copy the code

Five content are created.

In inst(node2) content node reference field(node1) not selected default.
toneity,excelcity are in node reference field but not as selected one.

($node->field_nodereference['field_fnr_city']['und'][0]['nid'] = $city_node->nid;)
that is:
SSM in toneity city
KSR in excelcity city

how to pass city nid to inst node reference field.(through code manually)

Vj’s picture

$city=array('toneity','excelcity');
  //Create an  empty array for city nids.
  $city_nid = array();

  for($i=0;$i<count($city);$i++){
    $node = new stdClass(); // We create a new node object 
    $node->type = "city"; // Or any other content type you want
    $node->title = $city[$i];
    $node->language = LANGUAGE_NONE;
    $city_node = node_submit($node); // Prepare node for a submit
    node_save($city_node); // After this call we'll get a nid
    // save your city nids as per city name
    $city_nid[$city[$i]] = $city_node->nid;
  }

  $inst=array(array('SSM'),array('KSR'),array('Kongu')); 
  for($i=0;$i<count($inst);$i++){
    $node = new stdClass(); // We create a new node object
    $node->type = "inst"; // Or any other content type you want
    $node->title = $inst[$i][0];
    if ($inst[$i][0] == 'SSM')
      $node->field_fnr_city['und'][0]['nid'] = $city_nid['toneity'];
    if ($inst[$i][0] == 'KSR')
      $node->field_fnr_city['und'][0]['nid'] = $city_nid['excelcity'];
    $node->language = LANGUAGE_NONE;
    $node = node_submit($node); // Prepare node for a submit
    node_save($node); // After this call we'll get a nid
  }

  $link ='node/'.$node->nid;
  drupal_goto($link); 

it will give you
SSM in toneity city
KSR in excelcity city
and Kongu with empty city field