7.x node.api.php hook_node_update($node)

Respond to updates to a node.

This hook is invoked from node_save() after the database query that will update node in the node table is scheduled for execution, after the type-specific hook_update() is invoked, and after field_attach_update() is called.

Note that when this hook is invoked, the changes have not yet been written to the database, because a database transaction is still in progress. The transaction is not finalized until the save operation is entirely completed and node_save() goes out of scope. You should not rely on data in the database at this time as it is not updated yet. You should also note that any write/update database queries executed from this hook are also not committed immediately. Check node_save() and db_transaction() for more info.

Parameters

$node: The node that is being updated.

Related topics

12 functions implement hook_node_update()

Note: this list is generated by pattern matching, so it may include some functions that are not actually implementations of this hook.

book_node_update in modules/book/book.module
Implements hook_node_update().
entity_crud_hook_test_node_update in modules/simpletest/tests/entity_crud_hook_test.module
Implements hook_node_update().
forum_node_update in modules/forum/forum.module
Implements hook_node_update().
menu_node_update in modules/menu/menu.module
Implements hook_node_update().
node_access_test_node_update in modules/node/tests/node_access_test.module
Implements hook_node_update().

... See full list

3 invocations of hook_node_update()
field_attach_update in modules/field/field.attach.inc
Save field data for an existing entity.
update_check_requirements in ./update.php
Checks update requirements and reports errors and (optionally) warnings.
user_save in modules/user/user.module
Save changes to a user account or add a new user.

File

modules/node/node.api.php, line 717
Hooks provided by the Node module.

Code

function hook_node_update($node) {
  db_update('mytable')
    ->fields(array('extra' => $node->extra))
    ->condition('nid', $node->nid)
    ->execute();
}

Comments

grayb’s picture

Into reading the above and thinking that your node has already been saved. I ran into a situation where I was doing a node_load on the nid of the passed node, which would provide me with the OLD values - the ones that should have been replaced before this hook was invoked.

function hook_node_update($node) {
     // Provides the "updated" values
     dpm($node);

     $loaded_node = node_load($node->nid);
     // Provides the old values, which shouldn't be there according
     // to the documentation above
     dpm($loaded_node);
}
bdragon’s picture

node_save() doesn't clear the cached node until later, so you're still getting the cached one. This is by design.

themrb’s picture

I just spent hours getting tripped up by this one, it should really be mentioned in the description.

FIX FOR FUTURE READERS: Call
entity_get_controller('node')->resetCache(array($node->nid));

David_Rothstein’s picture

I ran into this, and I'm pretty sure it's a bug and not by design.

(Nodes already have $node->original when they're passed to this hook if you need access to the pre-saved version. But calling node_load() should really always return something that reflects the current state of the database, and it seems like a bug if it doesn't.)

This is being discussed in the issue queue at http://drupal.org/node/221081. It looks like it's on its way to getting fixed for Drupal 8 (as part of other conversions that are happening there). For backwards-compatibility reasons I'm not sure if it can be fixed in Drupal 7, but it's at least worth discussing in that issue.

unnikrishnan’s picture

$loaded_node = node_load($node->nid, NULL, TRUE);
I think this will work for you. We have a reset flag in node_load function

Thanks
Unnikrishnan B.

valderama’s picture

i think the problem is, that the loaded node comes from the cache - which still holds the old values as the cache is cleared at the end of the update (technically the cache clear code is at the beginning, but because of a DB transaction it is called at the end)

if I remember correctly - please check the corresponding code if in doubt (as always ;)

NancyDru’s picture

The old values are in $node->original.

megadesk3000’s picture

On hook_node_update the old values are saved in $node->original.

mxh’s picture

Use hook_node_presave() if you want to alter basic node properties like $node->log before the node gets stored in db. Also if you are about to manipulate field values, I'd prefer hook_node_presave() to hook_node_update(), because then you don't have to extra call field_attach_update(). This might be more efficient than doing this in hook_node_update().

stevieegee’s picture

$original = entity_metadata_wrapper('node', $node->original); doesn't work with this hook (it returns ('node', $node)), although it should according to the documentation and works with hook_node_presave. Any ideas?

NancyDru’s picture

Clone the value, then wrap that.

sinasalek’s picture

Currently Drupal core does not offer any hook to do actions after a node/entity is inserted/updated/deleted in Database. So for example you can not send an email mentioning the node after the node is inserted because Drupal uses SQL transactions and the node is not yet fully written to database when hook node presave is called so if for any reason the transaction is rolled back, users will receive a false mail.

So Hook Post Action module introduces several new Drupal hooks to overcome this limitation:
- hook_entity_postsave
- hook_entity_postinsert
- hook_entity_postupdate
- hook_entity_postdelete
- hook_node_postsave
- hook_node_postinsert
- hook_node_postupdate
- hook_node_postdelete

https://drupal.org/project/hook_post_action