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.
Daniel Sipos
Danny founded WEBOMELETTE in 2012 as a passion project, mostly writing about Drupal problems he faced day to day, as well as about new technologies and things that he thought other developers would find useful. Now he now manages a team of developers and designers, delivering quality products that make businesses successful.
Comments
Hi,
Hi,
Nice article.
In case it can help, the Hook Post Action module follows that exact method to expose several hooks that allow you to act after an entity has been inserted / updated / deleted.
https://www.drupal.org/project/hook_post_action
There is already a module for
There is already a module for that :)
https://www.drupal.org/project/hook_post_action
In reply to There is already a module for by John (not verified)
:) Yes there is, but
:) Yes there is, but sometimes you may not need the entire thing just for one small use case. And knowing the power of
drupal_register_shutdown_function()
can be very helpful in other contexts as well :)In reply to :) Yes there is, but by admin
have any example drupal
have any example drupal_register_shutdown_function ()
Thanks
nice one!
Thanks for sharing!
There is a hook to alter the
There is a hook to alter the alias before it is saved: hook_pathauto_alias_alter().
nice
Thanks Danny for informative article. I usually use module for this...However, your guide also is very helpful.
David
Debug inside a drupal_register_shutdown_function callback
Note that you will not be able to dsm() or var_dump() inside a drupal_register_shutdown_function callback function.
You may use your favorite IDE debugger (solution which I've not tested), or like me you can use an output file :
In reply to Debug inside a drupal_register_shutdown_function callback by Mattew (not verified)
dd()
Wouldn't
dd()
function work in this case as well?Great solution
Thank you Danny, you saved my day!
I need this solution for a client site with very complex forms using paragraphs and field_collection modules. To gain overall delivery performance i decided to prerender the 'body' part of the node content as drupal render items and store them serialized into a custom module table. Because some of the nodes are a sort of aggregation pages which show teasers of other nodes and therefore they need to be updated as well when an editor updates a teaser node.
The drupal_register_shutdown_function makes this implementation easy, clean and handy.
Thanx for that.
btw: referring to debugging opportunities inside the shutdown callback you can write as well to watchdog.
nice article
exactly wat i needed
Add new comment