Problem/Motivation

In order to intercept an entity after it has saved, both hook_entity_insert and hook_entity_update must be implemented.

Proposed resolution

Add hook_entity_postsave. Detect if entity is new or being updated using entity API: $entity->isNew()

Remaining tasks

User interface changes

None

API changes

Deprecate hook_entity_[type_]insert and hook_entity_[type_]update.

Data model changes

Original report by ivanjaros

We already have a hook_entity_presave hook so why don't we also have hook_entity_postsave?
In current state if I want to run some logic after the entity hase been saved, and I don't care if it is/was new or already existing entity, I have to implement TWO hooks instead of just one: hook_entity_insert AND hook_entity_update.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

dpi’s picture

I was thinking the same today.

swentel’s picture

Version: 8.0.x-dev » 8.1.x-dev

I think the rational at some point was to not have any $op parameters anymore in hooks, which in the days of hook_nodeapi() made sense, because everything passed through that hook. Ironically, if you take the rational strict, there should have been an presave_insert and presave_update :-)

If we'd introduce post_save, then _insert and _update in a way don't make any sense anymore and those should be removed because you can all isNew() to figure out if it's a new or existing (although we can't for BC reasons). I agree, if you don't care about it, it's kind of tedious having to implement those two hooks, I actually could have used it as well.

Features are 8.1 though.

Anonymous’s picture

To me, this would make more sense to me hook_entity_presave($entity, $is_new) and hook_entity_postsave($entity, $was_new) than of hook_entity_presave($entity) and hook_entity_insert($entity) / hook_entity_update($entity).

Sure, if we have isNew() then no $op is not needed as mentioned.

dpi’s picture

Issue summary: View changes

Sounds reasonable to me. Added standard template.

dpi’s picture

Issue summary: View changes

extra words

drikc’s picture

Status: Active » Needs review
FileSize
9.28 KB

The attached patch add the hook_entity_postsave() call right after the hook_entity_insert()/update() call. I may also remove the hook_entity_insert()/update() tests since they will be deprecated!?...

Remaining things I'm thinking off:
- Update core/lib/Drupal/Core/Entity/entity.api.php
- ...

swentel’s picture

Hmm no, we shouldn't remove tests as long it's there.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.0-beta1 was released on March 2, 2016, which means new developments and disruptive changes should now be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

tstoeckler’s picture

dpi’s picture

tim.plunkett’s picture

Closing my issue. Please copy over the api.php changes as well as the @todo/deprecation comments.

dpi’s picture

Berdir’s picture

Status: Needs review » Needs work

I don't think that isNew() works, would definitely need more specific tests than just checking that it is called.

At this point, the entity is no longer new as it has been saved already. That's why we pass the additional flag to postSave().

Also agreed that if we do this, we should deprecate the other two hooks.

AaronBauman’s picture

Adding related events-dispatching discussion, which will require a re-roll here if it lands first.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Carlitus’s picture

¿This will be added to core?

hchonov’s picture

Re #15:

I don't think that isNew() works, would definitely need more specific tests than just checking that it is called.

At this point, the entity is no longer new as it has been saved already. That's why we pass the additional flag to postSave().

Well this actually has the answer in it :). The post save hook should be consistent with the postSave method and have a second parameter indicating whether this is an insert or update operation.

ravi.shankar’s picture

Added reroll of patch #6 on Drupal-9.2.x.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

MegaKeegMan’s picture

This seems like people participating in this thread have been in agreement that this change would be a good thing. I am also in a situation right now where I am needing to implement both insert and update, and dreaming of a hook_entity_postsave. Is there anything that can be done to keep this issue moving? I would be happy to assist with reviewing patches on D10 if that will help.

dpi’s picture

Had a thought, what if we call this hook hook_entity_upsert?

Since thats what DB's etc use. Our terminology cleanly already matches it with insert/update.

MegaKeegMan’s picture

I don't have particularly strong feelings about this, and would be okay with this direction. But I think I prefer postsave. For one, it will be clearer that this occurs later than presave. Additionally, insert, update, upsert, are all database language. Maybe my expectations are off, but I did not find this hook naming to be the most intuitive. I expect this will change between people, but as a Drupal developer I was looking for something closer to Drupal language, and not database language. I understand why insert is called insert, but it did not stand out to me as what I was looking for immediately. I think my prior point is the more important one for me. Though I am stating these preferences, I can appreciate the idea, and ultimately I really just want to see this feature in core, whatever the hook gets called.

jrockowitz’s picture

My immediate use case for a postsave hook is for a hook triggered after all insert or update hooks to an entity are executed. The immediate goal of this ticket is to simplify the entity API. My use case might be an edge case.

cosmicdreams’s picture

I found this issue as a result of an issue I reported to the estimated_read_time module https://www.drupal.org/project/estimated_read_time/issues/3427894

The logic of that module currently executes presave, but can possibly run into trouble when it uses data that only exists after the content is saved.

Without a postsave hook, we could use the Event Dispatcher to hook into entity.post_save. But it's weird there isn't a hook that fires AFTER all the entity saving.

I would appreciate having that today.