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

2
  • 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
    Commented Nov 1, 2013 at 9:52
  • Yes sure, I removed all the unnecessary code to focus the problem Commented Nov 4, 2013 at 9:46

2 Answers 2

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


}

}
5
  • 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. Commented Oct 31, 2013 at 16:31
  • am i wrong somewhere can u pls explain ?
    – harshal
    Commented Oct 31, 2013 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. Commented Oct 31, 2013 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. Commented Nov 1, 2013 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. Commented Nov 4, 2013 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 and acknowledge you have read our privacy policy.

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