Dynamically assign user roles 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 = &amp;drupal_static(__FUNCTION__, array());
  // Get defined roles
  $roles = user_roles(TRUE);

  // Process accounts
  foreach ($users as $uid =&gt; $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]) &amp;&amp; !array_key_exists($rid, $users[$uid]-&gt;roles)){
            $users[$uid]-&gt;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.
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);
  }