Post-save callback?
Asked Answered
A

5

12

How do I execute a function every time a node is being updated? I tried to use hook_nodeapi, but it looks like that the hook is removed from Drupal 7.

What I want to do is,

  1. add a new field to my content type called 'main image (bool)' to let the admin set a main image.
  2. I am going to use Views module to display nodes, but order nodes by 'main image' field and added date.
  3. so that the first node is always the main image.

to do this, I need to make sure that there is always only one node with 'main image' set to true.

Abbevillian answered 15/3, 2011 at 7:0 Comment(3)
Instead of adding Drupal 7 to the question title, you can use the drupal-7 tag, that saves you some space.Gobbledygook
Edited the post according to Berdir's suggestion. By the way, there is a Stack Exchange site dedicate to Drupal now: drupal.stackexchange.com.Lipid
@Lipid // thank you for the editing and drupal site!Abbevillian
G
11

The hook has not been removed but splitted up into separate hooks for each $op.

See: http://api.drupal.org/api/search/7/hook_node

For post-save, you want hook_node_insert() and hook_node_update()

Gobbledygook answered 15/3, 2011 at 7:4 Comment(3)
The node isn't completely saved at that moment, because the transaction isn't committed yet.Immoral
As Jorrit said, this isn't correct as the transaction is still open.Fervid
The node is completely saved from the perspective of the executed code, queries over the DB will work as expected and find the node data because they will be executed inside the transaction. This definition of 'completely saved' fits the OP use-case.Moncada
I
16

Currently Drupal core does not offer any hook to do actions after a node/entity is inserted/updated/deleted in Database. 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

Imperforate answered 4/6, 2014 at 11:7 Comment(2)
Thanks - this looks useful. I wanted to rebuild my sitemap.xml after nodes are added, deleted or updated so this looks perfect for my needs. I've installed it and all seems to be working perfectly too :)Ploy
I tried using it in our project. Initially, it worked, but after some time we noticed some memory leaks being supposedly caused by it. Not sure if it's something in our D7 application though.Drawers
G
11

The hook has not been removed but splitted up into separate hooks for each $op.

See: http://api.drupal.org/api/search/7/hook_node

For post-save, you want hook_node_insert() and hook_node_update()

Gobbledygook answered 15/3, 2011 at 7:4 Comment(3)
The node isn't completely saved at that moment, because the transaction isn't committed yet.Immoral
As Jorrit said, this isn't correct as the transaction is still open.Fervid
The node is completely saved from the perspective of the executed code, queries over the DB will work as expected and find the node data because they will be executed inside the transaction. This definition of 'completely saved' fits the OP use-case.Moncada
M
7

I suppose hook_entity_presave could be the hook you're looking for, if you want to act before your node is updated :

Act on an entity before it is about to be created or updated.


Or, if you prefer acting after it's updated, take a look at hook_entity_update :

Act on entities when updated.

Mackler answered 15/3, 2011 at 7:4 Comment(0)
U
7

Just to complete this a bit more and if you need to perform any operation after the node has been saved/updated you can use the module @sina-salek has recommended you or you can use this code:

// Same for hook_node_save!
function my_module_node_update($node) {
  if ($node->type == 'content_type_name') {
    // Invoke your callback function AFTER the node is updated.
    drupal_register_shutdown_function('_my_module_the_function_to_call', $node);
  }
}


function _my_module_the_function_to_call($node) {
  // do stuff...
}

By using the drupal_register_shutdown_function you are making sure to call your custom function when the hook has finished and the node has been persisted on the DB.

Unwearied answered 4/9, 2017 at 14:10 Comment(1)
This is the smallest and most simple solution.Ivanivana
E
1

Another way this can be achieved is by extending the Node entity with your custom class and calling your code inside the Node::postSave method. This method will get called when node gets saved or updated.

You specify your custom extended class by implementing hook called hook_entity_type_build and provide your new class, e.g.: $entity_types['node']->setClass(NodeExtended::class)

Inside your class you than override postSave method. I usually just dispatch my custom event here so other modules can subscribe to this node post save event, but that's another topic.

Esquire answered 3/10, 2019 at 10:57 Comment(1)
I found out that postSave is called before hook_entity_update though. Is there a postUpdate event to bind on ?Sanction

© 2022 - 2024 — McMap. All rights reserved.