function hook_node_insert

You are here

7 node.api.php hook_node_insert($node)
8 node.api.php hook_node_insert(\Drupal\node\NodeInterface $node)

Respond to creation of a new node.

This hook is invoked from node_save() after the database query that will insert the node into the node table is scheduled for execution, after the type-specific hook_insert() is invoked, and after field_attach_insert() 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 created.

Related topics

14 functions implement hook_node_insert()

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

book_node_insert in modules/book/book.module
Implements hook_node_insert().
comment_node_insert in modules/comment/comment.module
Implements hook_node_insert().
entity_crud_hook_test_node_insert in modules/simpletest/tests/entity_crud_hook_test.module
Implements hook_node_insert().
forum_node_insert in modules/forum/forum.module
Implements hook_node_insert().
menu_node_insert in modules/menu/menu.module
Implements hook_node_insert().

... See full list

2 invocations of hook_node_insert()
field_attach_insert in modules/field/field.attach.inc
Save field data for a new entity.
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 517
Hooks provided by the Node module.

Code

function hook_node_insert($node) {
  db_insert('mytable')->fields(array(
    'nid' => $node->nid,
    'extra' => $node->extra,
  ))->execute();
}

Comments

These docs are wrong. The query to add the node has already been executed at this point, so you do have access to the nid.

nid is there, but if you fetch database it won't be there, because transactions is not finished yet.

You have access to node->nid all right, but you cannot use node_save() in this context. You will get an error. I think it is because it will create a new node with the same nid.
You can actually have the nid before saving.

You wrote:

you cannot use node_save() in this context

But, you can use node_save in this context!

Example: I want to add a statuspost to the wall whenever a blog post is added.

<?php
function notify_node_insert($node) {
 
$statustext = '';
  global
$user;
  switch (
$node->type) {
    case
'blog_post':
     
$statustext = "New blog posted: " . l($n->title, "user/{$user->uid}/node/{$n->nid}");
      break;
  }
  if (!empty(
$statustext)) {
   
$title = "New $node->type: $node->title";
   
notify_insert_statuspost($title, $statustext);
  }
}

function

notify_insert_statuspost($title, $statustext) {
  global
$user;
 
$node = new stdClass();
 
$node->title = $title;
 
$node->type = "statuspost";
 
node_object_prepare($node); // Sets some defaults. Invokes hook_prepare() and hook_node_prepare().
 
$node->language = LANGUAGE_NONE; // Or e.g. 'en' if locale is enabled
 
$node->body[$node->language][0]['value']   = $statustext;
 
$node->uid = $user->uid;
 
$node->status = 1; //(1 or 0): published or not
 
$node->promote = 0; //(1 or 0): promoted to front page
 
$node->comment = 2; // 0 = comments disabled, 1 = read only, 2 = read/write
 
$node = node_submit($node); // Prepare node for saving
 
node_save($node);
}
?>

You have access to node->nid all right, but you cannot use node_save() in this context. You will get an error. I think it is because it will create a new node with the same nid.
You can actually have the nid before saving.

Documentation states that "You should not rely on data in the database at this time as it is not updated yet." This is not always true (my insert hooks assume correctly that data has been written). It would be nice to embellish the documentation to explain under what circumstances this is and is not the case.

That is the question... So I wonder if nid will be ok to use or not? Why is it there anyways?

I think I'll have to put up a watchdog for every node view to check if nid in the alias and the actual nid are equal.

If you are confused by whether or not to trust the NID, read up on database transactions. Up until a transaction is committed via COMMIT, any queries run against the database are present only to your connection. Effectively this means the node appears to have saved for your connection. If anything happens to cause a ROLL BACK instead of COMMIT, no work will actually be done on the db connection; the transaction will be rolled back and the NID will be invalid.

Since you are in the middle of a transaction, as long as you use the drupal db connection for db queries, db transactions you perform will be treated atomically along with the node_save operation; if the node fails to save, your db changes will be rolled back along with the node save operation.

The short of it is that yes, you can trust the NID for queries that use the drupal db connection. Using a different database connection/saving to the filesystem etc. could leave you in an inconsistent state.

Documentation also states clearly:
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.
So it's pointless to use node_load() for example.

In case it isn't clear...WARNING, if you implement this function, it will be called for EVERY node saved.

If you only want to handle certain node type, be sure to test against $node->type and act accordingly.

I hope this saves someone else the pain I just went through...I need a break...