Drupal 7 - Adding Roles to Users Dynamically http://www.andypangus.com/drupal-7-adding-roles-to-users-dynamically

Public

Now that we can create our own roles with pre-defined sets of permissions, what can we do with them? Well, what if you had a web-site that assigned user roles based on how long the user had been a member? New users would simply be authenticated users. Once a new user had been a member of the site for a week they would be granted the role 'newb' which would allow them to view special content and use the search widget. After being a member for a month that same user would be promoted to the role of 'pangus' with permission to create, edit, and delete special content as well as permission to use advanced search feature. How would you go about implementing that? Well, just like the previous example, we need to define the hook_install() and hook_uninstall() functions:

Get raw version
php
  1. /**
  2.  * Implements hook_install().
  3.  */
  4. function simple_user_roles_install() {
  5. // create any roles we will be using
  6. simple_user_roles_add_role('newb', 1);
  7. simple_user_roles_add_role('pangus', 1);
  8. // add permissions to the new roles
  9. $newb_permissions = array(
  10. 'search content',
  11. 'view simple content type',
  12. );
  13. $pangus_permissions = array(
  14. 'search content',
  15. 'use advanced search',
  16. 'view simple content type',
  17. 'create simple content type',
  18. 'edit simple content type',
  19. 'delete simple content type',
  20. );
  21. simple_user_roles_add_permissions('newb', $newb_permissions);
  22. simple_user_roles_add_permissions('pangus', $pangus_permissions);
  23. }
  24. /**
  25.  * Implements hook_uninstall().
  26.  */
  27. function simple_user_roles_uninstall() {
  28. // remove the roles we created
  29. user_role_delete('newb');
  30. user_role_delete('pangus');
  31. }

These hooks add and set-up the roles we will be using or removing them on uninstall, just like they do in the previous example. Now we need to set up the code which will handle assigning the correct role to users. For this functionality we want to tie into the Cron job functionality of Drupal and implement hook_cron():

Get raw version
php
  1. /**
  2.  * Implements hook_cron().
  3.  */
  4. function simple_user_roles_cron() {
  5. // get a list of active users
  6. $results = db_select('users', 'u')
  7. ->fields('u', array('uid', 'created'))
  8. ->condition('u.status', 1)
  9. ->execute();
  10. // limit the list of users to those who do not have the roles pangus or administrator
  11. $users = array();
  12. foreach ($results as $user) {
  13. // get any roles assigned to this user
  14. $roles = db_select('users_roles', 'r')
  15. ->fields('r', array('rid'))
  16. ->condition('r.uid', $user->uid)
  17. ->execute();
  18. if (!$roles) {
  19. $users[] = $user;
  20. }
  21. else {
  22. $add_role = TRUE;
  23. foreach ($roles as $role) {
  24. $role_name = user_role_load($role->rid)->name;
  25. if ($role_name == 'pangus' || $role_name == 'administrator') {
  26. $add_role = FALSE;
  27. } // end if
  28. } // end foreach
  29. if ($add_role) {
  30. $users[] = $user;
  31. } // end if
  32. } // end if
  33. } // end foreach
  34. // some convenience vars
  35. $newb_rid = user_role_load_by_name('newb')->rid;
  36. $week = 60 * 60 * 24 * 7;
  37. $month = 60 * 60 * 24 * 30;
  38. // get the current time
  39. $time = time();
  40. // foreach user
  41. foreach ($users as $user) {
  42. // how long has the user been a member?
  43. $time_length = $time - $user->created;
  44. // if it has it been longer than a week but less than a month
  45. if ($time_length >= $week && $time_length < $month) {
  46. // add the newb role if they do not have it already
  47. simple_user_roles_add_role_to_user('newb', $user->uid);
  48. }
  49. elseif ($time_length >= $month) {
  50. // if it has been longer than a month
  51. // remove the newb role
  52. $sql = "DELETE FROM {users_roles} WHERE uid=:uid AND rid=:rid";
  53. $delete = db_query($sql, array(':uid' => $user->uid, ':rid' => $newb_rid));
  54. // add the pangus role
  55. simple_user_roles_add_role_to_user('pangus', $user->uid);
  56. } // end if
  57. } // end foreach
  58. }

Let's step through what's going on above. First thing, we need to get a list of the active users on the site and remove any users from the list who already have the 'pangus' or 'administrator' role assigned to them. Next we need to find out how long each user in our list has been member. If the user has been a member for a week or longer but less than a month we assign the 'newb' role to them if it has not been assigned already. If a user has been a member for a month or longer we remove the 'newb' role and add the 'pangus' role if it hasn't been assigned already. That's the bulk of it. We do have a few helper functions which assist with adding and creating roles:

Get raw version
php
  1. /**
  2.  * Adds a new role
  3.  * @machine_name - the name of the role to be added
  4.  * @weight - the optional display weight for role
  5.  */
  6. function simple_user_roles_add_role($machine_name, $weight = 0) {
  7. $role = new stdClass();
  8. $role->name = $machine_name;
  9. $role->weight = $weight;
  10. if (!user_role_load_by_name($role->name)) {
  11. user_role_save($role);
  12. }
  13. }
  14. /**
  15.  * Adds permissions to a role
  16.  * @role_name - the name of the role to receive an update
  17.  * @permissions - the array of permissions to add
  18.  */
  19. function simple_user_roles_add_permissions($role_name, $permissions) {
  20. $role = user_role_load_by_name($role_name);
  21. user_role_grant_permissions($role->rid, $permissions);
  22. }
  23. /**
  24.  * Adds a role to a user
  25.  * @role_name - the machine name for the role to be added
  26.  * @uid - the {user}.uid for the user being updated
  27.  */
  28. function simple_user_roles_add_role_to_user($role_name, $uid) {
  29. $results = db_select('users_roles', 'ur')
  30. ->fields('ur', array('rid'))
  31. ->condition('ur.uid', $uid)
  32. ->execute();
  33. $_add_to_user = TRUE;
  34. if ($results->rowCount() > 0) {
  35. // check to see if the user already has this role assigned to them
  36. foreach ($results as $rid) {
  37. $name = user_role_load($rid->rid)->name;
  38. if ($name == $role_name) {
  39. $_add_to_user = FALSE;
  40. }
  41. }
  42. }
  43. if ($_add_to_user) {
  44. $rid = user_role_load_by_name($role_name)->rid;
  45. $insert = db_insert('users_roles')
  46. ->fields(array(
  47. 'uid' => $uid,
  48. 'rid' => $rid,
  49. ))
  50. ->execute();
  51. }
  52. }
Get raw version
php
  1. name = Simple User Roles
  2. description = A demonstration on adding roles to users dynamically based on how long they have been a site member
  3. package = Andy Pangus Examples
  4. core = 7.x
  5. dependencies[] = search
  6. dependencies[] = simple_content_type
  7. files[] = simple_user_roles.install
  8. files[] = simple_user_roles.module