You are here

filter_perms.module in Filter Permissions 6

Same filename and directory in other branches
  1. 7 filter_perms.module

This module adds a role and module filter to the user permissions page. Best used when you have an unruly amount of roles or permissions on your site and want to more efficiently manage them without loading a gigantic grid of checkboxes.

File

filter_perms.module
View source
<?php

/**
 * @file
 * This module adds a role and module filter to the user permissions page. Best used
 * when you have an unruly amount of roles or permissions on your site and want to
 * more efficiently manage them without loading a gigantic grid of checkboxes.
 */

/**
 * Implementation of hook_menu_alter().
 */
function filter_perms_menu_alter(&$callbacks) {
  $callbacks['admin/user/permissions']['page callback'] = 'filter_perms_admin_perm';
}

/**
 * Page callback which appends a filter form to the standard user_admin_perm form.
 */
function filter_perms_admin_perm($a) {
  $output = drupal_get_form('filter_perms_admin_perm_filter');
  $output .= drupal_get_form('user_admin_perm');
  return $output;
}

/**
 * Form providing a multiple select for roles and modules for filtering permissions.
 */
function filter_perms_admin_perm_filter() {
  $form['filters'] = array(
    '#type' => 'fieldset',
    '#title' => t('Permission Filters'),
    '#collapsible' => TRUE,
    '#collapsed' => FALSE,
  );
  $role_options = user_roles();

  // Displays all user roles.
  $form['filters']['roles'] = array(
    '#title' => t('Roles to display'),
    '#type' => 'select',
    '#options' => array(
      '-1' => '--All Roles',
    ) + $role_options,
    '#default_value' => isset($_SESSION['filter_perm_roles']) ? $_SESSION['filter_perm_roles'] : '',
    '#size' => 8,
    '#multiple' => TRUE,
  );
  $module_options = array();
  foreach (module_list(FALSE, FALSE, TRUE) as $module) {
    if ($module == 'content_permissions') {
      $module_options[$module] = $module . ' (' . t('or select individual content types below') . ')';
      $content_types = node_get_types('types');
      foreach ($content_types as $content_type) {
        $content_type_info = content_types($content_type->type);

        // Only show content types with fields.
        if (count($content_type_info['fields'])) {
          $module_options['content_permissions_' . $content_type->type] = '- ' . $content_type->name;
        }
      }
    }
    elseif (module_invoke($module, 'perm')) {
      $module_options[$module] = $module;
    }
  }

  // Displays all modules which implement hook_perm().
  $form['filters']['modules'] = array(
    '#title' => t('Modules to display'),
    '#type' => 'select',
    '#options' => array(
      '-1' => '--All Modules',
    ) + $module_options,
    '#default_value' => isset($_SESSION['filter_perm_modules']) ? $_SESSION['filter_perm_modules'] : '',
    '#size' => 8,
    '#multiple' => TRUE,
  );
  $form['filters']['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Filter Permissions'),
  );
  return $form;
}

/**
 * Submit handler for filter_perms_admin_perm_filter form.
 */
function filter_perms_admin_perm_filter_submit($form, &$form_state) {
  $_SESSION['filter_perm_roles'] = $form_state['values']['roles'];
  $_SESSION['filter_perm_modules'] = $form_state['values']['modules'];
}

/**
 * Implementation of hook_form_alter().
 */
function filter_perms_form_alter(&$form, $form_state, $form_id) {
  if ($form_id == 'user_admin_perm') {

    // CSS for floating and sizing the select boxes and submit button.
    drupal_add_css(drupal_get_path('module', 'filter_perms') . '/filter_perms.css');
    if (isset($_SESSION['filter_perm_roles']) && count($_SESSION['filter_perm_roles'])) {
      $roles = $_SESSION['filter_perm_roles'];

      // If '--All Roles' is selected, get all roles.
      if (isset($roles['-1'])) {
        $user_roles = user_roles();
        foreach ($user_roles as $user_role_key => $user_role) {
          $roles[$user_role_key] = $user_role_key;
        }
      }
    }
    else {

      // Until the session variable is set, don't display any roles.
      $roles = array();
    }
    $cp_field_perms = array();
    if (isset($_SESSION['filter_perm_modules']) && count($_SESSION['filter_perm_modules'])) {
      $modules = $_SESSION['filter_perm_modules'];
      if (!isset($modules['content_permissions']) && module_exists('content_permissions')) {
        $cp_types = array();

        // If any content type is chosen under content_permissions, show content_permissions.
        foreach ($modules as $cp_module) {
          if (strstr($cp_module, 'content_permissions_')) {
            $cp_types[] = str_replace('content_permissions_', '', $cp_module);
          }
        }
        if (count($cp_types)) {
          foreach ($cp_types as $cp_type) {
            $cp_info = content_types($cp_type);
            $cp_fields = $cp_info['fields'];
            foreach ($cp_fields as $cp_field) {
              $cp_field_perms[] = 'edit ' . $cp_field['field_name'];
              $cp_field_perms[] = 'view ' . $cp_field['field_name'];
            }
          }
        }
      }

      // if '--All Modules' is selected, get all modules.
      if (isset($modules['-1'])) {
        foreach (module_list(FALSE, FALSE, TRUE) as $module) {
          if (module_invoke($module, 'perm')) {
            $modules[$module] = $module;
          }
        }
      }
    }
    else {

      // Until the session variable is set, don't display any modules.
      $modules = array();
    }
    $perms = array();
    foreach ($form['permission'] as $perm_key => $perm) {
      if (is_numeric($perm_key)) {
        $perm_module = $perm['#value'];
      }
      else {
        if (in_array($perm_module, $modules)) {
          $perms[$perm_module][$perm_key] = $perm['#value'];
        }
        elseif ($perm_module == 'content_permissions' && in_array($perm['#value'], $cp_field_perms)) {
          $perms[$perm_module][$perm_key] = $perm['#value'];
        }
      }
    }
    $old_checkboxes = $form['checkboxes'];
    $old_roles = $form['role_names'];
    $form['permission'] = array();
    $form['checkboxes'] = array();
    $form['role_names'] = array();
    unset($form['submit']);

    // If either a role or module is not selected, don't display checkboxes.
    if (count($roles) && count($modules)) {
      $new_roles = array();
      foreach ($old_roles as $rid => $role) {
        if (in_array($rid, $roles)) {
          $new_roles[$rid] = $role;
        }
      }
      $perm_index = 0;
      foreach ($perms as $perm_key => $perm) {
        $form['permission'][$perm_index] = array(
          '#value' => $perm_key,
        );
        $perm_index++;
        foreach ($perms[$perm_key] as $perm_name => $perm_value) {
          $form['permission'][$perm_name] = array(
            '#value' => $perm_value,
          );
          foreach ($new_roles as $rid => $role) {
            $form['checkboxes'][$rid]['#type'] = 'checkboxes';
            $form['checkboxes'][$rid]['#options'][$perm_name] = '';
            $form['checkboxes'][$rid]['#default_value'] = $old_checkboxes[$rid]['#default_value'];
          }
        }
      }
      $form['role_names'] = $new_roles;
      $form['submit'] = array(
        '#type' => 'submit',
        '#value' => 'Save permissions',
      );
      $form['#submit'] = array(
        'filter_perms_user_admin_perm_submit',
      );
    }
    else {

      // Put some basic info in if filters are not selected.
      $form['permission']['-1'] = array(
        '#value' => 'Empty',
      );
      $form['permission']['Empty'] = array(
        '#value' => 'Please select at least one value from both the Roles and Modules select boxes above and then click the "Filter Permissions" button',
      );
    }
  }
}

/**
 * Submit handler which overrides user_admin_perm_submit().
 */
function filter_perms_user_admin_perm_submit($form, &$form_state) {

  // Save permissions:
  $result = db_query('SELECT * FROM {role}');
  while ($role = db_fetch_object($result)) {
    if (isset($form_state['values'][$role->rid])) {
      $permissions = array();
      $indexed_perms = array();
      $current_perms = db_result(db_query("SELECT perm FROM {permission} WHERE rid = %d", $role->rid));
      if (drupal_strlen($current_perms)) {
        $permissions = explode(', ', $current_perms);
      }
      foreach ($permissions as $permission) {
        $indexed_perms[$permission] = $permission;
      }
      $permissions = $indexed_perms;
      foreach ($form_state['values'][$role->rid] as $perm_key => $role_perms) {
        if (isset($permissions[$perm_key])) {
          if ($role_perms == 0) {
            unset($permissions[$perm_key]);
          }
        }
      }
      $permissions = array_merge($permissions, array_filter($form_state['values'][$role->rid]));
      db_query('DELETE FROM {permission} WHERE rid = %d', $role->rid);
      if (count($permissions)) {
        db_query("INSERT INTO {permission} (rid, perm) VALUES (%d, '%s')", $role->rid, implode(', ', array_values($permissions)));
      }
    }
  }
  drupal_set_message(t('The changes have been saved.'));

  // Clear the cached pages
  cache_clear_all();
}

/**
 * Implementation of hook_theme_registry_alter().
 */
function filter_perms_theme_registry_alter(&$theme_registry) {
  $theme_registry['system_admin_by_module']['function'] = 'theme_filter_perms_admin_by_module';
}
function theme_filter_perms_admin_by_module($menu_items) {
  $stripe = 0;
  $output = '';
  $container = array(
    'left' => '',
    'right' => '',
  );
  $flip = array(
    'left' => 'right',
    'right' => 'left',
  );
  $position = 'left';

  // Iterate over all modules
  foreach ($menu_items as $module => $block) {
    list($description, $items) = $block;

    // Output links
    if (count($items)) {
      if (isset($items['-1'])) {
        $items['-1'] = str_replace('#module-', '/', $items['-1']);
      }
      $block = array();
      $block['title'] = $module;
      $block['content'] = theme('item_list', $items);
      $block['description'] = t($description);
      if ($block_output = theme('admin_block', $block)) {
        if (!isset($block['position'])) {

          // Perform automatic striping.
          $block['position'] = $position;
          $position = $flip[$position];
        }
        $container[$block['position']] .= $block_output;
      }
    }
  }
  $output = '<div class="admin clear-block">';
  foreach ($container as $id => $data) {
    $output .= '<div class="' . $id . ' clear-block">';
    $output .= $data;
    $output .= '</div>';
  }
  $output .= '</div>';
  return $output;
}

Functions

Namesort descending Description
filter_perms_admin_perm Page callback which appends a filter form to the standard user_admin_perm form.
filter_perms_admin_perm_filter Form providing a multiple select for roles and modules for filtering permissions.
filter_perms_admin_perm_filter_submit Submit handler for filter_perms_admin_perm_filter form.
filter_perms_form_alter Implementation of hook_form_alter().
filter_perms_menu_alter Implementation of hook_menu_alter().
filter_perms_theme_registry_alter Implementation of hook_theme_registry_alter().
filter_perms_user_admin_perm_submit Submit handler which overrides user_admin_perm_submit().
theme_filter_perms_admin_by_module