0

I am using Drupal 7.34 and I have a problem..

My module is reacting on node changes. When a node is updated one or more other nodes are automatically being updated, too. I call a function that triggers that update in hook_node_save.

Everything is fine until I try to make changes to the node that was initially saved and is passed to the hook_node_save. The reason is actually pretty obviuos: The changes prepared during the inital save process are overwriting the changes made during the function that is called in hook_node_save.

So here is my question with an example: I want to change field_a of node 100 after node 100 is updated from somewhere around the system. How do I achieve that while having access to the initially updated values of node 100?

Edit 1:

My hook_node_presave:

if (!$node->is_new) {
  $items = field_get_items('node', $node, 'field_oc_revision');
  if ($items) {
    _trigger_steps($items[0]['value'], $node);
  }
  debug($node);
}

The _trigger_steps() function changes the $node object passed by reference.

Now when I click save on a node form hook_node_presave is triggered twice. The first time the debug shows that the field is changed in the normal $node field, but not in the $node->original field. The second time the debug shows that the field is changed in the $node->original field, but not in the $node field.

Hope that gives more insight.

Edit 2:

One more thing to mention: When using the same code with manually calling $node = node_load(100); node_save($node); everything works like it should.

Edit 3: This is the part of the code of the _trigger_step function that is executed.

$connected_node = user_activity_get_step_base_node($base_nid, $step['connected_node_type']); // In this special case this loads the node that was just updated

$items_base_field_name = field_get_items('node', $connected_node, $step['base_field_name']); // $step is a definition of a step to trigger.

$expert_uid = $process['coordinator_user'];

$expert_nid = $items_base_field_name[0]['target_id'];
$expert_nid = node_load($expert_nid) ? $expert_nid : '';
// check if expert uid is set and node is not already linked
if($expert_uid && !$expert_nid) {
  $expert_node = new stdClass;
  $expert_node->type = $step['node_type'];
  node_object_prepare($expert_node);

  $expert_node->language = LANGUAGE_NONE;
  $expert_node->title = $node_type_names[$step['node_type']];
  $expert_node->uid = $expert_uid;
  $expert_node->promote = 0;
  // connect the nodes
  $expert_node->{$step['assignee_field_name']}[LANGUAGE_NONE][0]['target_id'] = $connected_node->nid;
  // tree assignment
  $expert_node->field_oc_revision[LANGUAGE_NONE][0]['value'] = $base_nid;
  $expert_node->field_oc_tree_element[LANGUAGE_NONE][0]['value'] = $step['sid'];

  // save new node
  node_save($expert_node);

  // if the updated node is the one that we want to change here, we just change the passed node. it is saved after hook_node_presave.
  if($updated_node) { // $updated_node is passed by reference
    $updated_node->{$step['base_field_name']}[LANGUAGE_NONE][0]['target_id'] = $expert_node->nid;
  // if not we set save it directly
  } else {
    $connected_node->{$step['base_field_name']}[LANGUAGE_NONE][0]['target_id'] = $expert_node->nid;
    node_save($connected_node); 
  }
}

Thanks a lot! cheers j

  • if you explain it bit more it will be use full – DEVARAJ JOHNSON Feb 17 '15 at 14:34
  • We'd need to see what _trigger_steps is doing – Clive Feb 17 '15 at 15:15
  • Well.. this function is like 750 lines of code.. I will try to shrink it to what it really does.. One more thing to mention: When using the same code with manually calling $node = node_load(100); node_save($node); everything works like it should. – schlicki Feb 17 '15 at 15:16
  • I added the code of the _trigger_step function – schlicki Feb 17 '15 at 15:34
  • I found the problem in another module. It is solved now. Thanks! – schlicki Feb 18 '15 at 8:11
0

After a long night of debugging I finally found the bug. I always thought that hook_node_presave is called twice when submitting a form. That is wrong. Took me a while to find out.

I then searched for node_save operations in my code through like 20 modules and found a module calling node_save in a custom node form submission handler. I removed it and it works now.

Thank you all for your help!

|improve this answer|||||

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.