user_readonly.module in User Read-Only 7
Same filename and directory in other branches
This module provides restrictions on user account/profile fields.
File
user_readonly.moduleView source
<?php
/**
* @file
*
* This module provides restrictions on user account/profile fields.
*/
/**
* Implements hook_permission().
*/
function user_readonly_permission() {
return array(
'administer user read-only settings' => array(
'title' => t('Administer read-only settings'),
'description' => t('Set which fields will be set to be read-only on user accounts.'),
),
'modify user read-only settings' => array(
'title' => t('Modify read-only settings'),
'description' => t('Modify restricted fields on user accounts.'),
),
);
}
/**
* Implements hook_menu().
*
* @return array
*/
function user_readonly_menu() {
$items = array();
$items['admin/config/people/user_readonly'] = array(
'title' => 'User Read Only',
'description' => 'Set which profile fields cannot be edited.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'user_readonly_admin_settings',
),
'access callback' => 'user_access',
'access arguments' => array(
'administer user read-only settings',
),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
/**
* Implements hook_help().
*/
function user_readonly_help($path, $arg) {
switch ($path) {
case 'admin/config/people/user_readonly':
global $user;
return t('Here you can define modification restrictions for user/profile editing. ' . 'The options below the fieldsets correspond to the appropriate fields which are ' . 'visible in <a href="@account_url">account settings form</a>. Note that ' . 'password-type and date-type fields cannot be set read-only; they must be hidden.', array(
'@account_url' => url("user/{$user->uid}/edit"),
));
break;
}
}
/**
* Configuration form for setting default restrictions.
*
* @return array
*/
function user_readonly_admin_settings() {
global $user;
// Build the list of fields that we can configure from user_profile_form().
$fields = array();
$form = array();
$form_state = array();
$account = user_load($user->uid);
module_load_include('inc', 'user', 'user.pages');
$user_edit = user_profile_form($form, $form_state, $account);
foreach (element_children($user_edit) as $element_name) {
$element = $user_edit[$element_name];
foreach (element_children($element) as $element_value_name) {
if (isset($element[$element_value_name][0])) {
$element_values = $element[$element_value_name][0];
$element_value_name = $element[$element_value_name][0]["#field_name"];
$fields[$element_value_name] = $element_value_name;
}
elseif (isset($element[$element_value_name]["#field_name"])) {
$element_values = $element[$element_value_name];
$element_value_name = $element[$element_value_name]["#field_name"];
$fields[$element_value_name] = $element_value_name;
}
else {
$element_values = $element[$element_value_name];
$fields[$element_value_name] = $element_value_name;
}
}
}
// Tell Drupal to keep the tree structure of the form so we can save values per form element.
$form = array(
'#tree' => TRUE,
);
$settings = _user_readonly_get();
$roles = user_roles(TRUE);
$modes = array(
'deny' => t('Only <strong>DENY</strong> changes to users with these roles.'),
'allow' => t('Only <strong>ALLOW</strong> changes to users with these roles.'),
);
$actions = array(
'disable' => t('Disable the fields.'),
'hide' => t('Hide the fields.'),
);
// Create the default settings form.
if (empty($settings['user_readonly']['mode'])) {
$settings['user_readonly']['mode'] = 0;
}
if (empty($settings['user_readonly']['action'])) {
$settings['user_readonly']['action'] = 0;
}
$form['user_readonly'] = array(
'#title' => t('Default settings for all fields'),
'#type' => 'fieldset',
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
$form['user_readonly']['mode'] = array(
'#type' => 'radios',
'#title' => t('Restrictions mode'),
'#default_value' => $settings['user_readonly']['mode'],
'#options' => $modes,
'#description' => t('Define the restriction rules. ' . 'To deny all changes, choose ALLOW, but do not select any fields below.'),
);
$form['user_readonly']['roles'] = array(
'#type' => 'checkboxes',
'#title' => t('Roles'),
'#default_value' => $settings['user_readonly']['roles'],
'#options' => $roles,
);
$form['user_readonly']['action'] = array(
'#type' => 'radios',
'#title' => t('When restrictions apply'),
'#default_value' => $settings['user_readonly']['action'],
'#options' => $actions,
'#description' => t('Disabling fields greys them out but users can still see the fields. ' . 'Hiding fields removes them from the form. ' . 'This option is independent from the above restriction rule setting.'),
);
$modes['default'] = t('Use the default role settings.');
$actions['default'] = t('Use the default settings.');
// Create fieldsets for each identified profile element
foreach ($fields as $fid => $fname) {
$is_collapsed = TRUE;
if (!empty($settings[$fid]['mode']) && $settings[$fid]['mode'] != 'default' || !empty($settings[$fid]['action']) && $settings[$fid]['action'] != 'default') {
$is_collapsed = FALSE;
}
if (empty($settings[$fid]['mode'])) {
$settings[$fid]['mode'] = 'default';
}
if (empty($settings[$fid]['action'])) {
$settings[$fid]['action'] = 'default';
}
if (empty($settings[$fid]['roles'])) {
$settings[$fid]['roles'] = array();
}
$form[$fid] = array(
'#title' => $fname,
'#type' => 'fieldset',
'#collapsible' => TRUE,
'#collapsed' => $is_collapsed,
);
$form[$fid]['mode'] = array(
'#type' => 'radios',
'#title' => t('Restrictions mode'),
'#default_value' => $settings[$fid]['mode'],
'#options' => $modes,
'#description' => t('Define the restriction rules. ' . 'To deny all changes, choose ALLOW, but do not select any fields below.'),
);
$form[$fid]['roles'] = array(
'#type' => 'checkboxes',
'#title' => t('Roles'),
'#default_value' => $settings[$fid]['roles'],
'#options' => $roles,
);
$form[$fid]['action'] = array(
'#type' => 'radios',
'#title' => t('When restrictions apply'),
'#default_value' => $settings[$fid]['action'],
'#options' => $actions,
'#description' => t('Disabling fields greys them out but users can still see the fields. ' . 'Hiding fields removes them from the form. ' . 'This option is independent from the above restriction rule setting.'),
);
}
$form['user_readonly_submit'] = array(
'#type' => 'submit',
'#value' => t('Save configuration'),
'#weight' => 3000,
);
// We do not use system_settings_form() because the config is stored as an array of role settings.
return $form;
}
/**
* Automatic handler for the submission from user_readonly_admin_settings()
*/
function user_readonly_admin_settings_submit($form, &$form_state) {
// Some form values don't need to be saved in the db.
unset($form_state['values']['op'], $form_state['values']['user_readonly_submit'], $form_state['values']['reset'], $form_state['values']['form_token'], $form_state['values']['form_build_id'], $form_state['values']['form_id']);
variable_set('user_readonly', $form_state['values']);
drupal_set_message(t('The configuration options have been saved.'));
}
/**
* Implements hook_form_alter().
*
* Prevent the user from attempting to edit the field,
* thus preventing confusion.
* insert a hidden field w/ the appropriate value, since
* disabled fields do not get posted.
*/
function user_readonly_form_alter(&$form, &$form_state, $form_id) {
if ($form_id != 'user_edit' && $form_id != 'user_profile_form') {
return;
}
$settings = _user_readonly_get();
global $user;
$user_roles = $user->roles;
foreach ($form as $group => $data) {
if (!is_array($data) || preg_match("/^#/", $group) || count(element_children($data)) == 0) {
continue;
}
$display_group = FALSE;
foreach (element_children($data) as $key => $value) {
if (isset($data[$value][0]["#field_name"])) {
$field = $data[$value][0]["#field_name"];
}
elseif (isset($data[$value]["#field_name"])) {
$field = $data[$value]["#field_name"];
}
else {
$field = $value;
}
// Only restrict access to fields controlled by this module.
if (empty($settings[$field]) || !is_array($data[$value])) {
$display_group = TRUE;
continue;
// Skip to the next child element.
}
// Use the default values unless the setting says otherwise.
$settings_used = $settings['user_readonly'];
if (!empty($settings[$field]['mode']) && $settings[$field]['mode'] != 'default') {
$settings_used['mode'] = $settings[$field]['mode'];
$settings_used['roles'] = $settings[$field]['roles'];
}
if (!empty($settings[$field]['action']) && $settings[$field]['action'] != 'default') {
$settings_used['action'] = $settings[$field]['action'];
$settings_used['roles'] = $settings[$field]['roles'];
}
// Check if any of this user's roles are ticked in the settings.
$ticked = FALSE;
foreach ($user_roles as $role_rid => $role_name) {
if (!empty($settings_used['roles'][$role_rid])) {
$ticked = TRUE;
break;
}
}
// Check whether this user is allowed to make changes to this field.
// If user is allowed to modify settings, then we skip these changes.
if (!user_access('modify user read-only settings') && ($ticked == TRUE && $settings_used['mode'] == 'deny' || $ticked == FALSE && $settings_used['mode'] == 'allow')) {
$action = $settings_used['action'];
if (isset($form[$group][$value]['#type'])) {
switch ($form[$group][$value]['#type']) {
case 'date':
// Due to complexity of these fields, we just remove it.
$form[$group]['user_readonly'][$value] = $form[$group][$key];
$form[$group]['user_readonly'][$value]['#type'] = 'item';
$form[$group]['user_readonly'][$value]['#description'] = '';
$form[$group]['user_readonly'][$value]['#title'] = '';
$form[$group][$value]['#disabled'] = TRUE;
break;
case 'password_confirm':
// Due to complexity of these fields, we just remove it.
$form[$group][$value]['#access'] = FALSE;
break;
case 'button':
$form[$group][$value]['#access'] = FALSE;
break;
case 'submit':
$form[$group][$value]['#access'] = FALSE;
break;
case 'file':
$form[$group][$value]['#access'] = FALSE;
break;
default:
if ($action == 'hide') {
// Do not unset anything, just remove access to it.
$form[$group][$value]['#access'] = FALSE;
}
else {
// Disabled fields can still be manipulated via DOM or JS to change value.
// So we explicitly add the value as a return.
// This way, even if someone tries to circumvent it - #value sets it hard.
// Note, relies on the form default_value being set properly.
$display_group = TRUE;
$form[$group][$value]['#disabled'] = TRUE;
$form[$group][$value]['#value'] = '';
if (isset($form[$group][$value]['#default_value'])) {
if ($value == 'roles' && is_array($form[$group][$value]['#default_value'])) {
$form[$group][$value]['#value'] = drupal_map_assoc($form[$group][$value]['#default_value']);
}
else {
$form[$group][$value]['#value'] = $form[$group][$value]['#default_value'];
}
}
}
break;
}
// End switch.
}
// End check for existing type.
}
else {
$display_group = TRUE;
}
}
// End foreach (element_children($data) as $key => $value)
if (!$display_group) {
$form[$group]['#access'] = FALSE;
}
}
// End foreach ($form as $group => $data)
}
/**
* Helper function, gets the default restrictions set by user_readonly_admin_settings()
* and if none are set, returns default array elements.
*
* @return array
*/
function _user_readonly_get() {
$a = variable_get('user_readonly', '');
if (empty($a)) {
$a = array(
'user_readonly' => array(
'mode' => 'deny',
'roles' => array(),
'action' => 'disable',
),
);
}
return $a;
}Functions
|
Name |
Description |
|---|---|
| user_readonly_admin_settings | Configuration form for setting default restrictions. |
| user_readonly_admin_settings_submit | Automatic handler for the submission from user_readonly_admin_settings() |
| user_readonly_form_alter | Implements hook_form_alter(). |
| user_readonly_help | Implements hook_help(). |
| user_readonly_menu | Implements hook_menu(). |
| user_readonly_permission | Implements hook_permission(). |
| _user_readonly_get | Helper function, gets the default restrictions set by user_readonly_admin_settings() and if none are set, returns default array elements. |