Problem/Motivation
hook_comment_publish() and hook_comment_unpublish() are documented to exist. However, they are not really being invoked correctly. See Comment::postSave():
if ($this->isPublished()) {
\Drupal::moduleHandler()->invokeAll('comment_publish', array($this));
}
So the publish hook is being invoked every time a comment is saved and it is currently published (whether or not it was previously published), and as far as I can tell, the unpublish hook is not being invoked at all.
And (see comment #2/Berdir) we probably do not need these hooks anyway, because you can use the generic update hooks and look at the original comment to see if its published status has changed.
Proposed resolution
Remove these two hooks from the comment.api.php file, and from being invoked in the postSave() method.
Alternative proposal: Invoke them as they are documented to be invoked (if the publishing status is being changed to published/unpublished).
Remaining tasks
a) Write a patch, get it reviewed.
b) Write a short change notice describing how to use other hooks to achieve the same purpose.
User interface changes
None.
API changes
No hook_comment_publish() or hook_comment_unpublish().
Original report by jhodgdon
While I was working on #2216535: Replace Node overview topic and Node API topic with Entity Hooks topic, I noticed several problems with the entity hooks:
a) When the entity CRUD hooks are invoked, the generic ones like hook_entity_create() and hook_entity_load() all have the entity type ID passed in. This was not documented in most of the hook documentation in entity.api.php (I'm fixing that).
However, this is not being tested in entity_crud_hook_test.module where it tests all the entity CRUD hooks. I think that should be fixed?
b) Inconsistency: In all cases but one, the EntityStorageBase::invokeHook() method is used to invoke the entity hooks from the storage controller. This makes the type-specific hook run before the generic hook (hook_ENTITY_TYPE_create() before hook_entity_create() for instance).
However, during load it goes in the opposite order. It seems like this should be reversed? See EntityStorageBase::postLoad().
Comment | File | Size | Author |
---|---|---|---|
#17 | 2294375-comment-hooks-17.patch | 6.3 KB | jhodgdon |
#10 | 2294375-comment-hooks-9.patch | 5.86 KB | jhodgdon |
Comments
Comment #1
jhodgdonMore to address:
c) I do not think that hook_comment_publish() and hook_comment_unpublish() are being invoked correctly. See Comment::postSave()
https://api.drupal.org/api/drupal/core!modules!comment!src!Entity!Commen...
It looks like the publish hook is being invoked on every save if the comment is now published, and the unpublish hook is not being invoked???
Comment #2
BerdirSo we fixed a) in a separate issue by removing that.
b) Yeah, possibly.
c) Not sure why we even have those hooks, it's really not that hard to check it yourself now with $comment->original.
Comment #3
BerdirNote that c), unlike a/b is a comment specific problem, should possibly be a separate issue to discuss what to do with them? Agree that they are broken, so maybe just remove them as a "fix"...
Comment #4
jhodgdonWell, it looks like the comment hook is the only real relevant issue left on this one (I'm giving up worrying about the fact that the load() hooks run in backwards order from all other hooks; if you think it's worth pursuing, we can pursue it elsewhere).
So, repurposing this issue.
Comment #5
jhodgdonHere's the easy patch.
For the change notice, I think we could write this:
------
Title:
hook_comment_publish() and hook_comment_unpublish() have been removed
Body:
hook_comment_publish() and hook_comment_unpublish() have been removed in Drupal 8.x.
You can react to an update that changes the published status of a comment by using hook_entity_update(), or better yet hook_ENTITY_TYPE_update(). This will have $entity->original set to the original entity, before the changes.
Example in Drupal 7:
Drupal 8:
-------------
Thoughts? I can make a draft change notice, but since I am not sure the approach has been agreed to, I didn't do that yet.
Comment #7
jhodgdonIt looks like Forum and Tracker modules were relying on the (flawed) hook_comment_publish() invoke. Their hook implementations will need to be updated.
Comment #8
jhodgdonOK. Turns out node.module also implemented these two hooks, but since it also had a hook_comment_update(), it was pointless to do it again in those two hooks. The forum and tracker hook situation is I think a lot cleaner without these two hooks too, since (again) they were doing pretty much the same thing in the update hooks too.
This is seeming like a better and better idea...
Comment #10
jhodgdonOh, should fix a few docs things... and the non-working patch... interdiff failed...
Comment #12
jhodgdonOK, I give up. I don't get why using the update hook is failing. Maybe the comment storage class is doing something weird to bypass those hooks.
Anyway, the publish/unpublish hooks are not being invoked as they are documented and *something* needs to be done... I am just not sure what now.
Comment #13
larowlanSee #2289369: hook_comment_unpublish is never invoked
Comment #14
jhodgdonYeah, this issue should be a duplicate of that other one.
Comment #15
jhodgdonComment #16
jhodgdonI changed my mind. This issue is also about the publish hook, and the other one is only about unpublish.
Comment #17
jhodgdonOne more try on a patch. I think forum/tracker may need hook_comment_insert() done too.
Comment #18
larowlanShould these be replaced with comment_{insert,update} hooks too?
Thanks for working on this!
Comment #19
jhodgdonIf this works, here's a new proposed change notice:
=============
------
Title:
hook_comment_publish() and hook_comment_unpublish() have been removed
Body:
hook_comment_publish() and hook_comment_unpublish() have been removed in Drupal 8.x.
You can react to an update that changes the published status of a comment by using hook_entity_update(), hook_entity_insert(), or better yet hook_ENTITY_TYPE_update() and hook_ENTITY_TYPE_insert().
The update hooks will have $entity->original set to the original entity, before the changes.
Example in Drupal 7:
Drupal 8:
===============
Comment #20
jhodgdonRE #18 - no, the node module already has insert/update comment hooks in it. No additional publish/unpublish hooks are necessary.
Comment #21
andypost+1 to rtbc and removal, confirm #20
we could update https://www.drupal.org/node/2112417 change record for that and others anyway
Comment #22
jhodgdonI do not see this as being really related to that other change record. I also think having the hook names in the change record title is important. So I think we should make a separate change record.
The tests passed on the latest patch, so I will go ahead and make a draft change record.
Comment #23
BerdirThis looks great, the hooks were used when the mass publish/unpublish did not save comments as whole entities, but that was changed a long time ago.
Nice how the resulting code is actually easier in all cases.
Comment #26
andypostComment #27
alexpottCommitted ddaba8b and pushed to 8.x. Thanks!