0

I am trying to create a hook that creates a new entity('Notification') when an entity of another type is created (either of type 'Deadline' or 'Message'), but I can't seem to figure out how to add a new entity from a hook, am I completely missing something?

My hook in ost.module looks like this:

function ost_hook_ENTITY_TYPE_create(EntityInterface $entity){
  if ($entity->getEntityType() == ('Deadline' || 'Message')){
    createNotification($entity);
  }
}

The function which is called looks like this:

function createNotification(EntityInterface $notification){
  $newentity = EntityInterface::create([
    'title' => $notification->label() . "notification",
    'field_content' => $notification->toLink()
  ]);
  $newentity->save();
}
2
  • 2
    Does this answer your question? Programmatically create nodes. Replace node with your own entity.
    – Hudri
    Jul 13, 2020 at 9:07
  • 1
    Don't save an entity in a create hook. The correct hook would be hook_entity_insert() in your case. Unless you want to create the second entity to reference it in the first one, but then reference it without saving.
    – 4uk4
    Jul 13, 2020 at 10:53

2 Answers 2

0

That code needs to be changed for the following reasons.

In PHP, $entity->getEntityType() == ('Deadline' || 'Message') doesn't check that $entity->getEntityType() returns either 'Deadline' or 'Message'. Actually, the code you wrote is equivalent to the following one.

if ($entity->getEntityType() == TRUE) {
  createNotification($entity);
}

getEntityType() doesn't return the ID of the type of the entity, but its definition. The method that returns the ID of the type of the entity is getEntityTypeId().

It doesn't make sense to check the value returned from $entity->getEntityTypeId() in hook_ENTITY_TYPE_create() because hook_ENTITY_TYPE_create() is invoked only for the ENTITY_TYPE entities. (You are also supposed to implement hook_ENTITY_TYPE_create() by replacing ENTITY_TYPE with the entity type, for example node for the Node entity, or user for the User entity.)

EntityInterface is an interface, not a class; as such, it's never used to call a method, even if it's statically called as in the code you are using.

The correct code is similar to the following one. I assume that ost_hook is the module machine name, notification is entity type, and Notification is the class implementing the entity you are trying to create.

function ost_hook_entity_create(EntityInterface $entity) {
  if ($entity->getEntityTypeId() == 'Deadline' || $entity->getEntityTypeId() == 'Message') {
    $new_entity = Notification::create([
      'title' => $entity->label() . " notification",
      'field_content' => $entity->toLink()
    ]);
    $new_entity->save();
  }
}

Alternatively, you could use the following code.

function ost_hook_entity_create(EntityInterface $entity) {
  if ($entity->getEntityTypeId() == 'Deadline' || $entity->getEntityTypeId() == 'Message') {
    $new_entity = \Drupal::entityTypeManager()->getStorage('notification')->create([
      'title' => $entity->label() . " notification",
      'field_content' => $entity->toLink()
    ]);
    $new_entity->save();
  }
}

If the file containing the hook is ost.module (as I suspect), the function implementing the hook is ost_entity_create(), not ost_hook_entity_create().

I used hook_entity_create() because the code needs to be executed for two different entity types. Using hook_ENTITY_TYPE_create(), I should implement two hooks. (I assume that dealine and message are the entity machine names, in the same way the machine name for the Node entity is node.)

function ost_deadline_create(EntityInterface $entity) {
  $new_entity = \Drupal::entityTypeManager()->getStorage('notification')->create([
    'title' => $entity->label() . " notification",
    'field_content' => $entity->toLink()
  ]);
  $new_entity->save();
}

function ost_message_create(EntityInterface $entity) {
  $new_entity = \Drupal::entityTypeManager()->getStorage('notification')->create([
    'title' => $entity->label() . " notification",
    'field_content' => $entity->toLink()
  ]);
  $new_entity->save();
}

As side note, functions implemented from a module should always be prefixed by the module machine name. A module shouldn't have a createNotification() function, which should instead be called ost_create_notification() (assuming that ost is the module machine name).

3
  • Thank you for the reply, I am gonna try it out and see if it works.
    – sveggen
    Jul 13, 2020 at 12:42
  • I get the following error message when running the code your provided: Drupal\Core\Entity\EntityStorageException: The "Notification" entity type does not exist. in Drupal\Core\Entity\Sql\SqlContentEntityStorage->save() (line 846 of core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php).
    – sveggen
    Jul 14, 2020 at 8:41
  • You need to verify what the entity type ID is. With the few information given in the question, I cannot tell you what that exactly is.
    – apaderno
    Jul 14, 2020 at 9:15
0

The following code solved it for me:

function ost_notifications_entity_insert(EntityInterface $entity) {
  if ($entity->bundle() == 'deadline' || $entity->bundle() == 'message') {
    $new_entity = \Drupal::entityTypeManager()->getStorage('node')->create([
      'type' => 'notification',
      'title' => $entity->label(),
      'field_content' => "content"
    ]);
    $new_entity->save();
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.