Hey, i would like to add some field collection items while to a currently saved node (in hook_node_presave I thougth it would be the right place).

actually I do the fallowing:

      $values['field_name'] = 'field_invoice_vat';  
       $vat_rate_collection = entity_create('field_collection_item', $values);
      
      // Attach the field_collection entity to the application node. This has to
      // happen separately so that it actually works -- you can't just specify
      // this via the $values array.
      //@see http://drupal.org/node/1353926
      $vat_rate_collection->setHostEntity('node', $invoice, LANGUAGE_NONE, FALSE); //last param: true= link node to host
      
      //save the entity to link it to the host with its id, otherwise we dont have an id
      $vat_rate_collection->field_vat_rate[LANGUAGE_NONE]['value'] = $vat_rate;
      $vat_rate_collection->field_vat_total[LANGUAGE_NONE]['value'] = $vat;
      $vat_rate_collection->save(true); //last param skipps host save, because this will result in an endless loop!

I even tried to set TRUE as the last parameter of setHostEntity but this didnt work. The new entity is saved into the database, but the node, that is saved doesn't link to this entity.I thought this should setHostEntity do.

Is there any other way to do this or is hook_node_presave the wrong place for that?

Comments

manuelBS’s picture

In hook_node_update it works right now with the fallowing code:


$values = array();
      $values['field_name'] = 'field_invoice_vat';      
      $values['field_vat_rate'][LANGUAGE_NONE][0]['value'] = $vat_rate;   
      $values['field_vat_total'][LANGUAGE_NONE][0]['value'] = $vat;   
      
      //save the entity to link it to the host with its id, otherwise we dont have an id      
      $vat_rate_collection = entity_create('field_collection_item', $values);
      
      // Attach the field_collection entity to the application node. This has to
      // happen separately so that it actually works -- you can't just specify
      // this via the $values array.
      //@see http://drupal.org/node/1353926
      $vat_rate_collection->setHostEntity('node', $invoice, LANGUAGE_NONE, TRUE); //last param: true= link node to host
      
      $vat_rate_collection->save();  //last param skipps host save, because this will result in an endless loop!

But it doesn't work on hook_node_insert. Does anybody have any suggestions why that doesn't work?

odegard’s picture

Banging my head against this all day, finally found the solution. I guess it's too late for you, but I found this page after searching for the keywords: entity_create and hook_node_insert

Alright, the thing is that the $node is hook_node_insert is already committed before we can act on it. So with the code above, the field collection will be created, but the node won't be updated to inlude the reference. Perhaps this should've been taken care of with setHostEntity, I haven't checked. This worked for me:

function MYMODULE_node_insert($node) {
    $field_collection_item = entity_create('field_collection_item', array('field_name' => 'field_FIELDNAMEINNODE'));
    $field_collection_item->field_FIELDNAMEINCOLLECTION1[LANGUAGE_NONE][0] = array('tid' => 7); // term in a select list
    $field_collection_item->field_FIELDNAMEINCOLLECTION2[LANGUAGE_NONE][0] = array('value' => $node->created); // UNIX timestamp of node

    $field_collection_item->setHostEntity('node', $node);
    $field_collection_item->save(true);
    $node->field_FIELDNAMEINNODE[LANGUAGE_NONE][0] = array('value' => $field_collection_item->item_id);
    field_attach_update('node', $node);

Points of interest:

  • unless you set save() to save(true) the table field_collection_item won't get updated.
  • field_attach_update() takes care of attaching the new node. This is necessary probably because the node is already saved before this code is run
  • Although the node field to the collection is updated automatically, the field_attach_update won't fire unless we perform some manual alteration of the node object.

I'm stumped as to why I need to set the $node->field_FIELD... manually when a dsm($node) before this line shows it's there already, but as I said, without it, field_attach_update won't fire.

There might be som bugs hidden here, but I'm not sure where/which function should take care of what... I would've thought the setHostEntity method would take care of updating the node with the new field collection field... but perhaps the problem is that I'm running this code in hook_node_insert. If you know, please enlighten us all :)