Drupal 7 post insert hooks as a shutdown function
Have you ever needed to perform an action after a node has been inserted or updated? In this article we are going to see how we can trigger functionality after nodes have been inserted or updated. And no, it's probably not what you think.
By default, there is no hook that provides this in Drupal core. Sure, you have hook_node_insert()
, hook_node_update()
and hook_node_presave()
but all of these are called within the scope of node_save()
. This is important because, at this point, we cannot rely on the database for any data that may have been affected by the node save process. As the documentation for hook_node_insert()
says:
when this hook is invoked, the changes have not yet been written to the database, because a database transaction is still in progress.
When you have to deal with something totally external to the node in question, this may not be a problem. Heck, you might not even need the database. But there are those one or two cases in which you do need data that has been affected by the process.
For example, when inserting a new node, various actions take place. One of them can be Pathauto doing some magic with the node title and saving a path alias for this node. So if you need to alter this final alias in the scope of hook_node_insert()
, you cannot rely on something like path_load()
to get the node alias data because it might have not yet been written. I've actually seen it return different things in different cases.
What you can do then is register a function with Drupal that will get called just about when Drupal is finished with the request. It's actually very simple. You just call drupal_register_shutdown_function() with the name of the function you want to be called. Additionally, you can pass as further arguments whatever it is in your context you want passed to it. It's kinda like subscribing a function to an event.
So now when the request is finishing, we know the node_save()
database transaction has completed and we can rely on the data from the database. Using path_load()
now will guarantee that the latest path for that node is being loaded.
Hope this helps.