6

I have an application using domain access and am looking to reuse a set of subscriber roles across domains, assigning them on login.

I was hoping to use hook_user_load to add the additional roles.

I have some code like this:

/**
 * Implements hook_user_load()
 * 
 * Dynamically assign configured roles based on active domain and subscription
 */
function EXAMPLE_user_load($users) {

  // Process each account once per request
  $processed_uids = &drupal_static(__FUNCTION__, array());
  // Get defined roles
  $roles = user_roles(TRUE);

  // Process accounts
  foreach ($users as $uid => $account) {
    $grant_rids = array();
    if(!in_array($uid, $processed_uids)){
      // Code to get grant role ids here...
      // ...
      // ...
      // Grant subscriber roles
      if(!empty($grant_rids)){
        foreach($grant_rids as $rid){
          // Matching role exists and not already assigned
          if(!empty($roles[$rid]) && !array_key_exists($rid, $users[$uid]->roles)){
            $users[$uid]->roles[$rid] = $roles[$rid];
          }
        }
      }
      $processed_uids[] = $uid;
    }
  }
}

Using this approach, the roles do get added, and I can see them in the $users array after processing.

However the user logging in, despite running through hook_user_load doesn't appear to have those roles "set" ( i.e aren't authenticated as having that role )

Maybe some kind of cache issue?

Does anyone have any ideas about what needs changing above or how to assign user roles dynamically as the user logs in, or as the user is loaded?

UPDATE:

Well, it turns out, you can actually alter user roles in hook_user_load.

My issue was caused by a ctools bug I discovered in my debug travels whereby the current logged in user context didn't fully load the user entity, and thus the access checks for the Panel page access were failing. It also needed a drupal_static_reset('user_access') to reset the static user_access permission check cache. Patch posted here http://drupal.org/node/2010124

After that, the dynamic role assignment appears to be working fine.

UPDATE 2

I wrote too soon, still having problems...

Will update when resolved.

UPDATE 3

OK, the remaining issues were related to ctools context caching. I ended up writing my own ctools access plugin to ensure the logged in user context is checked uncached on each access request. After that, all appears well again.

3 Answers 3

1

You can try user_multiple_role_edit, something like this might help.

  $user_id = $user->uid;
  // user the role human name
  $role_name = 'My Awesome Role';
  if (user_role_load_by_name($role_name)) {
    // No need to check if the role is already granted
    user_multiple_role_edit(array($user_id), 'add_role', $role->rid);
  }

2
  • 1
    Thanks, but I want to assign the user roles dynamically, e.g on user load, without saving the roles to the database. The reason is a user may have 'subscriber' role on one domain, but not on another. The role should be assigned on login / load. Jun 2, 2013 at 6:59
  • can you do a custom table? something like |role_name| user_id| domain| 'subscriber' | 1 | 'some.domain.com' 'subscriber' | 1 | 'another.domain.com'
    – saadlulu
    Jun 2, 2013 at 8:41
0

The documentation for hook_user_load() contains a warning about overriding the user properties that are loaded from the {users} table, but apparently that is valid for properties loaded from the {users_roles} table read from UserController::attachLoad().

The only workaround I found is to alter the global $user variable, or change what shown in the user edit form when shown. The other possibility is changing the user roles when the user object is saved.
In a module I developed, I took the first approach.

2
  • Thanks kiamlaluno, I had found when using EntityFieldQuery that user roles weren't treated as a "property" of the user entity, so had assumed that was the case for the hook_user_load usage also. However, yes, perhaps there is some inconsistency of user role/property treatment in Drupal here. I'll have a go with altering global $user in an additional user_login_submit handler and perhaps also hook_boot to test. Will update when verified. Thanks again. Jun 2, 2013 at 9:46
  • OK, it appears it actually is possible to alter roles in hook_user_load. My issue was caused by a ctools bug I discovered whereby the current logged in user context didn't fully load the user entity ( patch posted here drupal.org/node/2010124 ) Jun 2, 2013 at 11:37
0

I am fairly certain that modifying hook_user_load as suggested above will not actually allow you to assign a role dynamically to a user. Even though doing this will show that role during the hook_user_login hook; the user does not actually get logged in authenticated with that new role.

1
  • 1
    Just noting, I did get this feature working using hook_user_load as per above - it also needs drupal_static_reset('user_access') Aug 4, 2014 at 22:01

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.