array('mode' => 'deny', 'roles' => array(), 'action' => 'disable')); } return $a; } /** * Implementation of hook_menu(). */ function user_readonly_menu($may_cache) { $items = array(); if ($may_cache) { $items[] = array( 'path' => 'admin/settings/user_readonly', 'description' => t('User ReadOnly settings.'), 'title' => t('User ReadOnly'), 'callback' => 'drupal_get_form', 'callback arguments' => array('user_readonly_settings'), 'access' => user_access('access administration pages'), ); } return $items; } /** * Implementation of hook_help(). */ function user_readonly_help($section) { switch ($section) { case 'admin/modules#description': return t('Restrict user/profile editing.'); break; case 'admin/settings/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 account settings form. Note that password-type and date-type fields cannot be disabled; they must be deleted.', array('@account_url' => url("user/$user->uid/edit"))); break; } } /** * Implementation of hook_settings(). */ function user_readonly_settings() { //important: tell Drupal to keep the tree structure of the form $form = array('#tree' => TRUE); $settings = _user_readonly_get(); //build the list of fields that we can configure $fields = array(); //drupal_retrieve_form() call changes the page title... so we workaround this $title = drupal_get_title(); $user_edit = drupal_retrieve_form('user_edit'); drupal_set_title($title); foreach ($user_edit as $k => $v) { if ($k[0] != '_' && !element_property($k)) { foreach ($v as $key => $value) { if (!element_property($key) && is_array($v[$key])) { $fields[$key] = check_plain($v['#title']) . (empty($v['#title']) ? '' : ' » ') . check_plain($key == 'pass' ? t('Password') : $value['#title']); } } } } if (module_exists('profile')) { $result = db_query('SELECT * from {profile_fields}'); while ($obj = db_fetch_object($result)) { $fields[$obj->name] = t($obj->title); } } $roles = user_roles(TRUE); $modes = array( 0 => t('Use the default role settings.'), 'deny' => t('Only DENY changes to users with these roles.'), 'allow' => t('Only ALLOW changes to users with these roles.'), ); //create the part of the form all the fields use for every field options $partialf = array( '#type' => 'fieldset', '#collapsible' => TRUE, '#collapsed' => TRUE, ); $partialf['mode'] = array( '#type' => 'radios', '#title' => t('Restrictions mode'), '#default_value' => $settings[0]['mode'], '#options' => $modes, '#description' => t('Define the restriction rules. To deny all changes, choose ALLOW, but do not select any fields below.'), ); $partialf['roles'] = array( '#type' => 'checkboxes', '#title' => t('Roles'), '#default_value' => $settings[0]['roles'], '#options' => $roles, ); $partialf['action'] = array( '#type' => 'radios', '#title' => t('When restrictions apply'), '#default_value' => $settings[0]['action'], '#options' => array(0 => t('Use the default settings.'), 'disable' => t('Disable the fields.'), 'delete' => t('Delete the fields.')), '#description' => t('Disabling fields greys them out but users can still see the fields. Deleting fields hides them. This option is independent from the above restriction rule setting.'), ); //create the default settings form $defaultf = $partialf; $defaultf['#collapsed'] = FALSE; $defaultf['#title'] = t('Default settings for all fields'); //if ($defaultf['mode']['#default_value'] == 'default') $defaultf['mode']['#default_value'] = 'deny'; unset($defaultf['mode']['#options'][0]); unset($defaultf['action']['#options'][0]); $form[0] = $defaultf; //create the form for all fields foreach ($fields as $fid => $fname) { $partialf['#title'] = $fname; $defaults = $settings[$fid]; if (empty($defaults)) { $defaults = array('mode' => 0, 'roles' => array(), 'action' => 0); } $partialf['mode']['#default_value'] = $defaults['mode']; $partialf['roles']['#default_value'] = $defaults['roles']; $partialf['action']['#default_value'] = $defaults['action']; $form[$fid] = $partialf; if (!empty($defaults['mode']) || !empty($defaults['action'])) { $form[$fid]['#collapsed'] = FALSE; } } $form['submit'] = array( '#type' => 'submit', '#value' => t('Save configuration') ); $form['reset'] = array( '#type' => 'submit', '#value' => t('Reset to defaults'), ); return $form; } function user_readonly_settings_submit($form_id, $form_values) { //dpm($form_values); //return; if ($form_values['op'] == t('Save configuration')) { variable_set('user_readonly', $form_values); drupal_set_message(t('The configuration options have been saved.')); } else if ($form_values['op'] == t('Reset to defaults')) { variable_del('user_readonly'); drupal_set_message(t('The configuration options have been reset to their default values.')); } drupal_goto('admin/settings/user_readonly'); } /** * 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_id, &$form) { //dpm($form_id); if (user_access('administer users') || $form_id != 'user_edit') { return; } $settings = _user_readonly_get(); global $user; $user_roles = $user->roles; foreach ($form as $group => $data) { if (!is_array($data)) { continue; } foreach (element_children($data) as $key => $value) { // only restrict access to fields controlled by this module. if (empty($settings[$value]) || !is_array($data[$value])) continue; //use the default values if the setting tells so $settings_used = empty($settings[$value]['mode']) ? $settings[0] : $settings[$value]; //check whether this user is allowed to make changes to this field //first, 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])) { //this means that in the settings, this user qualifies as 'ticked'. That can mean 'allow' or 'deny', depending on the mode. $ticked = TRUE; break; } } if (($ticked == TRUE && $settings_used['mode'] == 'deny') || ($ticked == FALSE && $settings_used['mode'] == 'allow')) { $action = empty($settings_used['action']) ? $settings[0]['action'] : $settings_used['action']; switch ($form[$group][$value]['#type']) { case 'date': case 'password_confirm': // due to the complex nature of these fields, we simply delete them from the form. unset($form[$group][$value]); break; default: if ($action == 'delete') { $form[$group][$value]['#type'] = 'hidden'; } else /*if ($action == 'disable')*/ { // fields must have a hidden field w/ proper value as disabled fields are not submitted. $form[$group]['_user_readonly'][$value] = $form[$group][$value]; $form[$group]['_user_readonly'][$value]['#type'] = 'hidden'; //new in Drupal 5: #disabled property $form[$group][$value]['#disabled'] = TRUE; } } } } } }