2

I'm trying to add a role to a user but I can't save the change.

function hook_entity_presave(Drupal\Core\Entity\EntityInterface $entity){
  $user = \Drupal\user\Entity\User::load(\Drupal::currentUser()->id());
  $user->addRole('foobar');
}

I would like to save the change, but $user->save() causes a fatal error.

What would be the correct way?

  • Please update the question with the error you are getting. – Kevin Feb 10 '17 at 15:15
  • There is a lot missing here - you should ensure you are about to operate on a User entity, and you should be loading the user from that entities provided id, not currentUser. – Kevin Feb 10 '17 at 15:15
  • The error is a whitescreen of death. I guess $user->save() is for creating new users. I would need to update an existing one. – J. Dough Feb 13 '17 at 8:47
1

Code should look like this, as an example:

use Drupal\Core\Entity\EntityInterface;
use Drupal\user\Entity\User;

function mymodule_entity_presave(EntityInterface $entity) {
  if ($entity instanceof AccountInterface && $entity->isTranslatable()) {
    $user = User::load($entity->id());
    $user->addRole('foobar');
  }
}

Or better yet, hook_ENTITY_TYPE_presave():

use Drupal\Core\Entity\EntityInterface;
use Drupal\user\Entity\User;

function mymodule_user_presave(EntityInterface $entity) {
  $user = User::load($entity->id());
  $user->addRole('foobar');
}

Simply using hook_entity_presave will fire for any entity about to be saved. So you either need to check the incoming entity, or use the second hook to isolate it.

  • Unfortunatelly this is not working. I want to add a user role while creating new content. So the $entity wouldn't be a user. That's why I used $user = \Drupal\user\Entity\User::load(\Drupal::currentUser()->id()); Also the _hook_user_presave isn't called. – J. Dough Feb 13 '17 at 8:43
1

I received an error using hook_user_presave saying unable to flip string and integer on $entity_id. Looks like it doesn't have the id on presave, worked when I switched to hook_user_insert.

<?php
use Drupal\Core\Entity\EntityInterface;
use Drupal\user\Entity\User;


function mymodule_user_insert(EntityInterface $entity) {
  $user = User::load($entity->id());
  $user->addRole('foobar');
  $user->save();
}
  • The OP said in a comment: Unfortunatelly this is not working. I want to add a user role while creating new content. So $entity wouldn't be a user. That's why I used $user = \Drupal\user\Entity\User::load(\Drupal::currentUser()->id());. Also hook_user_presave() isn't called. – kiamlaluno Jul 26 '18 at 16:06
0

For the code shown in the question, notice that:

  • hook_entity_presave() is called before every entity is saved, including a view, a block, a contact form, or an image style (just to list a few entities Drupal core implements)

  • With \Drupal::currentUser()->id(), you are getting the ID of the currently logged-in user; in the case a user is creating an entity for another user, that code would not assign the new role to the right account, which I assume should be the user who created the entity

  • The code is not checking the user account is for the anonymous user; supposing that anonymous users are allowed to create an entity, that code would not work as expected, since anonymous users don't have roles assigned

For the rest, the correct code to assign a role to $user requires to call $user->addRole() and $user->save().

Since you want to assign the new role when a node is saved, I would rather use the following code.

use Drupal\Core\Entity\EntityInterface;
use Drupal\node\NodeInterface;
use Drupal\user\EntityOwnerInterface;
use Drupal\user\UserInterface;

/**
 * Implements hook_ENTITY_TYPE_presave() for nodes.
 */
function mymodule_node_presave(EntityInterface $entity) {
  if ($entity instanceof EntityOwnerInterface) {
    /** @var \Drupal\user\UserInterface $user */
    $user = User::load($entity->getOwnerId());
    $user->addRole('foobar');
    $user->save();
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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