1

I have a node type with two field_collection fields. When I save the node I need to write the entity_id of the first field_collection into the secondo field_collection. This is my code:

function mymodule_node_update($node){
    $entity_id = $node->field_collection_1['und'][0]['value'];
    $entiry_array = entity_load('field_collection_item',array(entity_id));
    $entity = array_shift($entity_array);

    if (empty($entity->field_reference['und'][0]['value'])) {
        $entity->field_reference['und'][0]['value'] = $node->field_collection_2['und'][0]['value'];
        $entity->save();
    }
}

There are 2 problems there: 1) in hook_node_update() data is not committed yet https://drupal.org/node/1677830 2) $entity->save() triggers again hook_node_update() (and in my opinion it shouldn't)

So at the end in $node->field_collection_1 I have the right id $node->field_collection_2 would have, but due to recursive call to hook_node_update() and the fact that in hook_node_update() data is not committed to database yet field_collection_2 entity and all changes made to the node vanish.

Can someone suggest me a possible solution?

Thank you

  • One thing to keep in mind if you choose to use hook_node_update(): That hook is called for ALL node types, so it's wise to check the $node->type. – hargobind Nov 1 '13 at 9:52
  • Yes sure, I removed all the unnecessary code to focus the problem – LateAtNight Nov 4 '13 at 9:46
5

hook_node_presave($node)

Act on a node being inserted or updated.

This hook is invoked from node_save() before the node is saved to the database. Parameters

$node: The node that is being inserted or updated.

function hook_node_presave($node) {

if ($node->type == 'your_node_type') {
// you can write your desired code here


}

}
  • Just to add a word of clarification: the code should simply update the fields in the node object at this point, not save anything to the database. Drupal will do the database updates for you. – Alfred Armstrong Oct 31 '13 at 16:31
  • am i wrong somewhere can u pls explain ? – harshal Oct 31 '13 at 16:33
  • No, using presave is correct. But what the OP asked requires changes to some fields which are part of the node: they should be able to do that simply by altering the node object in this hook; they don't need to perform any DB updates themselves. – Alfred Armstrong Oct 31 '13 at 16:38
  • I don't understand what you are trying to do here, nor what relevance it has to the original question, sorry. Perhaps you should raise a question of your own where you explain more fully. – Alfred Armstrong Nov 1 '13 at 9:13
  • I'm not sure node_hook_presave() is the solution. During this hook the node still transient so I don't have the field_collection_2 entity_id. – LateAtNight Nov 4 '13 at 9:54
0

If you want to guarantee that everything including access rights is written to the database, you can register a shutdown function in one of the node hooks. You do that with drupal_register_shutdown_function passing in an arbitrary function name and the arguments. Here's how it might look for your case in hook_node_update:

function mymodule_node_update($node) {
  // only register shutdown for node of the right type
  // let's assume the node content type is 'foobar'
  if ($node->type == 'foobar') {
    drupal_register_shutdown_function('node_voodoo_on_shutdown', $node);
  }
}

function node_voodoo_on_shutdown($node) {
    $entity_id = $node->field_collection_1['und'][0]['value'];
    $entity = entity_load_single('field_collection_item',entity_id);

    if (empty($entity->field_reference['und'][0]['value'])) {
        $entity->field_reference['und'][0]['value'] = $node->field_collection_2['und'][0]['value'];
        $entity->save();
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.