user.admin.inc 15.1 KB
Newer Older
1 2 3 4 5 6 7
<?php

/**
 * @file
 * Admin page callback file for the user module.
 */

8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/**
 * Page callback: Generates the appropriate user administration form.
 *
 * This function generates the user registration, multiple user cancellation,
 * or filtered user list admin form, depending on the argument and the POST
 * form values.
 *
 * @param string $callback_arg
 *   (optional) Indicates which form to build. Defaults to '', which will
 *   trigger the user filter form. If the POST value 'op' is present, this
 *   function uses that value as the callback argument.
 *
 * @return string
 *   A renderable form array for the respective request.
 */
23 24 25 26 27 28
function user_admin($callback_arg = '') {
  $op = isset($_POST['op']) ? $_POST['op'] : $callback_arg;

  switch ($op) {
    case t('Create new account'):
    case 'create':
29 30
      $account = entity_create('user', array());
      $build['user_register'] = entity_get_form($account, 'register');
31 32
      break;
    default:
33
      if (!empty($_POST['accounts']) && isset($_POST['operation']) && ($_POST['operation'] == 'cancel')) {
34
        $build['user_multiple_cancel_confirm'] = drupal_get_form('user_multiple_cancel_confirm');
35 36
      }
      else {
37 38
        $build['user_filter_form'] = drupal_get_form('user_filter_form');
        $build['user_admin_account'] = drupal_get_form('user_admin_account');
39 40
      }
  }
41
  return $build;
42 43 44 45
}

/**
 * Form builder; Return form for user administration filters.
46
 *
47
 * @ingroup forms
48
 * @see user_filter_form_submit()
49 50
 */
function user_filter_form() {
51
  $session = isset($_SESSION['user_overview_filter']) ? $_SESSION['user_overview_filter'] : array();
52 53 54
  $filters = user_filters();

  $i = 0;
55
  $form['filters'] = array(
56
    '#type' => 'details',
57
    '#title' => t('Show only users where'),
58
    '#theme' => 'exposed_filters__user',
59
  );
60 61
  foreach ($session as $filter) {
    list($type, $value) = $filter;
62 63 64 65 66 67 68 69 70
    if ($type == 'permission') {
      // Merge arrays of module permissions into one.
      // Slice past the first element '[any]' whose value is not an array.
      $options = call_user_func_array('array_merge', array_slice($filters[$type]['options'], 1));
      $value = $options[$value];
    }
    else {
      $value = $filters[$type]['options'][$value];
    }
71
    $t_args = array('%property' => $filters[$type]['title'], '%value' => $value);
72
    if ($i++) {
73
      $form['filters']['current'][] = array('#markup' => t('and where %property is %value', $t_args));
74 75
    }
    else {
76
      $form['filters']['current'][] = array('#markup' => t('%property is %value', $t_args));
77
    }
78 79
  }

80 81 82 83 84 85 86 87 88
  $form['filters']['status'] = array(
    '#type' => 'container',
    '#attributes' => array('class' => array('clearfix')),
    '#prefix' => ($i ? '<div class="additional-filters">' . t('and where') . '</div>' : ''),
  );
  $form['filters']['status']['filters'] = array(
    '#type' => 'container',
    '#attributes' => array('class' => array('filters')),
  );
89
  foreach ($filters as $key => $filter) {
90
    $form['filters']['status']['filters'][$key] = array(
91 92
      '#type' => 'select',
      '#options' => $filter['options'],
93 94
      '#title' => $filter['title'],
      '#default_value' => '[any]',
95
    );
96 97
  }

98
  $form['filters']['status']['actions'] = array(
99 100
    '#type' => 'actions',
    '#attributes' => array('class' => array('container-inline')),
101
  );
102
  $form['filters']['status']['actions']['submit'] = array(
103 104 105
    '#type' => 'submit',
    '#value' => (count($session) ? t('Refine') : t('Filter')),
  );
106
  if (count($session)) {
107
    $form['filters']['status']['actions']['undo'] = array(
108 109 110
      '#type' => 'submit',
      '#value' => t('Undo'),
    );
111
    $form['filters']['status']['actions']['reset'] = array(
112 113 114
      '#type' => 'submit',
      '#value' => t('Reset'),
    );
115 116
  }

117
  drupal_add_library('system', 'drupal.form');
118

119 120 121 122 123 124 125 126 127 128
  return $form;
}

/**
 * Process result from user administration filter form.
 */
function user_filter_form_submit($form, &$form_state) {
  $op = $form_state['values']['op'];
  $filters = user_filters();
  switch ($op) {
129 130 131 132 133
    case t('Filter'):
    case t('Refine'):
      // Apply every filter that has a choice selected other than 'any'.
      foreach ($filters as $filter => $options) {
        if (isset($form_state['values'][$filter]) && $form_state['values'][$filter] != '[any]') {
134
          $_SESSION['user_overview_filter'][] = array($filter, $form_state['values'][$filter]);
135 136 137 138 139 140 141
        }
      }
      break;
    case t('Undo'):
      array_pop($_SESSION['user_overview_filter']);
      break;
    case t('Reset'):
142
      $_SESSION['user_overview_filter'] = array();
143 144 145 146 147
      break;
    case t('Update'):
      return;
  }

148
  $form_state['redirect'] = 'admin/people';
149 150 151 152 153 154 155
  return;
}

/**
 * Form builder; User administration page.
 *
 * @ingroup forms
156 157
 * @see user_admin_account_validate()
 * @see user_admin_account_submit()
158 159 160 161
 */
function user_admin_account() {

  $header = array(
162
    'username' => array('data' => t('Username'), 'field' => 'u.name'),
163 164 165 166
    'status' => array('data' => t('Status'), 'field' => 'u.status', 'class' => array(RESPONSIVE_PRIORITY_LOW)),
    'roles' => array('data' => t('Roles'), 'class' => array(RESPONSIVE_PRIORITY_LOW)),
    'member_for' => array('data' => t('Member for'), 'field' => 'u.created', 'sort' => 'desc', 'class' => array(RESPONSIVE_PRIORITY_LOW)),
    'access' => array('data' => t('Last access'), 'field' => 'u.access', 'class' => array(RESPONSIVE_PRIORITY_LOW)),
167
    'operations' => t('Operations'),
168 169
  );

170
  $query = db_select('users', 'u');
171 172
  $query->condition('u.uid', 0, '<>');
  user_build_filter_query($query);
173

174
  $count_query = clone $query;
175
  $count_query->addExpression('COUNT(u.uid)');
176

177 178
  $query = $query
    ->extend('Drupal\Core\Database\Query\PagerSelectExtender')
179
    ->extend('Drupal\Core\Database\Query\TableSortExtender');
180 181 182
  $query
    ->fields('u', array('uid', 'name', 'status', 'created', 'access'))
    ->limit(50)
183
    ->orderByHeader($header)
184 185
    ->setCountQuery($count_query);
  $result = $query->execute();
186 187

  $form['options'] = array(
188
    '#type' => 'details',
189
    '#title' => t('Update options'),
190
    '#attributes' => array('class' => array('container-inline')),
191 192
  );
  $options = array();
193 194 195
  $actions = entity_load_multiple_by_properties('action', array('type' => 'user'));
  foreach ($actions as $id => $action) {
    $options[$id] = $action->label();
196 197 198
  }
  $form['options']['operation'] = array(
    '#type' => 'select',
199
    '#title' => t('Action'),
200
    '#title_display' => 'invisible',
201 202 203
    '#options' => $options,
    '#default_value' => 'unblock',
  );
204
  $options = array();
205 206 207 208 209 210 211
  $form['options']['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Update'),
  );

  $destination = drupal_get_destination();
  $status = array(t('blocked'), t('active'));
212
  $roles = array_map('check_plain', user_role_names(TRUE));
213
  $accounts = array();
214
  foreach ($result as $account) {
215
    $account = user_load($account->uid);
216
    $users_roles = array();
217 218
    $roles_result = db_query('SELECT rid FROM {users_roles} WHERE uid = :uid', array(':uid' => $account->uid));
    foreach ($roles_result as $user_role) {
219
      $users_roles[] = $roles[$user_role->rid];
220
    }
221
    asort($users_roles);
222

223
    $options[$account->uid] = array(
224
      'username' => theme('username', array('account' => $account)),
225
      'status' =>  $status[$account->status],
226
      'roles' => theme('item_list', array('items' => $users_roles)),
227 228
      'member_for' => format_interval(REQUEST_TIME - $account->created),
      'access' =>  $account->access ? t('@time ago', array('@time' => format_interval(REQUEST_TIME - $account->access))) : t('never'),
229 230 231
    );
    $links = array();
    $links['edit'] = array(
232
      'title' => t('Edit'),
233
      'href' => 'user/' . $account->uid . '/edit',
234 235
      'query' => $destination,
    );
236 237
    if (module_invoke('translation_entity', 'translate_access', $account)) {
      $links['translate'] = array(
238
        'title' => t('Translate'),
239 240 241 242
        'href' => 'user/' . $account->uid . '/translations',
        'query' => $destination,
      );
    }
243 244 245
    $options[$account->uid]['operations']['data'] = array(
      '#type' => 'operations',
      '#links' => $links,
246
    );
247 248 249

    $options[$account->uid]['title']['data']['#title'] = check_plain($account->name);

250
  }
251

252
  $form['accounts'] = array(
253 254 255 256
    '#type' => 'tableselect',
    '#header' => $header,
    '#options' => $options,
    '#empty' => t('No people available.'),
257
  );
258
  $form['pager'] = array('#markup' => theme('pager'));
259 260 261 262 263 264 265 266

  return $form;
}

/**
 * Submit the user administration update form.
 */
function user_admin_account_submit($form, &$form_state) {
267 268 269 270 271 272
  if ($action = entity_load('action', $form_state['values']['operation'])) {
    $accounts = entity_load_multiple('user', array_filter($form_state['values']['accounts']));
    $action->execute($accounts);
    $operation_definition = $action->getPluginDefinition();
    if (!empty($operation_definition['confirm_form_path'])) {
      $form_state['redirect'] = $operation_definition['confirm_form_path'];
273 274 275 276 277 278 279 280 281 282 283 284 285 286
    }
    drupal_set_message(t('The update has been performed.'));
  }
}

function user_admin_account_validate($form, &$form_state) {
  $form_state['values']['accounts'] = array_filter($form_state['values']['accounts']);
  if (count($form_state['values']['accounts']) == 0) {
    form_set_error('', t('No users selected.'));
  }
}

/**
 * Menu callback: administer permissions.
287
 *
288
 * @ingroup forms
289 290
 * @see user_admin_permissions_submit()
 * @see theme_user_admin_permissions()
291
 */
292
function user_admin_permissions($form, $form_state, $rid = NULL) {
293

294
  // Retrieve role names for columns.
295
  $role_names = user_role_names();
296
  if (isset($rid)) {
297
    $role_names = array($rid => $role_names[$rid]);
298
  }
299
  // Fetch permissions for all roles or the one selected role.
300
  $role_permissions = user_role_permissions(array_keys($role_names));
301

302 303 304 305 306
  // Store $role_names for use when saving the data.
  $form['role_names'] = array(
    '#type' => 'value',
    '#value' => $role_names,
  );
307 308
  // Render role/permission overview:
  $options = array();
309
  $module_info = system_get_info('module');
310
  $hide_descriptions = system_admin_compact_mode();
311 312 313 314

  // Get a list of all the modules implementing a hook_permission() and sort by
  // display name.
  $modules = array();
315
  foreach (module_implements('permission') as $module) {
316
    $modules[$module] = $module_info[$module]['name'];
317
  }
318
  asort($modules);
319

320
  foreach ($modules as $module => $display_name) {
321
    if ($permissions = module_invoke($module, 'permission')) {
322
      $form['permission'][] = array(
323
        '#markup' => $module_info[$module]['name'],
324
        '#id' => $module,
325
      );
326
      foreach ($permissions as $perm => $perm_item) {
327 328 329 330 331 332
        // Fill in default values for the permission.
        $perm_item += array(
          'description' => '',
          'restrict access' => FALSE,
          'warning' => !empty($perm_item['restrict access']) ? t('Warning: Give to trusted roles only; this permission has security implications.') : '',
        );
333
        $options[$perm] = '';
334 335
        $form['permission'][$perm] = array(
          '#type' => 'item',
336
          '#markup' => $perm_item['title'],
337
          '#description' => theme('user_permission_description', array('permission_item' => $perm_item, 'hide' => $hide_descriptions)),
338
        );
339 340
        foreach ($role_names as $rid => $name) {
          // Builds arrays for checked boxes for each role
341
          if (isset($role_permissions[$rid][$perm])) {
342 343 344 345 346 347 348 349 350
            $status[$rid][] = $perm;
          }
        }
      }
    }
  }

  // Have to build checkboxes here after checkbox arrays are built
  foreach ($role_names as $rid => $name) {
351 352 353 354 355 356
    $form['checkboxes'][$rid] = array(
      '#type' => 'checkboxes',
      '#options' => $options,
      '#default_value' => isset($status[$rid]) ? $status[$rid] : array(),
      '#attributes' => array('class' => array('rid-' . $rid)),
    );
357
    $form['role_names'][$rid] = array('#markup' => check_plain($name), '#tree' => TRUE);
358
  }
359

360
  $form['actions'] = array('#type' => 'actions');
361
  $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Save permissions'));
362

363
  $form['#attached']['library'][] = array('user', 'drupal.user.permissions');
364

365 366 367
  return $form;
}

368 369 370
/**
 * Save permissions selected on the administer permissions page.
 *
371
 * @see user_admin_permissions()
372
 */
373
function user_admin_permissions_submit($form, &$form_state) {
374
  foreach ($form_state['values']['role_names'] as $rid => $name) {
375
    user_role_change_permissions($rid, $form_state['values'][$rid]);
376 377 378 379
  }

  drupal_set_message(t('The changes have been saved.'));

380
  // Clear the cached pages and blocks.
381
  cache_invalidate_tags(array('content' => TRUE));
382 383 384
}

/**
385 386 387 388 389
 * Returns HTML for the administer permissions page.
 *
 * @param $variables
 *   An associative array containing:
 *   - form: A render element representing the form.
390 391 392
 *
 * @ingroup themeable
 */
393 394 395
function theme_user_admin_permissions($variables) {
  $form = $variables['form'];

396
  $roles = user_role_names();
397
  foreach (element_children($form['permission']) as $key) {
398 399 400
    $row = array();
    // Module name
    if (is_numeric($key)) {
401
      $row[] = array('data' => drupal_render($form['permission'][$key]), 'class' => array('module'), 'id' => 'module-' . $form['permission'][$key]['#id'], 'colspan' => count($form['role_names']['#value']) + 1);
402 403 404 405 406
    }
    else {
      // Permission row.
      $row[] = array(
        'data' => drupal_render($form['permission'][$key]),
407
        'class' => array('permission'),
408 409
      );
      foreach (element_children($form['checkboxes']) as $rid) {
410
        $form['checkboxes'][$rid][$key]['#title'] = $roles[$rid] . ': ' . $form['permission'][$key]['#markup'];
411 412
        $form['checkboxes'][$rid][$key]['#title_display'] = 'invisible';
        $row[] = array('data' => drupal_render($form['checkboxes'][$rid][$key]), 'class' => array('checkbox'));
413 414
      }
    }
415
    $rows[] = $row;
416 417 418
  }
  $header[] = (t('Permission'));
  foreach (element_children($form['role_names']) as $rid) {
419
    $header[] = array('data' => drupal_render($form['role_names'][$rid]), 'class' => array('checkbox'));
420
  }
421
  $output = theme('system_compact_link');
422
  $output .= theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'permissions')));
423
  $output .= drupal_render_children($form);
424 425 426
  return $output;
}

427
/**
428
 * Returns HTML for an individual permission description.
429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456
 *
 * @param $variables
 *   An associative array containing:
 *   - permission_item: An associative array representing the permission whose
 *     description is being themed. Useful keys include:
 *     - description: The text of the permission description.
 *     - warning: A security-related warning message about the permission (if
 *       there is one).
 *   - hide: A boolean indicating whether or not the permission description was
 *     requested to be hidden rather than shown.
 *
 * @ingroup themeable
 */
function theme_user_permission_description($variables) {
  if (!$variables['hide']) {
    $description = array();
    $permission_item = $variables['permission_item'];
    if (!empty($permission_item['description'])) {
      $description[] = $permission_item['description'];
    }
    if (!empty($permission_item['warning'])) {
      $description[] = '<em class="permission-warning">' . $permission_item['warning'] . '</em>';
    }
    if (!empty($description)) {
      return implode(' ', $description);
    }
  }
}