diff --git a/core/lib/Drupal/Core/Entity/EntityStorageBase.php b/core/lib/Drupal/Core/Entity/EntityStorageBase.php index f583121..b4eee90 100644 --- a/core/lib/Drupal/Core/Entity/EntityStorageBase.php +++ b/core/lib/Drupal/Core/Entity/EntityStorageBase.php @@ -467,6 +467,9 @@ protected function doPostSave(EntityInterface $entity, $update) { // Allow code to run after saving. $entity->postSave($this, $update); + $this->invokeHook('postsave', $entity); + // @todo hook_entity_insert() and hook_entity_update() are deprecated, + // remove this invocation once they are removed. $this->invokeHook($update ? 'update' : 'insert', $entity); // After saving, this is now the "original entity", and subsequent saves diff --git a/core/lib/Drupal/Core/Entity/entity.api.php b/core/lib/Drupal/Core/Entity/entity.api.php index 9f6ef8b..abe995d 100644 --- a/core/lib/Drupal/Core/Entity/entity.api.php +++ b/core/lib/Drupal/Core/Entity/entity.api.php @@ -938,6 +938,8 @@ function hook_ENTITY_TYPE_presave(Drupal\Core\Entity\EntityInterface $entity) { * * @ingroup entity_crud * @see hook_ENTITY_TYPE_insert() + * + * @deprecated Use hook_entity_postsave() instead. */ function hook_entity_insert(Drupal\Core\Entity\EntityInterface $entity) { // Insert the new entity into a fictional table of all entities. @@ -962,6 +964,8 @@ function hook_entity_insert(Drupal\Core\Entity\EntityInterface $entity) { * * @ingroup entity_crud * @see hook_entity_insert() + * + * @deprecated Use hook_ENTITY_TYPE_postsave() instead. */ function hook_ENTITY_TYPE_insert(Drupal\Core\Entity\EntityInterface $entity) { // Insert the new entity into a fictional table of this type of entity. @@ -986,6 +990,8 @@ function hook_ENTITY_TYPE_insert(Drupal\Core\Entity\EntityInterface $entity) { * * @ingroup entity_crud * @see hook_ENTITY_TYPE_update() + * + * @deprecated Use hook_entity_postsave() instead. */ function hook_entity_update(Drupal\Core\Entity\EntityInterface $entity) { // Update the entity's entry in a fictional table of all entities. @@ -1010,6 +1016,8 @@ function hook_entity_update(Drupal\Core\Entity\EntityInterface $entity) { * * @ingroup entity_crud * @see hook_entity_update() + * + * @deprecated Use hook_ENTITY_TYPE_postsave() instead. */ function hook_ENTITY_TYPE_update(Drupal\Core\Entity\EntityInterface $entity) { // Update the entity's entry in a fictional table of this type of entity. @@ -1022,6 +1030,80 @@ function hook_ENTITY_TYPE_update(Drupal\Core\Entity\EntityInterface $entity) { } /** + * Respond to creation or update of an entity. + * + * This hook runs once the entity storage has been updated. Note that hook + * implementations may not alter the stored entity data. If the entity is being + * updated, get the original entity object from $entity->original. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity object. + * + * @ingroup entity_crud + * @see hook_ENTITY_TYPE_postsave() + */ +function hook_entity_postsave(\Drupal\Core\Entity\EntityInterface $entity) { + if ($entity->original) { + // Insert the new entity into a fictional table of all entities. + db_insert('example_entity') + ->fields(array( + 'type' => $entity->getEntityTypeId(), + 'id' => $entity->id(), + 'created' => REQUEST_TIME, + 'updated' => REQUEST_TIME, + )) + ->execute(); + } + else { + // Update the entity's entry in a fictional table of all entities. + db_update('example_entity') + ->fields(array( + 'updated' => REQUEST_TIME, + )) + ->condition('type', $entity->getEntityTypeId()) + ->condition('id', $entity->id()) + ->execute(); + } +} + +/** + * Respond to creation or update of an entity of a particular type. + * + * This hook runs once the entity storage has been updated. Note that hook + * implementations may not alter the stored entity data. If the entity is being + * updated, get the original entity object from $entity->original. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity object. + * + * @ingroup entity_crud + * @see hook_entity_postsave() + */ +function hook_ENTITY_TYPE_postsave(\Drupal\Core\Entity\EntityInterface $entity) { + if ($entity->original) { + // Insert the new entity into a fictional table of all entities. + db_insert('example_entity') + ->fields(array( + 'type' => $entity->getEntityTypeId(), + 'id' => $entity->id(), + 'created' => REQUEST_TIME, + 'updated' => REQUEST_TIME, + )) + ->execute(); + } + else { + // Update the entity's entry in a fictional table of all entities. + db_update('example_entity') + ->fields(array( + 'updated' => REQUEST_TIME, + )) + ->condition('type', $entity->getEntityTypeId()) + ->condition('id', $entity->id()) + ->execute(); + } +} + +/** * Acts when creating a new entity translation. * * This hook runs after a new entity translation object has just been diff --git a/core/modules/book/book.module b/core/modules/book/book.module index ecccb74..342971a 100644 --- a/core/modules/book/book.module +++ b/core/modules/book/book.module @@ -257,18 +257,9 @@ function book_node_presave(EntityInterface $node) { } /** - * Implements hook_ENTITY_TYPE_insert() for node entities. + * Implements hook_ENTITY_TYPE_postsave() for node entities. */ -function book_node_insert(EntityInterface $node) { - /** @var \Drupal\book\BookManagerInterface $book_manager */ - $book_manager = \Drupal::service('book.manager'); - $book_manager->updateOutline($node); -} - -/** - * Implements hook_ENTITY_TYPE_update() for node entities. - */ -function book_node_update(EntityInterface $node) { +function book_node_postsave(EntityInterface $node) { /** @var \Drupal\book\BookManagerInterface $book_manager */ $book_manager = \Drupal::service('book.manager'); $book_manager->updateOutline($node); diff --git a/core/modules/content_moderation/content_moderation.module b/core/modules/content_moderation/content_moderation.module index 582242b..a3cfffb 100644 --- a/core/modules/content_moderation/content_moderation.module +++ b/core/modules/content_moderation/content_moderation.module @@ -91,21 +91,16 @@ function content_moderation_entity_presave(EntityInterface $entity) { } /** - * Implements hook_entity_insert(). + * Implements hook_entity_postsave(). */ -function content_moderation_entity_insert(EntityInterface $entity) { - return \Drupal::service('class_resolver') - ->getInstanceFromDefinition(EntityOperations::class) - ->entityInsert($entity); -} - -/** - * Implements hook_entity_update(). - */ -function content_moderation_entity_update(EntityInterface $entity) { - return \Drupal::service('class_resolver') - ->getInstanceFromDefinition(EntityOperations::class) - ->entityUpdate($entity); +function content_moderation_entity_postsave(EntityInterface $entity) { + $entity_operation = \Drupal::service('class_resolver')->getInstanceFromDefinition(EntityOperations::class); + if ($entity->isNew()) { + return $entity_operation->entityInsert($entity); + } + else { + return $entity_operation->entityUpdate($entity); + } } /** diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module index 8d4a9f4..347298d 100644 --- a/core/modules/forum/forum.module +++ b/core/modules/forum/forum.module @@ -256,18 +256,9 @@ function forum_node_storage_load($nodes) { } /** - * Implements hook_ENTITY_TYPE_update() for comment entities. + * Implements hook_ENTITY_TYPE_postsave() for comment entities. */ -function forum_comment_update(CommentInterface $comment) { - if ($comment->getCommentedEntityTypeId() == 'node') { - \Drupal::service('forum.index_storage')->updateIndex($comment->getCommentedEntity()); - } -} - -/** - * Implements hook_ENTITY_TYPE_insert() for comment entities. - */ -function forum_comment_insert(CommentInterface $comment) { +function forum_comment_postsave(CommentInterface $comment) { if ($comment->getCommentedEntityTypeId() == 'node') { \Drupal::service('forum.index_storage')->updateIndex($comment->getCommentedEntity()); } diff --git a/core/modules/node/node.module b/core/modules/node/node.module index 5c86a13..075b3e1 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -1332,9 +1332,9 @@ function node_reindex_node_search($nid) { } /** - * Implements hook_ENTITY_TYPE_insert() for comment entities. + * Implements hook_ENTITY_TYPE_postsave() for comment entities. */ -function node_comment_insert($comment) { +function node_comment_postsave($comment) { // Reindex the node when comments are added. if ($comment->getCommentedEntityTypeId() == 'node') { node_reindex_node_search($comment->getCommentedEntityId()); @@ -1342,16 +1342,6 @@ function node_comment_insert($comment) { } /** - * Implements hook_ENTITY_TYPE_update() for comment entities. - */ -function node_comment_update($comment) { - // Reindex the node when comments are changed. - if ($comment->getCommentedEntityTypeId() == 'node') { - node_reindex_node_search($comment->getCommentedEntityId()); - } -} - -/** * Implements hook_ENTITY_TYPE_delete() for comment entities. */ function node_comment_delete($comment) { diff --git a/core/modules/tracker/tracker.module b/core/modules/tracker/tracker.module index 1b2f648..019f038 100644 --- a/core/modules/tracker/tracker.module +++ b/core/modules/tracker/tracker.module @@ -166,20 +166,9 @@ function _tracker_user_access($account) { } /** - * Implements hook_ENTITY_TYPE_insert() for node entities. - * - * Adds new tracking information for this node since it's new. - */ -function tracker_node_insert(NodeInterface $node, $arg = 0) { - _tracker_add($node->id(), $node->getOwnerId(), $node->getChangedTime()); -} - -/** - * Implements hook_ENTITY_TYPE_update() for node entities. - * - * Adds tracking information for this node since it's been updated. + * Implements hook_ENTITY_TYPE_postsave() for node entities. */ -function tracker_node_update(NodeInterface $node, $arg = 0) { +function tracker_node_postsave(NodeInterface $node) { _tracker_add($node->id(), $node->getOwnerId(), $node->getChangedTime()); } @@ -198,29 +187,20 @@ function tracker_node_predelete(EntityInterface $node, $arg = 0) { } /** - * Implements hook_ENTITY_TYPE_update() for comment entities. + * Implements hook_ENTITY_TYPE_postsave() for comment entities. */ -function tracker_comment_update(CommentInterface $comment) { +function tracker_comment_postsave(CommentInterface $comment) { if ($comment->getCommentedEntityTypeId() == 'node') { if ($comment->isPublished()) { _tracker_add($comment->getCommentedEntityId(), $comment->getOwnerId(), $comment->getChangedTime()); } - else { + elseif (!$comment->isNew()) { _tracker_remove($comment->getCommentedEntityId(), $comment->getOwnerId(), $comment->getChangedTime()); } } } /** - * Implements hook_ENTITY_TYPE_insert() for comment entities. - */ -function tracker_comment_insert(CommentInterface $comment) { - if ($comment->getCommentedEntityTypeId() == 'node' && $comment->isPublished()) { - _tracker_add($comment->getCommentedEntityId(), $comment->getOwnerId(), $comment->getChangedTime()); - } -} - -/** * Implements hook_ENTITY_TYPE_delete() for comment entities. */ function tracker_comment_delete(CommentInterface $comment) { diff --git a/core/modules/user/user.module b/core/modules/user/user.module index 90b813f..1e72ea8 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -977,11 +977,11 @@ function user_role_names($membersonly = FALSE, $permission = NULL) { } /** - * Implements hook_ENTITY_TYPE_insert() for user_role entities. + * Implements hook_ENTITY_TYPE_postsave() for user_role entities. */ -function user_user_role_insert(RoleInterface $role) { +function user_user_role_postsave(RoleInterface $role) { // Ignore the authenticated and anonymous roles or the role is being synced. - if (in_array($role->id(), array(RoleInterface::AUTHENTICATED_ID, RoleInterface::ANONYMOUS_ID)) || $role->isSyncing()) { + if (!$role->isNew() || in_array($role->id(), array(RoleInterface::AUTHENTICATED_ID, RoleInterface::ANONYMOUS_ID)) || $role->isSyncing()) { return; } diff --git a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityStorageTest.php b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityStorageTest.php index 6f02023..5012722 100644 --- a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityStorageTest.php +++ b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityStorageTest.php @@ -315,9 +315,15 @@ public function testSaveInsert(EntityInterface $entity) { ->with('entity_presave'); $this->moduleHandler->expects($this->at(2)) ->method('invokeAll') - ->with('test_entity_type_insert'); + ->with('test_entity_type_postsave'); $this->moduleHandler->expects($this->at(3)) ->method('invokeAll') + ->with('entity_postsave'); + $this->moduleHandler->expects($this->at(4)) + ->method('invokeAll') + ->with('test_entity_type_insert'); + $this->moduleHandler->expects($this->at(5)) + ->method('invokeAll') ->with('entity_insert'); $this->entityQuery->expects($this->once()) @@ -387,9 +393,15 @@ public function testSaveUpdate(EntityInterface $entity) { ->with('entity_presave'); $this->moduleHandler->expects($this->at(2)) ->method('invokeAll') - ->with('test_entity_type_update'); + ->with('test_entity_type_postsave'); $this->moduleHandler->expects($this->at(3)) ->method('invokeAll') + ->with('entity_postsave'); + $this->moduleHandler->expects($this->at(4)) + ->method('invokeAll') + ->with('test_entity_type_update'); + $this->moduleHandler->expects($this->at(5)) + ->method('invokeAll') ->with('entity_update'); $this->entityQuery->expects($this->once()) diff --git a/core/tests/Drupal/Tests/Core/Entity/KeyValueStore/KeyValueEntityStorageTest.php b/core/tests/Drupal/Tests/Core/Entity/KeyValueStore/KeyValueEntityStorageTest.php index 4fbdba3..0df5a86 100644 --- a/core/tests/Drupal/Tests/Core/Entity/KeyValueStore/KeyValueEntityStorageTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/KeyValueStore/KeyValueEntityStorageTest.php @@ -249,9 +249,15 @@ public function testSaveInsert(EntityInterface $entity) { ->with('entity_presave'); $this->moduleHandler->expects($this->at(2)) ->method('invokeAll') - ->with('test_entity_type_insert'); + ->with('test_entity_type_postsave'); $this->moduleHandler->expects($this->at(3)) ->method('invokeAll') + ->with('entity_postsave'); + $this->moduleHandler->expects($this->at(4)) + ->method('invokeAll') + ->with('test_entity_type_insert'); + $this->moduleHandler->expects($this->at(5)) + ->method('invokeAll') ->with('entity_insert'); $this->keyValueStore->expects($this->once()) ->method('set') @@ -305,9 +311,15 @@ public function testSaveUpdate(EntityInterface $entity) { ->with('entity_presave'); $this->moduleHandler->expects($this->at(4)) ->method('invokeAll') - ->with('test_entity_type_update'); + ->with('test_entity_type_postsave'); $this->moduleHandler->expects($this->at(5)) ->method('invokeAll') + ->with('entity_postsave'); + $this->moduleHandler->expects($this->at(6)) + ->method('invokeAll') + ->with('test_entity_type_update'); + $this->moduleHandler->expects($this->at(7)) + ->method('invokeAll') ->with('entity_update'); $this->keyValueStore->expects($this->once()) ->method('set')