Adding roles to a user programmatically in Drupal 8

December 23, 2015

For a new Drupal 8 site I needed to hook into the user registration process and add a role to users with email addresses on a specific domain.

As with most tasks in Drupal 8, if you’re used to working with procedural code from Drupal 7, working with object-oriented code can involve a bit of a mental shift, and sometimes figuring out which object is relevant involves a bit of digging around in the core code, or judicious use of a debugger.

This is a good example of the OO approach - the User class extends ContentEntityBase, which extends Entity, so some of the relevant methods aren’t in User. Also, while there is effectively a hook_user_insert, you won’t find it in the user module, but in the entity module.

One thing that makes this easier and more logical in Drupal 8 is the fact that roles now have machine names rather than numeric IDs.

getEmail(); $domain = substr($email, strrpos($email, '@') + 1); if ($domain == '') { $entity->addRole('mydomainrole'); $entity->save(); } } ?>

Here’s the equivalent Drupal 7 code:

mail; $domain = substr($email, strrpos($email, '@') + 1); if ($domain == '') { $user = user_load($account->uid); $role = user_role_load_by_name('user manager'); $user->roles[$role->rid] = $role->name; user_save($user); } } ?>

To my mind, the Drupal 8 code is clearer and more logical to the reader, and probably easier to get your head around, unless you’re coming from the Drupal island.