t('User'), 'field' => 'name', 'sort' => 'asc'));
$protect_columns = userprotect_get_protection_display();
foreach ($protect_columns as $field => $data) {
$header[] = array('data' => $data, 'field' => $field);
}
$header[] = array('data' => t('Operations'));
$query = db_select('userprotect', 'up');
$query->innerJoin('users', 'u', 'up.uid = u.uid');
$query->condition('up.up_type', $type);
$count_query = clone $query;
$count_query->addExpression('COUNT(DISTINCT u.uid)');
$query = $query->extend('PagerDefault')->extend('TableSort');
// These are all protection fields in the database.
$protection_fields = array_keys(userprotect_get_protection_display());
// Grab the protected users.
$query
->fields('up', $protection_fields)
->fields('u', array('uid', 'name'))
->limit(25)
->orderByHeader($header)
->setCountQuery($count_query);
$protected_users = $query->execute();
// Set some initial values.
$delete = t('delete');
$options = array();
// These are all available protections.
$protections = array_keys(userprotect_user_protection_defaults());
// Pass in the header and list of protections to the form so they'll be available
// to the theming function.
$form = array();
$form['protection']['#tree'] = TRUE;
$form['#header'] = $header;
$form['#protections'] = $protections;
$form['#submit'][] = 'userprotect_protections_bypass_submit';
$form['#theme'] = 'userprotect_protections_bypass';
// Build the checkboxes options.
foreach ($protections as $protection) {
$options[$protection] = '';
}
// For each protected user, build their table row.
foreach ($protected_users as $protected_user) {
$defaults = array();
$user = user_load($protected_user->uid);
$form['user'][$user->uid]['uid'] = array(
'#type' => 'value',
'#value' => $user->uid
);
$form[$user->uid]['name'] = array(
'#theme' => 'username',
'#account' => $user,
);
$form[$user->uid]['operations'] = array('#markup' => $user->uid ? l($delete, "userprotect/delete/$user->uid/$type") : '');
// Build the protections for the user row.
foreach ($protections as $protection) {
if ($protected_user->$protection) {
$defaults[] = $protection;
}
}
// The checkboxes for this user.
$form['protection'][$user->uid] = array(
'#type' => 'checkboxes',
'#options' => $options,
'#default_value' => $defaults,
);
}
// An autocomplete field to add new users for protection.
// This needs a custom validation function to check the user
// to be added.
$form['up_add'] = array(
'#type' => 'textfield',
'#maxlength' => 60,
'#autocomplete_path' => 'user/autocomplete',
'#element_validate' => array('userprotect_up_add_validate'),
'#userprotect_type' => $type,
);
$form['up_add_text'] = array('#markup' => t('Add user'),);
$form['userprotect_type'] = array(
'#type' => 'value',
'#value' => $type,
);
$form['pager'] = array(
'#theme' => 'pager',
'#tags' => NULL,
);
$form['actions']['submit'] = array(
'#type' => 'submit',
'#value' => t('Save')
);
return $form;
}
/**
* Themes the protected users table.
*
* @param $form The form to theme.
* @return An HTML string representing the constructed form.
*/
function theme_userprotect_protections_bypass($variables) {
$form = $variables['form'];
$rows = array();
// Buikd the row for each user.
foreach (element_children($form['user']) as $uid) {
$row = array();
$row[] = drupal_render($form[$uid]['name']);
// Build the protections for the user row.
foreach ($form['#protections'] as $protection) {
$row[] = drupal_render($form['protection'][$uid][$protection]);
}
$row[] = drupal_render($form[$uid]['operations']);
$rows[] = $row;
}
// Add the last row with the add textfield.
$rows[] = array(
array('data' => drupal_render($form['up_add']), 'colspan' => strval(count($form['#header']) - 1)),
array('data' => drupal_render($form['up_add_text']), 'colspan' => '1')
);
// Theme the table.
$output = theme('table', array('header' => $form['#header'], 'rows' => $rows));
$output .= drupal_render_children($form);
return $output;
}
/**
* Custom validation function for adding a user for protection.
*/
function userprotect_up_add_validate($form, &$form_state) {
// If a user has been submitted
if ($username = $form['#value']) {
$type = $form['#userprotect_type'];
// If the user is valid, and they are not already being protected...
if ($uid = db_query("SELECT uid FROM {users} WHERE name = :name", array(
':name' => $username,
))->fetchField()) {
if (!db_query("SELECT uid FROM {userprotect} WHERE uid = :uid AND up_type = :up_type", array(
':uid' => $uid,
':up_type' => $type,
))->fetchField()) {
if ($uid != 1 && $type == 'admin' && !db_query("SELECT ur.uid FROM {users_roles} ur INNER JOIN {role_permission} rp ON ur.rid = rp.rid WHERE rp.permission = :permission AND ur.uid = :uid", array(
':permission' => 'administer users',
':uid' => $uid,
))->fetchField()) {
form_set_error('up_add', t('%user does not have user administration privileges.', array('%user' => $username)));
}
else {
// Transform the username into a uid.
form_set_value($form, $uid, $form_state);
}
}
// Can't add a user twice
else {
form_set_error('up_add', t('%user is already on this list.', array('%user' => $username)));
}
}
// Can't add a user that doesn't exist.
else {
form_set_error('up_add', t('The username is invalid.'));
}
}
}
/**
* Processes the submitted user protection form.
*/
function userprotect_protections_bypass_submit($form, &$form_state) {
$type = $form_state['values']['userprotect_type'];
// A user was added, so add them to the protected users table.
if ($uid = $form_state['values']['up_add']) {
userprotect_add_user($uid, $type);
$username = userprotect_get_username($uid);
if ($type == 'user') {
drupal_set_message(t('%user is now protected.', array('%user' => $username)));
}
elseif ($type == 'admin') {
drupal_set_message(t('%user now has bypass capabilities matching the default protections for newly protected users.', array('%user' => $username)));
}
}
if (is_array($form_state['values']['protection'])) {
// Load the defaults as a reference to all protections.
$protections_values = userprotect_user_protection_defaults();
// Loop through each user.
foreach ($form_state['values']['protection'] as $uid => $protections) {
$fields = array();
// Loop through the submitted user's protections, setting them enabled or
// disabled as appropriate for the update query. Note: $protection is
// a module generated string, so it's safe.
foreach ($protections_values as $protection => $value) {
$fields[$protection] = $protections[$protection] ? 1 : 0;
}
// Update the user's protections.
db_update('userprotect')
->fields($fields)
->condition('uid', $uid)
->condition('up_type', $type)
->execute();
}
if ($type == 'user') {
drupal_set_message(t('Protection settings updated.'));
}
elseif ($type == 'admin') {
drupal_set_message(t('Bypass settings updated.'));
}
}
}
/**
* Menu callback. Removes a user from being protected, or removes an
* administrator bypass.
*/
function userprotect_protected_users_delete_form($form, &$form_state, $account, $type = 'user') {
if ($type == 'user') {
$type_display = t('protections');
$admin_page = 'protected_users';
}
elseif ($type == 'admin') {
$type_display = t('administrator bypass');
$admin_page = 'administrator_bypass';
}
$form_state['userprotect']['account'] = $account;
$form_state['userprotect']['type'] = $type;
$form_state['userprotect']['type_display'] = $type_display;
$form_state['userprotect']['admin_page'] = $admin_page;
return confirm_form(array(), t('Are you sure you want to delete the individual !type for %user?', array('!type' => $type_display, '%user' => $account->name)), "admin/config/people/userprotect/$admin_page");
}
/**
* Submit function for the delete confirmation form.
*/
function userprotect_protected_users_delete_form_submit($form, &$form_state) {
$account = $form_state['userprotect']['account'];
$type = $form_state['userprotect']['type'];
$type_display = $form_state['userprotect']['type_display'];
$admin_page = $form_state['userprotect']['admin_page'];
db_delete('userprotect')
->condition('uid', $account->uid)
->condition('up_type', $type)
->execute();
if ($type == 'user') {
drupal_set_message(t('%user is no longer protected.', array('%user' => $account->name)));
}
elseif ($type == 'admin') {
drupal_set_message(t('%user is no longer enabled for bypass.', array('%user' => $account->name)));
}
$form_state['redirect'] = "admin/config/people/userprotect/$admin_page";
}
/**
* Builds a form for the role protection settings.
*
* @return An array representing the form.
*/
function userprotect_protected_roles() {
$form = array();
// Get the list of all protections, and the current default settings.
$options = userprotect_get_protection_display();
// Build the header.
$header = array(t('Role'));
foreach ($options as $field => $data) {
$header[] = $data;
}
// Grab all roles but the anonymous role, and grab the current default settings.
$roles = user_roles(TRUE);
$protected_roles = variable_get('userprotect_role_protections', array());
// This is a complete list of protections for reference.
$protections = array_keys(userprotect_user_protection_defaults());
// Pass in the header and protections so they're available for the theme function.
// Also, we want this as one big array to save in the variables table, so tree it.
$form['role_table']['#header'] = $header;
$form['role_table']['#theme'] = 'userprotect_admin_role_table';
$form['role_table']['#protections'] = $protections;
$form['role_table']['userprotect_role_protections']['#tree'] = TRUE;
// Build a row for each role.
foreach ($roles as $rid => $role) {
$form['role_table']['userprotect_role_protections'][$rid]['name'] = array('#markup' => $role);
// Build protections for the row.
foreach ($protections as $protection) {
$form['role_table']['userprotect_role_protections'][$rid][$protection] = array(
'#type' => 'checkbox',
);
if (isset($protected_roles[$rid][$protection])) {
$form['role_table']['userprotect_role_protections'][$rid][$protection]['#default_value'] = $protected_roles[$rid][$protection];
}
}
}
return system_settings_form($form);
}
/**
* Builds a form for the userprotect default settings.
*
* @return An array representing the form.
*/
function userprotect_protection_defaults() {
// Get the list of all protections, and the current default settings.
$options = userprotect_get_protection_display();
$current_defaults = variable_get('userprotect_protection_defaults', userprotect_user_protection_defaults());
// Transform the defaults into proper checkboxes defaults.
$defaults = array_keys(array_filter($current_defaults));
// A set of checkboxes that lists the default protection settings.
$form['userprotect_protection_defaults'] = array(
'#type' => 'checkboxes',
'#title' => t('User protection defaults'),
'#description' => t('The selected protections will be assigned to users when they are first added for protection.'),
'#options' => $options,
'#default_value' => $defaults,
);
// A checkbox to enable the auto-protect functionality.
$form['userprotect_autoprotect'] = array(
'#type' => 'checkbox',
'#title' => t('Auto-protect new users'),
'#description' => t('If selected, all newly created users will automatically be protected and assigned the default protections above.'),
'#default_value' => variable_get('userprotect_autoprotect', FALSE),
);
// A set of checkboxes that lists the default protection settings.
$form['userprotect_administrator_bypass_defaults'] = array(
'#type' => 'checkboxes',
'#title' => t('Administrator bypass defaults'),
'#description' => t('If selected, all users with the \'administer users\' permission will be allowed to bypass the protection
Note: this default setting is overridden by the per-user administrator bypass settings..', array('!per_user_bypass' => url('admin/config/people/userprotect/administrator_bypass'))),
'#options' => $options,
'#default_value' => variable_get('userprotect_administrator_bypass_defaults', userprotect_administrator_bypass_defaults()),
);
return system_settings_form($form);
}
/**
* Themes the role protections table.
*
* @param $form The form for the table.
* @return An HTML string representing the table.
*/
function theme_userprotect_admin_role_table($variables) {
$form = $variables['form'];
$rows = array();
// Build a row for each role
foreach (element_children($form['userprotect_role_protections']) as $rid) {
$row = array();
$row[] = drupal_render($form['userprotect_role_protections'][$rid]['name']);
// Build the protections for each row.
foreach ($form['#protections'] as $protection) {
$row[] = drupal_render($form['userprotect_role_protections'][$rid][$protection]);
}
$rows[] = $row;
}
// Theme the table.
$output = t('