role_delegation.module in Role Delegation 5
Same filename and directory in other branches
This module allows site administrators to grant some roles the authority to assign selected roles to users, without them needing the 'administer access control' permission.
It provides its own tab in the user profile so that roles can be assigned without needing access to the user edit form.
File
role_delegation.moduleView source
<?php
/**
* @file
*
* This module allows site administrators to grant some roles the authority to
* assign selected roles to users, without them needing the 'administer access
* control' permission.
*
* It provides its own tab in the user profile so that roles can be assigned
* without needing access to the user edit form.
*/
/**
* Implementation of hook_help().
*/
function role_delegation_help($section) {
switch ($section) {
case 'admin/help#role_delegation':
return '<p>' . t('This module allows site administrators to grant some roles the authority to assign selected roles to users, without them needing the <em>administer access control</em> permission.') . '</p><p>' . t('It provides its own tab in the user profile so that roles can be assigned without needing access to the user edit form.') . '</p>';
}
}
/**
* Implementation of hook_perm().
*/
function role_delegation_perm() {
$roles = _role_delegation_roles();
$perms = array(
'assign all roles',
);
foreach ($roles as $role) {
$perms[] = _role_delegation_make_perm($role);
}
return $perms;
}
/**
* Implementation of hook_menu().
*/
function role_delegation_menu($may_cache) {
global $user;
$items = array();
if (!$may_cache) {
if (arg(0) == 'user' && is_numeric(arg(1)) && arg(1) > 0) {
$account = user_load(array(
'uid' => arg(1),
));
// Determine access to user profile page (same as user.module).
$profile_access = $user->uid == arg(1) || user_access('access user profiles');
$profile_access &= $account->status || user_access('administer users');
// Determine access to role assignment page.
$delegation_access = FALSE;
if (!user_access('administer users') && !($delegation_access = user_access('administer access control'))) {
$perms = role_delegation_perm();
foreach ($perms as $perm) {
if (user_access($perm)) {
$delegation_access = TRUE;
break;
}
}
}
$items[] = array(
'path' => 'user/' . arg(1) . '/roles',
'title' => t('Roles'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'role_delegation_roles_form',
$account,
),
'access' => $profile_access && $delegation_access,
'type' => MENU_LOCAL_TASK,
);
}
}
return $items;
}
/**
* Provides a form for assigning roles to the current user.
*/
function role_delegation_roles_form($account) {
$form['roles'] = array(
'#type' => 'fieldset',
'#title' => t('Roles'),
'#tree' => TRUE,
);
// Provide a separate checkbox for each role but hide those the user has no authority over.
$roles = _role_delegation_roles();
$roles_preserve = array(
'authenticated user',
);
foreach ($roles as $rid => $role) {
if (!(user_access('assign all roles') || user_access(_role_delegation_make_perm($role)) || user_access('administer access control'))) {
// Hide roles the user can't assign.
$form['roles'][$rid] = array(
'#type' => 'value',
'#value' => isset($account->roles[$rid]),
);
if (isset($account->roles[$rid])) {
$roles_preserve[] = $role;
}
}
else {
$form['roles'][$rid] = array(
'#type' => 'checkbox',
'#title' => check_plain($role),
'#default_value' => isset($account->roles[$rid]),
);
}
}
$form['roles']['#description'] = t('The user receives the combined permissions of the %roles role(s), and all roles selected here. ', array(
'%roles' => implode(', ', $roles_preserve),
));
$form['account'] = array(
'#type' => 'value',
'#value' => $account,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
);
drupal_set_title(check_plain($account->name));
return $form;
}
/**
* Saves the roles assigned to the account given in the form.
*/
function role_delegation_roles_form_submit($form_id, $form_values) {
if (is_array($form_values['roles']) && isset($form_values['account']->uid)) {
$account = user_load(array(
'uid' => (int) $form_values['account']->uid,
));
$myroles = array();
$rolenames = user_roles(TRUE);
foreach (array_keys(array_filter($form_values['roles'])) as $rid) {
$myroles[$rid] = $rolenames[$rid];
// we don't need to have the role name
}
user_save($account, array(
'roles' => $myroles,
));
// Delete the user's menu cache.
cache_clear_all($form_values['account']->uid . ':', 'cache_menu', TRUE);
drupal_set_message(t('The roles have been updated.'));
}
}
/**
* Returns all existing roles, except anonymous and authenticated user.
*/
function _role_delegation_roles() {
$roles = user_roles(TRUE);
unset($roles[DRUPAL_AUTHENTICATED_RID]);
return $roles;
}
/**
* Returns the delegation permission for a role. Any characters from the role
* that are not allowed in permission names are filtered out.
*/
function _role_delegation_make_perm($role) {
// Allow alphanumerics, space, hyphen, underscore.
$role = preg_replace('/[^a-zA-Z0-9 \\-_]/', '', $role);
return "assign {$role} role";
}
/**
* Implementation of hook_form_alter().
*/
function role_delegation_form_alter($form_id, &$form) {
// Only alter user form when user can't assign permissions without Role Delegation.
if ($form_id != 'user_register' && $form_id != 'user_edit') {
return;
}
if (user_access('administer access control')) {
return;
}
// Split up roles based on whether they can be delegated or not.
$current_roles = is_numeric(arg(1)) && ($user = user_load(array(
'uid' => arg(1),
))) ? $user->roles : array();
$rids_default = array();
$rids_preserve = array(
DRUPAL_AUTHENTICATED_RID => DRUPAL_AUTHENTICATED_RID,
);
$roles_preserve = array(
'authenticated user',
);
$roles_options = array();
$roles = _role_delegation_roles();
foreach ($roles as $rid => $role) {
if (user_access('assign all roles') || user_access(_role_delegation_make_perm($role))) {
if (array_key_exists($rid, $current_roles)) {
$rids_default[] = $rid;
}
$roles_options[$rid] = $role;
}
else {
if (array_key_exists($rid, $current_roles)) {
$rids_preserve[$rid] = $rid;
$roles_preserve[] = $role;
}
}
}
if (empty($roles_options)) {
// No role can be assigned.
return;
}
// Generate the form items.
$form['roles_preserve'] = array(
'#type' => 'value',
'#value' => $rids_preserve,
);
$assign_item = array(
'#type' => 'checkboxes',
'#title' => t('Roles'),
'#description' => t('The user receives the combined permissions of the %roles role(s), and all roles selected here. ', array(
'%roles' => implode(', ', $roles_preserve),
)),
'#options' => $roles_options,
'#default_value' => $rids_default,
);
if (isset($form['account'])) {
$form['account']['roles_assign'] = $assign_item;
}
else {
$form['roles_assign'] = $assign_item;
}
}
/**
* Implementation of hook_user().
*/
function role_delegation_user($op, &$edit, &$account, $category = NULL) {
if ($op != 'insert' && $op != 'submit') {
return;
}
if (!isset($edit['roles_assign'])) {
return;
}
$edit['roles'] = $edit['roles_preserve'] + array_filter($edit['roles_assign']);
}
Functions
Name | Description |
---|---|
role_delegation_form_alter | Implementation of hook_form_alter(). |
role_delegation_help | Implementation of hook_help(). |
role_delegation_menu | Implementation of hook_menu(). |
role_delegation_perm | Implementation of hook_perm(). |
role_delegation_roles_form | Provides a form for assigning roles to the current user. |
role_delegation_roles_form_submit | Saves the roles assigned to the account given in the form. |
role_delegation_user | Implementation of hook_user(). |
_role_delegation_make_perm | Returns the delegation permission for a role. Any characters from the role that are not allowed in permission names are filtered out. |
_role_delegation_roles | Returns all existing roles, except anonymous and authenticated user. |