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.
Comment | File | Size | Author |
---|---|---|---|
#26 | 2221347-26.patch | 9.24 KB | ravi.shankar |
#6 | add_hook_entity_post_save_hook-2221347-6.patch | 9.28 KB | drikc |
Comments
Comment #1
dpiI was thinking the same today.
Comment #2
swentel CreditAttribution: swentel commentedI 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.
Comment #3
Anonymous (not verified) CreditAttribution: Anonymous commentedTo me, this would make more sense to me
hook_entity_presave($entity, $is_new)
andhook_entity_postsave($entity, $was_new)
than ofhook_entity_presave($entity)
andhook_entity_insert($entity)
/hook_entity_update($entity)
.Sure, if we have isNew() then no $op is not needed as mentioned.
Comment #4
dpiSounds reasonable to me. Added standard template.
Comment #5
dpiextra words
Comment #6
drikc CreditAttribution: drikc commentedThe 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
- ...
Comment #7
swentel CreditAttribution: swentel commentedHmm no, we shouldn't remove tests as long it's there.
Comment #11
tstoecklerMarked #2848894: new hook to cover both entity insert and update - hook_entity_postsave as duplicate.
Comment #12
dpi#2798783: hook_entity_insert() and hook_entity_update() are confusing is also a dupe.
Comment #13
tim.plunkettClosing my issue. Please copy over the api.php changes as well as the @todo/deprecation comments.
Comment #14
dpi#2798783: hook_entity_insert() and hook_entity_update() are confusing, for reference.
Comment #15
BerdirI 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.
Comment #16
AaronBaumanAdding related events-dispatching discussion, which will require a re-roll here if it lands first.
Comment #24
Carlitus CreditAttribution: Carlitus commented¿This will be added to core?
Comment #25
hchonovRe #15:
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.
Comment #26
ravi.shankar CreditAttribution: ravi.shankar at OpenSense Labs commentedAdded reroll of patch #6 on Drupal-9.2.x.
Comment #32
MegaKeegMan CreditAttribution: MegaKeegMan at Agaric for Drutopia, Portside commentedThis 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.
Comment #33
dpiHad 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.
Comment #34
MegaKeegMan CreditAttribution: MegaKeegMan at Agaric for Drutopia, Portside commentedI 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.
Comment #35
jrockowitz CreditAttribution: jrockowitz as a volunteer and at Webform module Open Collective, The Big Blue House commentedMy 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.
Comment #36
cosmicdreams CreditAttribution: cosmicdreams at Velir commentedI 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.